diff --git a/app/src/main/java/com/nextcloud/talk/activities/CallActivity.java b/app/src/main/java/com/nextcloud/talk/activities/CallActivity.java index 77742d61a1..ddb21d87a5 100644 --- a/app/src/main/java/com/nextcloud/talk/activities/CallActivity.java +++ b/app/src/main/java/com/nextcloud/talk/activities/CallActivity.java @@ -428,7 +428,14 @@ public void switchCamera() { } private void createCameraEnumerator() { - if (Camera2Enumerator.isSupported(this)) { + boolean camera2EnumeratorIsSupported = false; + try { + camera2EnumeratorIsSupported = Camera2Enumerator.isSupported(this); + } catch (final Throwable throwable) { + Log.w(TAG, "Camera2Enumator threw an error"); + } + + if (camera2EnumeratorIsSupported) { cameraEnumerator = new Camera2Enumerator(this); } else { cameraEnumerator = new Camera1Enumerator(true); @@ -548,14 +555,6 @@ private void basicInitialization() { rootEglBase = EglBase.create(); createCameraEnumerator(); - //Initialize PeerConnectionFactory globals. - PeerConnectionFactory.InitializationOptions initializationOptions = PeerConnectionFactory.InitializationOptions - .builder(this) - .setEnableVideoHwAcceleration(true) - .setFieldTrials(null) - .createInitializationOptions(); - PeerConnectionFactory.initialize(initializationOptions); - //Create a new PeerConnectionFactory instance. PeerConnectionFactory.Options options = new PeerConnectionFactory.Options(); peerConnectionFactory = new PeerConnectionFactory(options); @@ -968,55 +967,48 @@ private void hangup(boolean dueToNetworkChange) { leavingCall = true; inCall = false; - dispose(null); + + if (videoCapturer != null) { + try { + videoCapturer.stopCapture(); + } catch (InterruptedException e) { + Log.e(TAG, "Failed to stop capturing while hanging up"); + } + videoCapturer.dispose(); + videoCapturer = null; + } for (int i = 0; i < magicPeerConnectionWrapperList.size(); i++) { endPeerConnection(magicPeerConnectionWrapperList.get(i).getSessionId()); } - if (!dueToNetworkChange) { - pipVideoView.release(); + pipVideoView.release(); - if (audioSource != null) { - audioSource.dispose(); - audioSource = null; - } - - if (audioManager != null) { - audioManager.stop(); - audioManager = null; - } + if (audioSource != null) { + audioSource.dispose(); + audioSource = null; + } - if (videoCapturer != null) { - try { - videoCapturer.stopCapture(); - } catch (InterruptedException e) { - Log.e(TAG, "Failed to stop capturing while hanging up"); - } - videoCapturer.dispose(); - videoCapturer = null; - } + if (audioManager != null) { + audioManager.stop(); + audioManager = null; + } - Log.d(TAG, "Closing video source."); - if (videoSource != null) { - videoSource.dispose(); - videoSource = null; - } + if (videoSource != null) { + videoSource = null; + } - if (peerConnectionFactory != null) { - peerConnectionFactory.dispose(); - peerConnectionFactory = null; - } + if (peerConnectionFactory != null) { + peerConnectionFactory.dispose(); + peerConnectionFactory = null; + } - localMediaStream.removeTrack(localAudioTrack); - localMediaStream.removeTrack(localVideoTrack); - localMediaStream = null; - localAudioTrack = null; - localVideoTrack = null; + localMediaStream = null; + localAudioTrack = null; + localVideoTrack = null; - hangupNetworkCalls(); - } + hangupNetworkCalls(); } private void hangupNetworkCalls() { @@ -1131,6 +1123,7 @@ public void onDestroy() { hangup(false); } //this.unregisterReceiver(networkBroadcastReceier); + rootEglBase.release(); super.onDestroy(); } diff --git a/app/src/main/java/com/nextcloud/talk/application/NextcloudTalkApplication.java b/app/src/main/java/com/nextcloud/talk/application/NextcloudTalkApplication.java index 6de9391465..02a8d2036c 100644 --- a/app/src/main/java/com/nextcloud/talk/application/NextcloudTalkApplication.java +++ b/app/src/main/java/com/nextcloud/talk/application/NextcloudTalkApplication.java @@ -43,10 +43,16 @@ import com.squareup.leakcanary.LeakCanary; import com.squareup.leakcanary.RefWatcher; +import org.webrtc.PeerConnectionFactory; +import org.webrtc.voiceengine.WebRtcAudioManager; +import org.webrtc.voiceengine.WebRtcAudioUtils; + import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.security.GeneralSecurityException; +import java.util.HashSet; +import java.util.Set; import javax.inject.Singleton; @@ -107,6 +113,54 @@ private void useCompatVectorIfNeeded() { } } } + + /* + AEC blacklist and SL_ES_WHITELIST are borrowed from Signal + https://github.com/WhisperSystems/Signal-Android/blob/551470123d006b76a68d705d131bb12513a5e683/src/org/thoughtcrime/securesms/ApplicationContext.java + */ + private void initializeWebRtc() { + try { + Set HARDWARE_AEC_BLACKLIST = new HashSet() {{ + add("D6503"); // Sony Xperia Z2 D6503 + add("ONE A2005"); // OnePlus 2 + add("MotoG3"); // Moto G (3rd Generation) + add("Nexus 6P"); // Nexus 6p + add("Pixel"); // Pixel + add("Pixel XL"); // Pixel XL + add("MI 4LTE"); // Xiami Mi4 + add("Redmi Note 3"); // Redmi Note 3 + add("Redmi Note 4"); // Redmi Note 4 + add("SM-G900F"); // Samsung Galaxy S5 + add("g3_kt_kr"); // LG G3 + add("SM-G930F"); // Samsung Galaxy S7 + add("Xperia SP"); // Sony Xperia SP + add("Nexus 6"); // Nexus 6 + add("ONE E1003"); // OnePlus X + add("One"); // OnePlus One + add("Moto G5"); + }}; + + Set OPEN_SL_ES_WHITELIST = new HashSet() {{ + add("Pixel"); + add("Pixel XL"); + }}; + + if (HARDWARE_AEC_BLACKLIST.contains(Build.MODEL)) { + WebRtcAudioUtils.setWebRtcBasedAcousticEchoCanceler(true); + } + + if (!OPEN_SL_ES_WHITELIST.contains(Build.MODEL)) { + WebRtcAudioManager.setBlacklistDeviceForOpenSLESUsage(true); + } + + PeerConnectionFactory.initialize(PeerConnectionFactory.InitializationOptions.builder(this) + .setEnableVideoHwAcceleration(true) + .createInitializationOptions()); + } catch (UnsatisfiedLinkError e) { + Log.w(TAG, e); + } + } + //endregion //region Overridden methods @@ -115,8 +169,10 @@ public void onCreate() { super.onCreate(); JobManager.create(this).addJobCreator(new MagicJobCreator()); FirebaseAnalytics.getInstance(this).setAnalyticsCollectionEnabled(false); + sharedApplication = this; + initializeWebRtc(); useCompatVectorIfNeeded();