mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-22 01:40:07 +01:00
Add peek and join capabilities to call links implementation.
This commit is contained in:
committed by
Cody Henthorne
parent
f8434bede5
commit
62940893f0
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright 2023 Signal Messenger, LLC
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package org.thoughtcrime.securesms.service.webrtc
|
||||
|
||||
import org.signal.core.util.logging.Log
|
||||
import org.thoughtcrime.securesms.service.webrtc.state.WebRtcServiceState
|
||||
|
||||
/**
|
||||
* Process actions for when the call link has at least once been connected and joined.
|
||||
*/
|
||||
class CallLinkConnectedActionProcessor(
|
||||
webRtcInteractor: WebRtcInteractor
|
||||
) : GroupConnectedActionProcessor(webRtcInteractor) {
|
||||
override fun getGroupNetworkUnavailableActionProcessor(): GroupNetworkUnavailableActionProcessor {
|
||||
return CallLinkNetworkUnavailableActionProcessor(webRtcInteractor)
|
||||
}
|
||||
|
||||
override fun handleGroupRequestUpdateMembers(currentState: WebRtcServiceState): WebRtcServiceState {
|
||||
Log.i(tag, "handleGroupRequestUpdateMembers():")
|
||||
|
||||
return currentState
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright 2023 Signal Messenger, LLC
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package org.thoughtcrime.securesms.service.webrtc
|
||||
|
||||
import org.signal.core.util.logging.Log
|
||||
import org.thoughtcrime.securesms.service.webrtc.state.WebRtcServiceState
|
||||
|
||||
/**
|
||||
* Process actions to go from lobby to a joined call link.
|
||||
*/
|
||||
class CallLinkJoiningActionProcessor(
|
||||
webRtcInteractor: WebRtcInteractor
|
||||
) : GroupJoiningActionProcessor(webRtcInteractor) {
|
||||
override fun getGroupNetworkUnavailableActionProcessor(): GroupNetworkUnavailableActionProcessor {
|
||||
return CallLinkNetworkUnavailableActionProcessor(webRtcInteractor)
|
||||
}
|
||||
|
||||
override fun handleGroupRequestUpdateMembers(currentState: WebRtcServiceState): WebRtcServiceState {
|
||||
Log.i(tag, "handleGroupRequestUpdateMembers():")
|
||||
|
||||
return currentState
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright 2023 Signal Messenger, LLC
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package org.thoughtcrime.securesms.service.webrtc
|
||||
|
||||
/**
|
||||
* Processor which is utilized when the network becomes unavailable during a call link call. In general,
|
||||
* this is triggered whenever there is a call ended, and the ending was not the result of direct user
|
||||
* action.
|
||||
*
|
||||
* This class will check the network status when handlePreJoinCall is invoked, and transition to
|
||||
* [CallLinkPreJoinActionProcessor] as network becomes available again.
|
||||
*/
|
||||
class CallLinkNetworkUnavailableActionProcessor(
|
||||
webRtcInteractor: WebRtcInteractor
|
||||
) : GroupNetworkUnavailableActionProcessor(webRtcInteractor) {
|
||||
override fun createGroupPreJoinActionProcessor(): GroupPreJoinActionProcessor {
|
||||
return CallLinkPreJoinActionProcessor(webRtcInteractor)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright 2023 Signal Messenger, LLC
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package org.thoughtcrime.securesms.service.webrtc
|
||||
|
||||
import org.signal.ringrtc.CallId
|
||||
import org.signal.ringrtc.PeekInfo
|
||||
|
||||
/**
|
||||
* App-level peek info object for call links.
|
||||
*/
|
||||
data class CallLinkPeekInfo(
|
||||
val callId: CallId?
|
||||
) {
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun fromPeekInfo(peekInfo: PeekInfo): CallLinkPeekInfo {
|
||||
return CallLinkPeekInfo(
|
||||
callId = peekInfo.eraId?.let { CallId.fromEra(it) }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright 2023 Signal Messenger, LLC
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package org.thoughtcrime.securesms.service.webrtc
|
||||
|
||||
import org.signal.core.util.logging.Log
|
||||
import org.signal.libsignal.zkgroup.GenericServerPublicParams
|
||||
import org.signal.libsignal.zkgroup.InvalidInputException
|
||||
import org.signal.libsignal.zkgroup.VerificationFailedException
|
||||
import org.signal.libsignal.zkgroup.calllinks.CallLinkSecretParams
|
||||
import org.signal.ringrtc.CallException
|
||||
import org.signal.ringrtc.CallLinkRootKey
|
||||
import org.thoughtcrime.securesms.database.SignalDatabase.Companion.callLinks
|
||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies
|
||||
import org.thoughtcrime.securesms.events.WebRtcViewModel
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
||||
import org.thoughtcrime.securesms.ringrtc.RemotePeer
|
||||
import org.thoughtcrime.securesms.service.webrtc.RingRtcDynamicConfiguration.getAudioProcessingMethod
|
||||
import org.thoughtcrime.securesms.service.webrtc.state.WebRtcServiceState
|
||||
import org.thoughtcrime.securesms.util.NetworkUtil
|
||||
import java.io.IOException
|
||||
|
||||
/**
|
||||
* Process actions while the user is in the pre-join lobby for the call link.
|
||||
*/
|
||||
class CallLinkPreJoinActionProcessor(
|
||||
webRtcInteractor: WebRtcInteractor
|
||||
) : GroupPreJoinActionProcessor(webRtcInteractor) {
|
||||
|
||||
companion object {
|
||||
private val TAG = Log.tag(CallLinkPreJoinActionProcessor::class.java)
|
||||
}
|
||||
|
||||
override fun handlePreJoinCall(currentState: WebRtcServiceState, remotePeer: RemotePeer): WebRtcServiceState {
|
||||
Log.i(TAG, "handlePreJoinCall():")
|
||||
|
||||
val groupCall = try {
|
||||
val callLink = callLinks.getCallLinkByRoomId(remotePeer.recipient.requireCallLinkRoomId())
|
||||
if (callLink?.credentials == null) {
|
||||
return groupCallFailure(currentState, "No access to this call link.", Exception())
|
||||
}
|
||||
|
||||
val callLinkRootKey = CallLinkRootKey(callLink.credentials.linkKeyBytes)
|
||||
val callLinkSecretParams = CallLinkSecretParams.deriveFromRootKey(callLink.credentials.linkKeyBytes)
|
||||
val genericServerPublicParams = GenericServerPublicParams(
|
||||
ApplicationDependencies.getSignalServiceNetworkAccess()
|
||||
.getConfiguration()
|
||||
.genericServerPublicParams
|
||||
)
|
||||
|
||||
val callLinkAuthCredentialPresentation = ApplicationDependencies
|
||||
.getGroupsV2Authorization()
|
||||
.getCallLinkAuthorizationForToday(genericServerPublicParams, callLinkSecretParams)
|
||||
|
||||
webRtcInteractor.callManager.createCallLinkCall(
|
||||
SignalStore.internalValues().groupCallingServer(),
|
||||
callLinkAuthCredentialPresentation.serialize(),
|
||||
callLinkRootKey,
|
||||
callLink.credentials.adminPassBytes,
|
||||
ByteArray(0),
|
||||
AUDIO_LEVELS_INTERVAL,
|
||||
getAudioProcessingMethod(),
|
||||
webRtcInteractor.groupCallObserver
|
||||
)
|
||||
} catch (e: InvalidInputException) {
|
||||
return groupCallFailure(currentState, "Failed to create server public parameters.", e)
|
||||
} catch (e: IOException) {
|
||||
return groupCallFailure(currentState, "Failed to get call link authorization", e)
|
||||
} catch (e: VerificationFailedException) {
|
||||
return groupCallFailure(currentState, "Failed to get call link authorization", e)
|
||||
} catch (e: CallException) {
|
||||
return groupCallFailure(currentState, "Failed to parse call link root key", e)
|
||||
} ?: return groupCallFailure(currentState, "Failed to create group call object for call link.", Exception())
|
||||
|
||||
try {
|
||||
groupCall.setOutgoingAudioMuted(true)
|
||||
groupCall.setOutgoingVideoMuted(true)
|
||||
groupCall.setDataMode(NetworkUtil.getCallingDataMode(context, groupCall.localDeviceState.networkRoute.localAdapterType))
|
||||
Log.i(TAG, "Connecting to group call: " + currentState.callInfoState.callRecipient.id)
|
||||
groupCall.connect()
|
||||
} catch (e: CallException) {
|
||||
return groupCallFailure(currentState, "Unable to connect to call link", e)
|
||||
}
|
||||
|
||||
SignalStore.tooltips().markGroupCallingLobbyEntered()
|
||||
return currentState.builder()
|
||||
.changeCallInfoState()
|
||||
.groupCall(groupCall)
|
||||
.groupCallState(WebRtcViewModel.GroupCallState.DISCONNECTED)
|
||||
.activePeer(RemotePeer(currentState.callInfoState.callRecipient.id, RemotePeer.GROUP_CALL_ID))
|
||||
.build()
|
||||
}
|
||||
|
||||
override fun handleGroupRequestUpdateMembers(currentState: WebRtcServiceState): WebRtcServiceState {
|
||||
Log.i(tag, "handleGroupRequestUpdateMembers():")
|
||||
|
||||
return currentState
|
||||
}
|
||||
|
||||
override fun getGroupNetworkUnavailableActionProcessor(): GroupNetworkUnavailableActionProcessor {
|
||||
return CallLinkNetworkUnavailableActionProcessor(webRtcInteractor)
|
||||
}
|
||||
}
|
||||
@@ -295,7 +295,7 @@ public class GroupActionProcessor extends DeviceAwareActionProcessor {
|
||||
VideoState videoState = currentState.getVideoState();
|
||||
|
||||
currentState = terminateGroupCall(currentState, false).builder()
|
||||
.actionProcessor(new GroupNetworkUnavailableActionProcessor(webRtcInteractor))
|
||||
.actionProcessor(getGroupNetworkUnavailableActionProcessor())
|
||||
.changeVideoState()
|
||||
.eglBase(videoState.getLockableEglBase())
|
||||
.camera(videoState.getCamera())
|
||||
@@ -321,4 +321,8 @@ public class GroupActionProcessor extends DeviceAwareActionProcessor {
|
||||
|
||||
return terminateGroupCall(currentState);
|
||||
}
|
||||
|
||||
public @NonNull GroupNetworkUnavailableActionProcessor getGroupNetworkUnavailableActionProcessor() {
|
||||
return new GroupNetworkUnavailableActionProcessor(webRtcInteractor);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ import org.thoughtcrime.securesms.service.webrtc.state.WebRtcServiceState;
|
||||
* This class will check the network status when handlePreJoinCall is invoked, and transition to
|
||||
* GroupPreJoinActionProcessor as network becomes available again.
|
||||
*/
|
||||
class GroupNetworkUnavailableActionProcessor extends WebRtcActionProcessor {
|
||||
public class GroupNetworkUnavailableActionProcessor extends WebRtcActionProcessor {
|
||||
|
||||
private static final String TAG = Log.tag(GroupNetworkUnavailableActionProcessor.class);
|
||||
|
||||
@@ -38,7 +38,7 @@ class GroupNetworkUnavailableActionProcessor extends WebRtcActionProcessor {
|
||||
NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
|
||||
|
||||
if (activeNetworkInfo != null && activeNetworkInfo.isConnected()) {
|
||||
GroupPreJoinActionProcessor processor = new GroupPreJoinActionProcessor(webRtcInteractor);
|
||||
GroupPreJoinActionProcessor processor = createGroupPreJoinActionProcessor();
|
||||
return processor.handlePreJoinCall(currentState.builder().actionProcessor(processor).build(), remotePeer);
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ class GroupNetworkUnavailableActionProcessor extends WebRtcActionProcessor {
|
||||
public @NonNull WebRtcServiceState handleNetworkChanged(@NonNull WebRtcServiceState currentState, boolean available) {
|
||||
if (available) {
|
||||
return currentState.builder()
|
||||
.actionProcessor(new GroupPreJoinActionProcessor(webRtcInteractor))
|
||||
.actionProcessor(createGroupPreJoinActionProcessor())
|
||||
.changeCallInfoState()
|
||||
.callState(WebRtcViewModel.State.CALL_PRE_JOIN)
|
||||
.build();
|
||||
@@ -80,4 +80,8 @@ class GroupNetworkUnavailableActionProcessor extends WebRtcActionProcessor {
|
||||
return currentState;
|
||||
}
|
||||
}
|
||||
|
||||
protected @NonNull GroupPreJoinActionProcessor createGroupPreJoinActionProcessor() {
|
||||
return new GroupPreJoinActionProcessor(webRtcInteractor);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -207,7 +207,7 @@ public class GroupPreJoinActionProcessor extends GroupActionProcessor {
|
||||
public @NonNull WebRtcServiceState handleNetworkChanged(@NonNull WebRtcServiceState currentState, boolean available) {
|
||||
if (!available) {
|
||||
return currentState.builder()
|
||||
.actionProcessor(new GroupNetworkUnavailableActionProcessor(webRtcInteractor))
|
||||
.actionProcessor(getGroupNetworkUnavailableActionProcessor())
|
||||
.changeCallInfoState()
|
||||
.callState(WebRtcViewModel.State.NETWORK_FAILURE)
|
||||
.build();
|
||||
|
||||
@@ -65,9 +65,16 @@ public class IdleActionProcessor extends WebRtcActionProcessor {
|
||||
protected @NonNull WebRtcServiceState handlePreJoinCall(@NonNull WebRtcServiceState currentState, @NonNull RemotePeer remotePeer) {
|
||||
Log.i(TAG, "handlePreJoinCall():");
|
||||
|
||||
boolean isGroupCall = remotePeer.getRecipient().isPushV2Group() || remotePeer.getRecipient().isCallLink();
|
||||
WebRtcActionProcessor processor = isGroupCall ? new GroupPreJoinActionProcessor(webRtcInteractor)
|
||||
: new PreJoinActionProcessor(webRtcInteractor);
|
||||
boolean isGroupCall = remotePeer.getRecipient().isPushV2Group() || remotePeer.getRecipient().isCallLink();
|
||||
|
||||
final WebRtcActionProcessor processor;
|
||||
if (remotePeer.getRecipient().isCallLink()) {
|
||||
processor = new CallLinkPreJoinActionProcessor(webRtcInteractor);
|
||||
} else if (remotePeer.getRecipient().isPushV2Group()) {
|
||||
processor = new GroupPreJoinActionProcessor(webRtcInteractor);
|
||||
} else {
|
||||
processor = new PreJoinActionProcessor(webRtcInteractor);
|
||||
}
|
||||
|
||||
currentState = WebRtcVideoUtil.initializeVanityCamera(WebRtcVideoUtil.initializeVideo(context,
|
||||
webRtcInteractor.getCameraEventListener(),
|
||||
|
||||
@@ -16,11 +16,15 @@ import org.greenrobot.eventbus.EventBus;
|
||||
import org.signal.core.util.concurrent.SignalExecutors;
|
||||
import org.signal.core.util.logging.Log;
|
||||
import org.signal.libsignal.protocol.util.Pair;
|
||||
import org.signal.libsignal.zkgroup.GenericServerPublicParams;
|
||||
import org.signal.libsignal.zkgroup.InvalidInputException;
|
||||
import org.signal.libsignal.zkgroup.VerificationFailedException;
|
||||
import org.signal.libsignal.zkgroup.calllinks.CallLinkAuthCredentialPresentation;
|
||||
import org.signal.libsignal.zkgroup.calllinks.CallLinkSecretParams;
|
||||
import org.signal.libsignal.zkgroup.groups.GroupIdentifier;
|
||||
import org.signal.ringrtc.CallException;
|
||||
import org.signal.ringrtc.CallId;
|
||||
import org.signal.ringrtc.CallLinkRootKey;
|
||||
import org.signal.ringrtc.CallManager;
|
||||
import org.signal.ringrtc.GroupCall;
|
||||
import org.signal.ringrtc.HttpHeader;
|
||||
@@ -30,6 +34,7 @@ import org.signal.ringrtc.Remote;
|
||||
import org.signal.storageservice.protos.groups.GroupExternalCredential;
|
||||
import org.thoughtcrime.securesms.WebRtcCallActivity;
|
||||
import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil;
|
||||
import org.thoughtcrime.securesms.database.CallLinkTable;
|
||||
import org.thoughtcrime.securesms.database.CallTable;
|
||||
import org.thoughtcrime.securesms.database.GroupTable;
|
||||
import org.thoughtcrime.securesms.database.SignalDatabase;
|
||||
@@ -52,11 +57,13 @@ import org.thoughtcrime.securesms.recipients.RecipientUtil;
|
||||
import org.thoughtcrime.securesms.ringrtc.CameraEventListener;
|
||||
import org.thoughtcrime.securesms.ringrtc.CameraState;
|
||||
import org.thoughtcrime.securesms.ringrtc.RemotePeer;
|
||||
import org.thoughtcrime.securesms.service.webrtc.links.CallLinkRoomId;
|
||||
import org.thoughtcrime.securesms.service.webrtc.links.SignalCallLinkManager;
|
||||
import org.thoughtcrime.securesms.service.webrtc.state.WebRtcEphemeralState;
|
||||
import org.thoughtcrime.securesms.service.webrtc.state.WebRtcServiceState;
|
||||
import org.thoughtcrime.securesms.util.AppForegroundObserver;
|
||||
import org.thoughtcrime.securesms.util.BubbleUtil;
|
||||
import org.thoughtcrime.securesms.util.FeatureFlags;
|
||||
import org.thoughtcrime.securesms.util.RecipientAccessList;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
@@ -80,8 +87,10 @@ import org.whispersystems.signalservice.internal.push.SignalServiceProtos.SyncMe
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
@@ -123,12 +132,15 @@ public final class SignalCallManager implements CallManager.Observer, GroupCall.
|
||||
private RxStore<WebRtcEphemeralState> ephemeralStateStore;
|
||||
private boolean needsToSetSelfUuid = true;
|
||||
|
||||
private RxStore<Map<RecipientId, CallLinkPeekInfo>> linkPeekInfoStore;
|
||||
|
||||
public SignalCallManager(@NonNull Application application) {
|
||||
this.context = application.getApplicationContext();
|
||||
this.lockManager = new LockManager(this.context);
|
||||
this.serviceExecutor = Executors.newSingleThreadExecutor();
|
||||
this.networkExecutor = Executors.newSingleThreadExecutor();
|
||||
this.ephemeralStateStore = new RxStore<>(new WebRtcEphemeralState(), Schedulers.from(serviceExecutor));
|
||||
this.linkPeekInfoStore = new RxStore<>(new HashMap<>(), Schedulers.from(serviceExecutor));
|
||||
|
||||
CallManager callManager = null;
|
||||
try {
|
||||
@@ -159,6 +171,14 @@ public final class SignalCallManager implements CallManager.Observer, GroupCall.
|
||||
return lockManager;
|
||||
}
|
||||
|
||||
public @NonNull Flowable<Map<RecipientId, CallLinkPeekInfo>> getPeekInfoCache() {
|
||||
return linkPeekInfoStore.getStateFlowable();
|
||||
}
|
||||
|
||||
public @NonNull Map<RecipientId, CallLinkPeekInfo> getPeekInfoSnapshot() {
|
||||
return linkPeekInfoStore.getState();
|
||||
}
|
||||
|
||||
private void process(@NonNull ProcessAction action) {
|
||||
Throwable t = new Throwable();
|
||||
String caller = t.getStackTrace().length > 1 ? t.getStackTrace()[1].getMethodName() : "unknown";
|
||||
@@ -334,6 +354,59 @@ private void processStateless(@NonNull Function1<WebRtcEphemeralState, WebRtcEph
|
||||
process((s, p) -> p.handleDropCall(s, callId));
|
||||
}
|
||||
|
||||
public void peekCallLinkCall(@NonNull RecipientId id) {
|
||||
if (callManager == null) {
|
||||
Log.i(TAG, "Unable to peekCallLinkCall, call manager is null");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!FeatureFlags.adHocCalling()) {
|
||||
Log.i(TAG, "Ad Hoc Calling is disabled. Ignoring request to peek.");
|
||||
return;
|
||||
}
|
||||
|
||||
networkExecutor.execute(() -> {
|
||||
try {
|
||||
Recipient callLinkRecipient = Recipient.resolved(id);
|
||||
CallLinkRoomId callLinkRoomId = callLinkRecipient.requireCallLinkRoomId();
|
||||
CallLinkTable.CallLink callLink = SignalDatabase.callLinks().getCallLinkByRoomId(callLinkRoomId);
|
||||
|
||||
if (callLink == null || callLink.getCredentials() == null) {
|
||||
Log.w(TAG, "Cannot peek call link without credentials.");
|
||||
return;
|
||||
}
|
||||
|
||||
CallLinkRootKey callLinkRootKey = new CallLinkRootKey(callLink.getCredentials().getLinkKeyBytes());
|
||||
GenericServerPublicParams genericServerPublicParams = new GenericServerPublicParams(ApplicationDependencies.getSignalServiceNetworkAccess()
|
||||
.getConfiguration()
|
||||
.getGenericServerPublicParams());
|
||||
|
||||
|
||||
CallLinkAuthCredentialPresentation callLinkAuthCredentialPresentation = ApplicationDependencies.getGroupsV2Authorization()
|
||||
.getCallLinkAuthorizationForToday(
|
||||
genericServerPublicParams,
|
||||
CallLinkSecretParams.deriveFromRootKey(callLinkRootKey.getKeyBytes())
|
||||
);
|
||||
|
||||
callManager.peekCallLinkCall(SignalStore.internalValues().groupCallingServer(), callLinkAuthCredentialPresentation.serialize(), callLinkRootKey, peekInfo -> {
|
||||
PeekInfo info = peekInfo.getValue();
|
||||
if (info == null) {
|
||||
Log.w(TAG, "Failed to get peek info: " + peekInfo.getStatus());
|
||||
return;
|
||||
}
|
||||
|
||||
linkPeekInfoStore.update(store -> {
|
||||
Map<RecipientId, CallLinkPeekInfo> newHashMap = new HashMap<>(store);
|
||||
newHashMap.put(id, CallLinkPeekInfo.fromPeekInfo(info));
|
||||
return newHashMap;
|
||||
});
|
||||
});
|
||||
} catch (CallException | VerificationFailedException | InvalidInputException | IOException e) {
|
||||
Log.i(TAG, "error peeking call link", e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void peekGroupCall(@NonNull RecipientId id) {
|
||||
if (callManager == null) {
|
||||
Log.i(TAG, "Unable to peekGroupCall, call manager is null");
|
||||
@@ -349,7 +422,6 @@ private void processStateless(@NonNull Function1<WebRtcEphemeralState, WebRtcEph
|
||||
List<GroupCall.GroupMemberInfo> members = Stream.of(GroupManager.getUuidCipherTexts(context, groupId))
|
||||
.map(entry -> new GroupCall.GroupMemberInfo(entry.getKey(), entry.getValue().serialize()))
|
||||
.toList();
|
||||
|
||||
callManager.peekGroupCall(SignalStore.internalValues().groupCallingServer(), credential.getTokenBytes().toByteArray(), members, peekInfo -> {
|
||||
Long threadId = SignalDatabase.threads().getThreadIdFor(group.getId());
|
||||
|
||||
@@ -541,7 +613,7 @@ private void processStateless(@NonNull Function1<WebRtcEphemeralState, WebRtcEph
|
||||
process((s, p) -> p.handleNetworkRouteChanged(s, networkRoute));
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override
|
||||
public void onAudioLevels(Remote remote, int capturedLevel, int receivedLevel) {
|
||||
processStateless(s -> serviceState.getActionProcessor().handleAudioLevelsChanged(serviceState, s, capturedLevel, receivedLevel));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user