Fix EGL crash when ending call.
This commit is contained in:
parent
8a05626791
commit
f0ab919ca5
14 changed files with 105 additions and 114 deletions
|
@ -31,7 +31,7 @@ public class BroadcastVideoSink implements VideoSink {
|
||||||
private RequestedSize currentlyRequestedMaxSize;
|
private RequestedSize currentlyRequestedMaxSize;
|
||||||
|
|
||||||
public BroadcastVideoSink() {
|
public BroadcastVideoSink() {
|
||||||
this(new EglBaseWrapper(null), false, true, 0);
|
this(new EglBaseWrapper(), false, true, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -15,16 +15,21 @@ private val TAG = Log.tag(EglBaseWrapper::class.java)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wrapper which allows caller to perform synchronized actions on an EglBase object.
|
* Wrapper which allows caller to perform synchronized actions on an EglBase object.
|
||||||
*/
|
* Must use [acquireEglBase] to get a valid instance to an [EglBaseWrapper] for use in calling.
|
||||||
class EglBaseWrapper(val eglBase: EglBase?) {
|
* The instance returned may be shared across calls. Call [releaseEglBase] when it is no longer
|
||||||
|
* required. When the wrapper has no others are using it, it will be properly released (a la reference counting).
|
||||||
|
*/
|
||||||
|
class EglBaseWrapper private constructor(val eglBase: EglBase?) {
|
||||||
|
|
||||||
private val lock: Lock = ReentrantLock()
|
private val lock: Lock = ReentrantLock()
|
||||||
|
|
||||||
fun require(): EglBase = requireNotNull(eglBase)
|
|
||||||
|
|
||||||
@Volatile
|
@Volatile
|
||||||
private var isReleased: Boolean = false
|
private var isReleased: Boolean = false
|
||||||
|
|
||||||
|
constructor() : this(null)
|
||||||
|
|
||||||
|
fun require(): EglBase = requireNotNull(eglBase)
|
||||||
|
|
||||||
fun performWithValidEglBase(consumer: Consumer<EglBase>) {
|
fun performWithValidEglBase(consumer: Consumer<EglBase>) {
|
||||||
if (isReleased) {
|
if (isReleased) {
|
||||||
Log.d(TAG, "Tried to use a released EglBase", Exception())
|
Log.d(TAG, "Tried to use a released EglBase", Exception())
|
||||||
|
@ -53,7 +58,7 @@ class EglBaseWrapper(val eglBase: EglBase?) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun releaseEglBase() {
|
private fun releaseEglBase() {
|
||||||
if (isReleased || eglBase == null) {
|
if (isReleased || eglBase == null) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -67,4 +72,48 @@ class EglBaseWrapper(val eglBase: EglBase?) {
|
||||||
eglBase.release()
|
eglBase.release()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val OUTGOING_PLACEHOLDER: String = "OUTGOING_PLACEHOLDER"
|
||||||
|
|
||||||
|
private var eglBaseWrapper: EglBaseWrapper? = null
|
||||||
|
private val holders: MutableSet<Any> = mutableSetOf()
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun acquireEglBase(holder: Any): EglBaseWrapper {
|
||||||
|
val eglBase: EglBaseWrapper = eglBaseWrapper ?: EglBaseWrapper(EglBase.create())
|
||||||
|
eglBaseWrapper = eglBase
|
||||||
|
holders += holder
|
||||||
|
Log.d(TAG, "Acquire EGL $eglBaseWrapper with holder: $holder")
|
||||||
|
return eglBase
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun releaseEglBase(holder: Any) {
|
||||||
|
Log.d(TAG, "Release EGL with holder: $holder")
|
||||||
|
holders.remove(holder)
|
||||||
|
if (holders.isEmpty()) {
|
||||||
|
Log.d(TAG, "Holders empty, release EGL Base")
|
||||||
|
eglBaseWrapper?.releaseEglBase()
|
||||||
|
eglBaseWrapper = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun replaceHolder(currentHolder: Any, newHolder: Any) {
|
||||||
|
if (currentHolder == newHolder) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
Log.d(TAG, "Replace holder $currentHolder with $newHolder")
|
||||||
|
holders += newHolder
|
||||||
|
holders.remove(currentHolder)
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun forceRelease() {
|
||||||
|
eglBaseWrapper?.releaseEglBase()
|
||||||
|
eglBaseWrapper = null
|
||||||
|
holders.clear()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -118,21 +118,6 @@ public class ActiveCallActionProcessorDelegate extends WebRtcActionProcessor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected @NonNull WebRtcServiceState handleCallConcluded(@NonNull WebRtcServiceState currentState, @Nullable RemotePeer remotePeer) {
|
|
||||||
Log.i(tag, "handleCallConcluded():");
|
|
||||||
|
|
||||||
if (remotePeer == null) {
|
|
||||||
return currentState;
|
|
||||||
}
|
|
||||||
|
|
||||||
Log.i(tag, "delete remotePeer callId: " + remotePeer.getCallId() + " key: " + remotePeer.hashCode());
|
|
||||||
return currentState.builder()
|
|
||||||
.changeCallInfoState()
|
|
||||||
.removeRemotePeer(remotePeer)
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected @NonNull WebRtcServiceState handleReceivedOfferWhileActive(@NonNull WebRtcServiceState currentState, @NonNull RemotePeer remotePeer) {
|
protected @NonNull WebRtcServiceState handleReceivedOfferWhileActive(@NonNull WebRtcServiceState currentState, @NonNull RemotePeer remotePeer) {
|
||||||
RemotePeer activePeer = currentState.getCallInfoState().requireActivePeer();
|
RemotePeer activePeer = currentState.getCallInfoState().requireActivePeer();
|
||||||
|
|
|
@ -105,9 +105,4 @@ public class ConnectedCallActionProcessor extends DeviceAwareActionProcessor {
|
||||||
protected @NonNull WebRtcServiceState handleReceivedOfferWhileActive(@NonNull WebRtcServiceState currentState, @NonNull RemotePeer remotePeer) {
|
protected @NonNull WebRtcServiceState handleReceivedOfferWhileActive(@NonNull WebRtcServiceState currentState, @NonNull RemotePeer remotePeer) {
|
||||||
return activeCallDelegate.handleReceivedOfferWhileActive(currentState, remotePeer);
|
return activeCallDelegate.handleReceivedOfferWhileActive(currentState, remotePeer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected @NonNull WebRtcServiceState handleCallConcluded(@NonNull WebRtcServiceState currentState, @Nullable RemotePeer remotePeer) {
|
|
||||||
return activeCallDelegate.handleCallConcluded(currentState, remotePeer);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,60 +0,0 @@
|
||||||
package org.thoughtcrime.securesms.service.webrtc;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
|
|
||||||
import org.signal.core.util.logging.Log;
|
|
||||||
import org.thoughtcrime.securesms.ringrtc.RemotePeer;
|
|
||||||
import org.thoughtcrime.securesms.service.webrtc.state.WebRtcServiceState;
|
|
||||||
import org.thoughtcrime.securesms.service.webrtc.state.WebRtcServiceStateBuilder;
|
|
||||||
import org.whispersystems.signalservice.api.messages.calls.OfferMessage;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handles disconnecting state actions. This primairly entails dealing with final
|
|
||||||
* clean up in the call concluded action, but also allows for transitioning into idle/setup
|
|
||||||
* via beginning an outgoing or incoming call.
|
|
||||||
*/
|
|
||||||
public class DisconnectingCallActionProcessor extends WebRtcActionProcessor {
|
|
||||||
|
|
||||||
private static final String TAG = Log.tag(DisconnectingCallActionProcessor.class);
|
|
||||||
|
|
||||||
public DisconnectingCallActionProcessor(@NonNull WebRtcInteractor webRtcInteractor) {
|
|
||||||
super(webRtcInteractor, TAG);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected @NonNull WebRtcServiceState handleStartIncomingCall(@NonNull WebRtcServiceState currentState, @NonNull RemotePeer remotePeer) {
|
|
||||||
Log.i(TAG, "handleStartIncomingCall():");
|
|
||||||
currentState = currentState.builder()
|
|
||||||
.actionProcessor(new IdleActionProcessor(webRtcInteractor))
|
|
||||||
.build();
|
|
||||||
return currentState.getActionProcessor().handleStartIncomingCall(currentState, remotePeer);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected @NonNull WebRtcServiceState handleOutgoingCall(@NonNull WebRtcServiceState currentState, @NonNull RemotePeer remotePeer, @NonNull OfferMessage.Type offerType) {
|
|
||||||
Log.i(TAG, "handleOutgoingCall():");
|
|
||||||
currentState = currentState.builder()
|
|
||||||
.actionProcessor(new IdleActionProcessor(webRtcInteractor))
|
|
||||||
.build();
|
|
||||||
return currentState.getActionProcessor().handleOutgoingCall(currentState, remotePeer, offerType);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected @NonNull WebRtcServiceState handleCallConcluded(@NonNull WebRtcServiceState currentState, @Nullable RemotePeer remotePeer) {
|
|
||||||
Log.i(TAG, "handleCallConcluded():");
|
|
||||||
|
|
||||||
WebRtcServiceStateBuilder builder = currentState.builder()
|
|
||||||
.actionProcessor(new IdleActionProcessor(webRtcInteractor));
|
|
||||||
|
|
||||||
if (remotePeer != null) {
|
|
||||||
Log.i(TAG, "delete remotePeer callId: " + remotePeer.getCallId() + " key: " + remotePeer.hashCode());
|
|
||||||
|
|
||||||
builder.changeCallInfoState()
|
|
||||||
.removeRemotePeer(remotePeer)
|
|
||||||
.commit();
|
|
||||||
}
|
|
||||||
|
|
||||||
return builder.build();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -8,6 +8,7 @@ import androidx.annotation.NonNull;
|
||||||
|
|
||||||
import org.signal.core.util.logging.Log;
|
import org.signal.core.util.logging.Log;
|
||||||
import org.signal.ringrtc.GroupCall;
|
import org.signal.ringrtc.GroupCall;
|
||||||
|
import org.thoughtcrime.securesms.components.webrtc.EglBaseWrapper;
|
||||||
import org.thoughtcrime.securesms.events.WebRtcViewModel;
|
import org.thoughtcrime.securesms.events.WebRtcViewModel;
|
||||||
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
||||||
import org.thoughtcrime.securesms.ringrtc.RemotePeer;
|
import org.thoughtcrime.securesms.ringrtc.RemotePeer;
|
||||||
|
@ -60,6 +61,7 @@ class GroupNetworkUnavailableActionProcessor extends WebRtcActionProcessor {
|
||||||
Log.i(TAG, "handleCancelPreJoinCall():");
|
Log.i(TAG, "handleCancelPreJoinCall():");
|
||||||
|
|
||||||
WebRtcVideoUtil.deinitializeVideo(currentState);
|
WebRtcVideoUtil.deinitializeVideo(currentState);
|
||||||
|
EglBaseWrapper.releaseEglBase(RemotePeer.GROUP_CALL_ID.longValue());
|
||||||
|
|
||||||
return new WebRtcServiceState(new IdleActionProcessor(webRtcInteractor));
|
return new WebRtcServiceState(new IdleActionProcessor(webRtcInteractor));
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ import org.signal.ringrtc.CallException;
|
||||||
import org.signal.ringrtc.GroupCall;
|
import org.signal.ringrtc.GroupCall;
|
||||||
import org.signal.ringrtc.PeekInfo;
|
import org.signal.ringrtc.PeekInfo;
|
||||||
import org.thoughtcrime.securesms.components.webrtc.BroadcastVideoSink;
|
import org.thoughtcrime.securesms.components.webrtc.BroadcastVideoSink;
|
||||||
|
import org.thoughtcrime.securesms.components.webrtc.EglBaseWrapper;
|
||||||
import org.thoughtcrime.securesms.events.CallParticipant;
|
import org.thoughtcrime.securesms.events.CallParticipant;
|
||||||
import org.thoughtcrime.securesms.events.CallParticipantId;
|
import org.thoughtcrime.securesms.events.CallParticipantId;
|
||||||
import org.thoughtcrime.securesms.events.WebRtcViewModel;
|
import org.thoughtcrime.securesms.events.WebRtcViewModel;
|
||||||
|
@ -78,6 +79,7 @@ public class GroupPreJoinActionProcessor extends GroupActionProcessor {
|
||||||
}
|
}
|
||||||
|
|
||||||
WebRtcVideoUtil.deinitializeVideo(currentState);
|
WebRtcVideoUtil.deinitializeVideo(currentState);
|
||||||
|
EglBaseWrapper.releaseEglBase(RemotePeer.GROUP_CALL_ID.longValue());
|
||||||
|
|
||||||
return new WebRtcServiceState(new IdleActionProcessor(webRtcInteractor));
|
return new WebRtcServiceState(new IdleActionProcessor(webRtcInteractor));
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ import androidx.annotation.NonNull;
|
||||||
import org.signal.core.util.logging.Log;
|
import org.signal.core.util.logging.Log;
|
||||||
import org.signal.ringrtc.CallException;
|
import org.signal.ringrtc.CallException;
|
||||||
import org.signal.ringrtc.CallManager;
|
import org.signal.ringrtc.CallManager;
|
||||||
|
import org.thoughtcrime.securesms.components.webrtc.EglBaseWrapper;
|
||||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||||
import org.thoughtcrime.securesms.events.WebRtcViewModel;
|
import org.thoughtcrime.securesms.events.WebRtcViewModel;
|
||||||
import org.thoughtcrime.securesms.groups.GroupId;
|
import org.thoughtcrime.securesms.groups.GroupId;
|
||||||
|
@ -34,7 +35,7 @@ public class IdleActionProcessor extends WebRtcActionProcessor {
|
||||||
protected @NonNull WebRtcServiceState handleStartIncomingCall(@NonNull WebRtcServiceState currentState, @NonNull RemotePeer remotePeer) {
|
protected @NonNull WebRtcServiceState handleStartIncomingCall(@NonNull WebRtcServiceState currentState, @NonNull RemotePeer remotePeer) {
|
||||||
Log.i(TAG, "handleStartIncomingCall():");
|
Log.i(TAG, "handleStartIncomingCall():");
|
||||||
|
|
||||||
currentState = WebRtcVideoUtil.initializeVideo(context, webRtcInteractor.getCameraEventListener(), currentState);
|
currentState = WebRtcVideoUtil.initializeVideo(context, webRtcInteractor.getCameraEventListener(), currentState, remotePeer.getCallId().longValue());
|
||||||
return beginCallDelegate.handleStartIncomingCall(currentState, remotePeer);
|
return beginCallDelegate.handleStartIncomingCall(currentState, remotePeer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,7 +52,7 @@ public class IdleActionProcessor extends WebRtcActionProcessor {
|
||||||
return currentState;
|
return currentState;
|
||||||
}
|
}
|
||||||
|
|
||||||
currentState = WebRtcVideoUtil.initializeVideo(context, webRtcInteractor.getCameraEventListener(), currentState);
|
currentState = WebRtcVideoUtil.initializeVideo(context, webRtcInteractor.getCameraEventListener(), currentState, EglBaseWrapper.OUTGOING_PLACEHOLDER);
|
||||||
return beginCallDelegate.handleOutgoingCall(currentState, remotePeer, offerType);
|
return beginCallDelegate.handleOutgoingCall(currentState, remotePeer, offerType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,7 +64,11 @@ public class IdleActionProcessor extends WebRtcActionProcessor {
|
||||||
WebRtcActionProcessor processor = isGroupCall ? new GroupPreJoinActionProcessor(webRtcInteractor)
|
WebRtcActionProcessor processor = isGroupCall ? new GroupPreJoinActionProcessor(webRtcInteractor)
|
||||||
: new PreJoinActionProcessor(webRtcInteractor);
|
: new PreJoinActionProcessor(webRtcInteractor);
|
||||||
|
|
||||||
currentState = WebRtcVideoUtil.initializeVanityCamera(WebRtcVideoUtil.initializeVideo(context, webRtcInteractor.getCameraEventListener(), currentState));
|
currentState = WebRtcVideoUtil.initializeVanityCamera(WebRtcVideoUtil.initializeVideo(context,
|
||||||
|
webRtcInteractor.getCameraEventListener(),
|
||||||
|
currentState,
|
||||||
|
isGroupCall ? RemotePeer.GROUP_CALL_ID.longValue()
|
||||||
|
: EglBaseWrapper.OUTGOING_PLACEHOLDER));
|
||||||
|
|
||||||
currentState = currentState.builder()
|
currentState = currentState.builder()
|
||||||
.actionProcessor(processor)
|
.actionProcessor(processor)
|
||||||
|
|
|
@ -204,11 +204,6 @@ public class IncomingCallActionProcessor extends DeviceAwareActionProcessor {
|
||||||
return activeCallDelegate.handleSetupFailure(currentState, callId);
|
return activeCallDelegate.handleSetupFailure(currentState, callId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected @NonNull WebRtcServiceState handleCallConcluded(@NonNull WebRtcServiceState currentState, @Nullable RemotePeer remotePeer) {
|
|
||||||
return activeCallDelegate.handleCallConcluded(currentState, remotePeer);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @NonNull WebRtcServiceState handleCallConnected(@NonNull WebRtcServiceState currentState, @NonNull RemotePeer remotePeer) {
|
public @NonNull WebRtcServiceState handleCallConnected(@NonNull WebRtcServiceState currentState, @NonNull RemotePeer remotePeer) {
|
||||||
return callSetupDelegate.handleCallConnected(currentState, remotePeer);
|
return callSetupDelegate.handleCallConnected(currentState, remotePeer);
|
||||||
|
|
|
@ -9,6 +9,7 @@ import org.signal.ringrtc.CallException;
|
||||||
import org.signal.ringrtc.CallManager;
|
import org.signal.ringrtc.CallManager;
|
||||||
import org.signal.ringrtc.GroupCall;
|
import org.signal.ringrtc.GroupCall;
|
||||||
import org.thoughtcrime.securesms.components.webrtc.BroadcastVideoSink;
|
import org.thoughtcrime.securesms.components.webrtc.BroadcastVideoSink;
|
||||||
|
import org.thoughtcrime.securesms.components.webrtc.EglBaseWrapper;
|
||||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||||
import org.thoughtcrime.securesms.database.RecipientDatabase;
|
import org.thoughtcrime.securesms.database.RecipientDatabase;
|
||||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
||||||
|
@ -105,7 +106,7 @@ public final class IncomingGroupCallActionProcessor extends DeviceAwareActionPro
|
||||||
|
|
||||||
DatabaseFactory.getGroupCallRingDatabase(context).insertGroupRing(ringId, System.currentTimeMillis(), ringUpdate);
|
DatabaseFactory.getGroupCallRingDatabase(context).insertGroupRing(ringId, System.currentTimeMillis(), ringUpdate);
|
||||||
|
|
||||||
currentState = WebRtcVideoUtil.initializeVideo(context, webRtcInteractor.getCameraEventListener(), currentState);
|
currentState = WebRtcVideoUtil.initializeVideo(context, webRtcInteractor.getCameraEventListener(), currentState, RemotePeer.GROUP_CALL_ID.longValue());
|
||||||
|
|
||||||
webRtcInteractor.setCallInProgressNotification(TYPE_INCOMING_RINGING, remotePeerGroup);
|
webRtcInteractor.setCallInProgressNotification(TYPE_INCOMING_RINGING, remotePeerGroup);
|
||||||
webRtcInteractor.updatePhoneState(LockManager.PhoneState.INTERACTIVE);
|
webRtcInteractor.updatePhoneState(LockManager.PhoneState.INTERACTIVE);
|
||||||
|
@ -240,10 +241,12 @@ public final class IncomingGroupCallActionProcessor extends DeviceAwareActionPro
|
||||||
webRtcInteractor.updatePhoneState(LockManager.PhoneState.IDLE);
|
webRtcInteractor.updatePhoneState(LockManager.PhoneState.IDLE);
|
||||||
webRtcInteractor.stopForegroundService();
|
webRtcInteractor.stopForegroundService();
|
||||||
|
|
||||||
return WebRtcVideoUtil.deinitializeVideo(currentState)
|
currentState = WebRtcVideoUtil.deinitializeVideo(currentState);
|
||||||
.builder()
|
EglBaseWrapper.releaseEglBase(RemotePeer.GROUP_CALL_ID.longValue());
|
||||||
.actionProcessor(new IdleActionProcessor(webRtcInteractor))
|
|
||||||
.terminate(RemotePeer.GROUP_CALL_ID)
|
return currentState.builder()
|
||||||
.build();
|
.actionProcessor(new IdleActionProcessor(webRtcInteractor))
|
||||||
|
.terminate(RemotePeer.GROUP_CALL_ID)
|
||||||
|
.build();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ import org.signal.core.util.logging.Log;
|
||||||
import org.signal.ringrtc.CallException;
|
import org.signal.ringrtc.CallException;
|
||||||
import org.signal.ringrtc.CallId;
|
import org.signal.ringrtc.CallId;
|
||||||
import org.signal.ringrtc.CallManager;
|
import org.signal.ringrtc.CallManager;
|
||||||
|
import org.thoughtcrime.securesms.components.webrtc.EglBaseWrapper;
|
||||||
import org.thoughtcrime.securesms.crypto.IdentityKeyUtil;
|
import org.thoughtcrime.securesms.crypto.IdentityKeyUtil;
|
||||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||||
import org.thoughtcrime.securesms.events.CallParticipant;
|
import org.thoughtcrime.securesms.events.CallParticipant;
|
||||||
|
@ -76,6 +77,8 @@ public class OutgoingCallActionProcessor extends DeviceAwareActionProcessor {
|
||||||
RecipientUtil.setAndSendUniversalExpireTimerIfNecessary(context, Recipient.resolved(remotePeer.getId()), DatabaseFactory.getThreadDatabase(context).getThreadIdIfExistsFor(remotePeer.getId()));
|
RecipientUtil.setAndSendUniversalExpireTimerIfNecessary(context, Recipient.resolved(remotePeer.getId()), DatabaseFactory.getThreadDatabase(context).getThreadIdIfExistsFor(remotePeer.getId()));
|
||||||
DatabaseFactory.getSmsDatabase(context).insertOutgoingCall(remotePeer.getId(), isVideoCall);
|
DatabaseFactory.getSmsDatabase(context).insertOutgoingCall(remotePeer.getId(), isVideoCall);
|
||||||
|
|
||||||
|
EglBaseWrapper.replaceHolder(EglBaseWrapper.OUTGOING_PLACEHOLDER, remotePeer.getCallId().longValue());
|
||||||
|
|
||||||
webRtcInteractor.retrieveTurnServers(remotePeer);
|
webRtcInteractor.retrieveTurnServers(remotePeer);
|
||||||
|
|
||||||
return builder.changeCallSetupState(remotePeer.getCallId())
|
return builder.changeCallSetupState(remotePeer.getCallId())
|
||||||
|
@ -210,11 +213,6 @@ public class OutgoingCallActionProcessor extends DeviceAwareActionProcessor {
|
||||||
return activeCallDelegate.handleSetupFailure(currentState, callId);
|
return activeCallDelegate.handleSetupFailure(currentState, callId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected @NonNull WebRtcServiceState handleCallConcluded(@NonNull WebRtcServiceState currentState, @Nullable RemotePeer remotePeer) {
|
|
||||||
return activeCallDelegate.handleCallConcluded(currentState, remotePeer);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @NonNull WebRtcServiceState handleCallConnected(@NonNull WebRtcServiceState currentState, @NonNull RemotePeer remotePeer) {
|
public @NonNull WebRtcServiceState handleCallConnected(@NonNull WebRtcServiceState currentState, @NonNull RemotePeer remotePeer) {
|
||||||
return callSetupDelegate.handleCallConnected(currentState, remotePeer);
|
return callSetupDelegate.handleCallConnected(currentState, remotePeer);
|
||||||
|
|
|
@ -3,6 +3,7 @@ package org.thoughtcrime.securesms.service.webrtc;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
import org.signal.core.util.logging.Log;
|
import org.signal.core.util.logging.Log;
|
||||||
|
import org.thoughtcrime.securesms.components.webrtc.EglBaseWrapper;
|
||||||
import org.thoughtcrime.securesms.events.WebRtcViewModel;
|
import org.thoughtcrime.securesms.events.WebRtcViewModel;
|
||||||
import org.thoughtcrime.securesms.ringrtc.RemotePeer;
|
import org.thoughtcrime.securesms.ringrtc.RemotePeer;
|
||||||
import org.thoughtcrime.securesms.service.webrtc.state.WebRtcServiceState;
|
import org.thoughtcrime.securesms.service.webrtc.state.WebRtcServiceState;
|
||||||
|
@ -28,6 +29,7 @@ public class PreJoinActionProcessor extends DeviceAwareActionProcessor {
|
||||||
Log.i(TAG, "handleCancelPreJoinCall():");
|
Log.i(TAG, "handleCancelPreJoinCall():");
|
||||||
|
|
||||||
WebRtcVideoUtil.deinitializeVideo(currentState);
|
WebRtcVideoUtil.deinitializeVideo(currentState);
|
||||||
|
EglBaseWrapper.releaseEglBase(EglBaseWrapper.OUTGOING_PLACEHOLDER);
|
||||||
|
|
||||||
return new WebRtcServiceState(new IdleActionProcessor(webRtcInteractor));
|
return new WebRtcServiceState(new IdleActionProcessor(webRtcInteractor));
|
||||||
}
|
}
|
||||||
|
@ -35,6 +37,7 @@ public class PreJoinActionProcessor extends DeviceAwareActionProcessor {
|
||||||
protected @NonNull WebRtcServiceState handleStartIncomingCall(@NonNull WebRtcServiceState currentState, @NonNull RemotePeer remotePeer) {
|
protected @NonNull WebRtcServiceState handleStartIncomingCall(@NonNull WebRtcServiceState currentState, @NonNull RemotePeer remotePeer) {
|
||||||
Log.i(TAG, "handleStartIncomingCall():");
|
Log.i(TAG, "handleStartIncomingCall():");
|
||||||
|
|
||||||
|
EglBaseWrapper.replaceHolder(EglBaseWrapper.OUTGOING_PLACEHOLDER, remotePeer.getCallId().longValue());
|
||||||
currentState = WebRtcVideoUtil.reinitializeCamera(context, webRtcInteractor.getCameraEventListener(), currentState)
|
currentState = WebRtcVideoUtil.reinitializeCamera(context, webRtcInteractor.getCameraEventListener(), currentState)
|
||||||
.builder()
|
.builder()
|
||||||
.changeCallInfoState()
|
.changeCallInfoState()
|
||||||
|
|
|
@ -16,6 +16,7 @@ import org.signal.ringrtc.CallManager.RingUpdate;
|
||||||
import org.signal.ringrtc.GroupCall;
|
import org.signal.ringrtc.GroupCall;
|
||||||
import org.thoughtcrime.securesms.components.sensors.Orientation;
|
import org.thoughtcrime.securesms.components.sensors.Orientation;
|
||||||
import org.thoughtcrime.securesms.components.webrtc.BroadcastVideoSink;
|
import org.thoughtcrime.securesms.components.webrtc.BroadcastVideoSink;
|
||||||
|
import org.thoughtcrime.securesms.components.webrtc.EglBaseWrapper;
|
||||||
import org.thoughtcrime.securesms.components.webrtc.GroupCallSafetyNumberChangeNotificationUtil;
|
import org.thoughtcrime.securesms.components.webrtc.GroupCallSafetyNumberChangeNotificationUtil;
|
||||||
import org.thoughtcrime.securesms.crypto.IdentityKeyUtil;
|
import org.thoughtcrime.securesms.crypto.IdentityKeyUtil;
|
||||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||||
|
@ -295,9 +296,21 @@ public abstract class WebRtcActionProcessor {
|
||||||
return currentState;
|
return currentState;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected @NonNull WebRtcServiceState handleCallConcluded(@NonNull WebRtcServiceState currentState, @Nullable RemotePeer remotePeer) {
|
final protected @NonNull WebRtcServiceState handleCallConcluded(@NonNull WebRtcServiceState currentState, @Nullable RemotePeer remotePeer) {
|
||||||
Log.i(tag, "handleCallConcluded not processed");
|
Log.i(tag, "handleCallConcluded():");
|
||||||
return currentState;
|
|
||||||
|
if (remotePeer == null) {
|
||||||
|
return currentState;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.i(tag, "delete remotePeer callId: " + remotePeer.getCallId() + " key: " + remotePeer.hashCode());
|
||||||
|
|
||||||
|
EglBaseWrapper.releaseEglBase(remotePeer.getCallId().longValue());
|
||||||
|
|
||||||
|
return currentState.builder()
|
||||||
|
.changeCallInfoState()
|
||||||
|
.removeRemotePeer(remotePeer)
|
||||||
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected @NonNull WebRtcServiceState handleRemoteVideoEnable(@NonNull WebRtcServiceState currentState, boolean enable) {
|
protected @NonNull WebRtcServiceState handleRemoteVideoEnable(@NonNull WebRtcServiceState currentState, boolean enable) {
|
||||||
|
@ -558,6 +571,8 @@ public abstract class WebRtcActionProcessor {
|
||||||
Log.w(tag, "Unable to reset call manager: ", e);
|
Log.w(tag, "Unable to reset call manager: ", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EglBaseWrapper.forceRelease();
|
||||||
|
|
||||||
currentState = builder.changeCallInfoState().clearPeerMap().build();
|
currentState = builder.changeCallInfoState().clearPeerMap().build();
|
||||||
return terminate(currentState, currentState.getCallInfoState().getActivePeer());
|
return terminate(currentState, currentState.getCallInfoState().getActivePeer());
|
||||||
}
|
}
|
||||||
|
@ -596,7 +611,7 @@ public abstract class WebRtcActionProcessor {
|
||||||
.commit()
|
.commit()
|
||||||
.changeLocalDeviceState()
|
.changeLocalDeviceState()
|
||||||
.commit()
|
.commit()
|
||||||
.actionProcessor(currentState.getCallInfoState().getCallState() == WebRtcViewModel.State.CALL_DISCONNECTED ? new DisconnectingCallActionProcessor(webRtcInteractor) : new IdleActionProcessor(webRtcInteractor))
|
.actionProcessor(new IdleActionProcessor(webRtcInteractor))
|
||||||
.terminate(remotePeer.getCallId())
|
.terminate(remotePeer.getCallId())
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
@ -748,6 +763,7 @@ public abstract class WebRtcActionProcessor {
|
||||||
|
|
||||||
if (terminateVideo) {
|
if (terminateVideo) {
|
||||||
WebRtcVideoUtil.deinitializeVideo(currentState);
|
WebRtcVideoUtil.deinitializeVideo(currentState);
|
||||||
|
EglBaseWrapper.releaseEglBase(RemotePeer.GROUP_CALL_ID.longValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
GroupCallSafetyNumberChangeNotificationUtil.cancelNotification(context, currentState.getCallInfoState().getCallRecipient());
|
GroupCallSafetyNumberChangeNotificationUtil.cancelNotification(context, currentState.getCallInfoState().getCallRecipient());
|
||||||
|
|
|
@ -13,7 +13,6 @@ import org.thoughtcrime.securesms.ringrtc.CameraState;
|
||||||
import org.thoughtcrime.securesms.service.webrtc.state.WebRtcServiceState;
|
import org.thoughtcrime.securesms.service.webrtc.state.WebRtcServiceState;
|
||||||
import org.thoughtcrime.securesms.service.webrtc.state.WebRtcServiceStateBuilder;
|
import org.thoughtcrime.securesms.service.webrtc.state.WebRtcServiceStateBuilder;
|
||||||
import org.webrtc.CapturerObserver;
|
import org.webrtc.CapturerObserver;
|
||||||
import org.webrtc.EglBase;
|
|
||||||
import org.webrtc.VideoFrame;
|
import org.webrtc.VideoFrame;
|
||||||
import org.webrtc.VideoSink;
|
import org.webrtc.VideoSink;
|
||||||
|
|
||||||
|
@ -27,12 +26,13 @@ public final class WebRtcVideoUtil {
|
||||||
|
|
||||||
public static @NonNull WebRtcServiceState initializeVideo(@NonNull Context context,
|
public static @NonNull WebRtcServiceState initializeVideo(@NonNull Context context,
|
||||||
@NonNull CameraEventListener cameraEventListener,
|
@NonNull CameraEventListener cameraEventListener,
|
||||||
@NonNull WebRtcServiceState currentState)
|
@NonNull WebRtcServiceState currentState,
|
||||||
|
@NonNull Object eglBaseHolder)
|
||||||
{
|
{
|
||||||
final WebRtcServiceStateBuilder builder = currentState.builder();
|
final WebRtcServiceStateBuilder builder = currentState.builder();
|
||||||
|
|
||||||
ThreadUtil.runOnMainSync(() -> {
|
ThreadUtil.runOnMainSync(() -> {
|
||||||
EglBaseWrapper eglBase = new EglBaseWrapper(EglBase.create());
|
EglBaseWrapper eglBase = EglBaseWrapper.acquireEglBase(eglBaseHolder);
|
||||||
BroadcastVideoSink localSink = new BroadcastVideoSink(eglBase,
|
BroadcastVideoSink localSink = new BroadcastVideoSink(eglBase,
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
|
@ -89,8 +89,6 @@ public final class WebRtcVideoUtil {
|
||||||
camera.dispose();
|
camera.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
currentState.getVideoState().getLockableEglBase().releaseEglBase();
|
|
||||||
|
|
||||||
return currentState.builder()
|
return currentState.builder()
|
||||||
.changeVideoState()
|
.changeVideoState()
|
||||||
.eglBase(null)
|
.eglBase(null)
|
||||||
|
|
Loading…
Add table
Reference in a new issue