Fix call screen timeout with remote video active.

This commit is contained in:
Alex Hart
2025-12-03 15:17:43 -04:00
committed by jeffrey-signal
parent 7297f7a894
commit c6de4c7650
8 changed files with 54 additions and 28 deletions

View File

@@ -80,10 +80,17 @@ public class ActiveCallActionProcessorDelegate extends WebRtcActionProcessor {
CallParticipant oldParticipant = Objects.requireNonNull(currentState.getCallInfoState().getRemoteCallParticipant(activePeer.getRecipient()));
CallParticipant newParticipant = oldParticipant.withVideoEnabled(enable);
return currentState.builder()
.changeCallInfoState()
.putParticipant(activePeer.getRecipient(), newParticipant)
.build();
currentState = currentState.builder()
.changeCallInfoState()
.putParticipant(activePeer.getRecipient(), newParticipant)
.build();
if (currentState.getCallInfoState().getCallState() == WebRtcViewModel.State.CALL_CONNECTED) {
boolean localVideoEnabled = currentState.getLocalDeviceState().getCameraState().isEnabled();
webRtcInteractor.updatePhoneState(WebRtcUtil.getInCallPhoneState(context, localVideoEnabled, enable));
}
return currentState;
}
@Override

View File

@@ -50,11 +50,9 @@ public class CallSetupActionProcessorDelegate extends WebRtcActionProcessor {
activePeer.connected();
if (currentState.getLocalDeviceState().getCameraState().isEnabled()) {
webRtcInteractor.updatePhoneState(LockManager.PhoneState.IN_VIDEO);
} else {
webRtcInteractor.updatePhoneState(WebRtcUtil.getInCallPhoneState(context));
}
boolean localVideoEnabled = currentState.getLocalDeviceState().getCameraState().isEnabled();
boolean remoteVideoEnabled = currentState.getCallSetupState(activePeer).isRemoteVideoOffer();
webRtcInteractor.updatePhoneState(WebRtcUtil.getInCallPhoneState(context, localVideoEnabled, remoteVideoEnabled));
currentState = currentState.builder()
.actionProcessor(new ConnectedCallActionProcessor(webRtcInteractor))

View File

@@ -14,7 +14,6 @@ import org.thoughtcrime.securesms.events.WebRtcViewModel;
import org.thoughtcrime.securesms.ringrtc.RemotePeer;
import org.thoughtcrime.securesms.service.webrtc.state.WebRtcEphemeralState;
import org.thoughtcrime.securesms.service.webrtc.state.WebRtcServiceState;
import org.thoughtcrime.securesms.webrtc.locks.LockManager;
import java.util.Collections;
import java.util.Optional;
@@ -54,11 +53,9 @@ public class ConnectedCallActionProcessor extends DeviceAwareActionProcessor {
.cameraState(currentState.getVideoState().requireCamera().getCameraState())
.build();
if (currentState.getLocalDeviceState().getCameraState().isEnabled()) {
webRtcInteractor.updatePhoneState(LockManager.PhoneState.IN_VIDEO);
} else {
webRtcInteractor.updatePhoneState(WebRtcUtil.getInCallPhoneState(context));
}
boolean localVideoEnabled = currentState.getLocalDeviceState().getCameraState().isEnabled();
boolean remoteVideoEnabled = currentState.getCallInfoState().getRemoteCallParticipantsMap().values().stream().anyMatch(CallParticipant::isVideoEnabled);
webRtcInteractor.updatePhoneState(WebRtcUtil.getInCallPhoneState(context, localVideoEnabled, remoteVideoEnabled));
WebRtcUtil.enableSpeakerPhoneIfNeeded(webRtcInteractor, currentState);

View File

@@ -7,6 +7,7 @@ import org.thoughtcrime.securesms.components.webrtc.BroadcastVideoSink;
import org.thoughtcrime.securesms.events.WebRtcViewModel;
import org.thoughtcrime.securesms.ringrtc.CameraState;
import org.thoughtcrime.securesms.ringrtc.RemotePeer;
import org.thoughtcrime.securesms.events.CallParticipant;
import org.thoughtcrime.securesms.service.webrtc.state.WebRtcServiceState;
import org.thoughtcrime.securesms.webrtc.audio.SignalAudioManager;
@@ -27,12 +28,12 @@ public abstract class DeviceAwareActionProcessor extends WebRtcActionProcessor {
protected @NonNull WebRtcServiceState handleAudioDeviceChanged(@NonNull WebRtcServiceState currentState, @NonNull SignalAudioManager.AudioDevice activeDevice, @NonNull Set<SignalAudioManager.AudioDevice> availableDevices) {
Log.i(tag, "handleAudioDeviceChanged(): active: " + activeDevice + " available: " + availableDevices);
if (!currentState.getLocalDeviceState().getCameraState().isEnabled()) {
if (currentState.getCallInfoState().getCallState() == WebRtcViewModel.State.CALL_CONNECTED) {
webRtcInteractor.updatePhoneState(WebRtcUtil.getInCallPhoneState(context));
} else {
Log.i(tag, "handleAudioDeviceChanged(): call not connected, not updating phone state");
}
if (currentState.getCallInfoState().getCallState() == WebRtcViewModel.State.CALL_CONNECTED) {
boolean localVideoEnabled = currentState.getLocalDeviceState().getCameraState().isEnabled();
boolean remoteVideoEnabled = currentState.getCallInfoState().getRemoteCallParticipantsMap().values().stream().anyMatch(CallParticipant::isVideoEnabled);
webRtcInteractor.updatePhoneState(WebRtcUtil.getInCallPhoneState(context, localVideoEnabled, remoteVideoEnabled));
} else {
Log.i(tag, "handleAudioDeviceChanged(): call not connected, not updating phone state");
}
return currentState.builder()

View File

@@ -14,6 +14,7 @@ import org.thoughtcrime.securesms.components.webrtc.BroadcastVideoSink;
import org.thoughtcrime.securesms.events.CallParticipant;
import org.thoughtcrime.securesms.events.CallParticipantId;
import org.thoughtcrime.securesms.events.WebRtcViewModel;
import org.thoughtcrime.securesms.events.WebRtcViewModel.State;
import org.thoughtcrime.securesms.groups.GroupManager;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.RecipientId;
@@ -132,7 +133,15 @@ public class GroupActionProcessor extends DeviceAwareActionProcessor {
builder.remoteDevicesCount(remoteDevices.size());
return builder.build();
WebRtcServiceState updatedState = builder.build();
if (updatedState.getCallInfoState().getCallState() == State.CALL_CONNECTED) {
boolean localVideoEnabled = updatedState.getLocalDeviceState().getCameraState().isEnabled();
boolean remoteVideoEnabled = updatedState.getCallInfoState().getRemoteCallParticipantsMap().values().stream().anyMatch(CallParticipant::isVideoEnabled);
webRtcInteractor.updatePhoneState(WebRtcUtil.getInCallPhoneState(context, localVideoEnabled, remoteVideoEnabled));
}
return updatedState;
}
@Override

View File

@@ -103,6 +103,10 @@ public class GroupConnectedActionProcessor extends GroupActionProcessor {
.cameraState(camera.getCameraState())
.build();
boolean localVideoEnabled = currentState.getLocalDeviceState().getCameraState().isEnabled();
boolean remoteVideoEnabled = currentState.getCallInfoState().getRemoteCallParticipantsMap().values().stream().anyMatch(CallParticipant::isVideoEnabled);
webRtcInteractor.updatePhoneState(WebRtcUtil.getInCallPhoneState(context, localVideoEnabled, remoteVideoEnabled));
WebRtcUtil.enableSpeakerPhoneIfNeeded(webRtcInteractor, currentState);
return currentState;

View File

@@ -12,9 +12,9 @@ import org.thoughtcrime.securesms.events.WebRtcViewModel;
import org.thoughtcrime.securesms.ringrtc.Camera;
import org.thoughtcrime.securesms.ringrtc.RemotePeer;
import org.thoughtcrime.securesms.service.webrtc.state.WebRtcServiceState;
import org.thoughtcrime.securesms.events.CallParticipant;
import org.thoughtcrime.securesms.service.webrtc.state.WebRtcServiceStateBuilder;
import org.thoughtcrime.securesms.util.NetworkUtil;
import org.thoughtcrime.securesms.webrtc.locks.LockManager;
import static org.thoughtcrime.securesms.webrtc.CallNotificationBuilder.TYPE_ESTABLISHED;
@@ -68,11 +68,9 @@ public class GroupJoiningActionProcessor extends GroupActionProcessor {
webRtcInteractor.setCallInProgressNotification(TYPE_ESTABLISHED, currentState.getCallInfoState().getCallRecipient(), true);
webRtcInteractor.startAudioCommunication();
if (currentState.getLocalDeviceState().getCameraState().isEnabled()) {
webRtcInteractor.updatePhoneState(LockManager.PhoneState.IN_VIDEO);
} else {
webRtcInteractor.updatePhoneState(WebRtcUtil.getInCallPhoneState(context));
}
boolean localVideoEnabled = currentState.getLocalDeviceState().getCameraState().isEnabled();
boolean remoteVideoEnabled = currentState.getCallInfoState().getRemoteCallParticipantsMap().values().stream().anyMatch(CallParticipant::isVideoEnabled);
webRtcInteractor.updatePhoneState(WebRtcUtil.getInCallPhoneState(context, localVideoEnabled, remoteVideoEnabled));
try {
groupCall.setOutgoingVideoMuted(!currentState.getLocalDeviceState().getCameraState().isEnabled());

View File

@@ -41,6 +41,18 @@ public final class WebRtcUtil {
}
}
/**
* Returns the appropriate phone state for an in-call scenario, considering both local and remote video state.
* If either local or remote video is enabled, returns {@link LockManager.PhoneState#IN_VIDEO} to keep the screen on.
* Otherwise, falls back to audio-device based phone state.
*/
public static @NonNull LockManager.PhoneState getInCallPhoneState(@NonNull Context context, boolean localVideoEnabled, boolean remoteVideoEnabled) {
if (localVideoEnabled || remoteVideoEnabled) {
return LockManager.PhoneState.IN_VIDEO;
}
return getInCallPhoneState(context);
}
public static @NonNull CallManager.CallMediaType getCallMediaTypeFromOfferType(@NonNull OfferMessage.Type offerType) {
return offerType == OfferMessage.Type.VIDEO_CALL ? CallManager.CallMediaType.VIDEO_CALL : CallManager.CallMediaType.AUDIO_CALL;
}