mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-23 02:10:44 +01:00
Add foundational UX and state support for Group Calling.
This commit is contained in:
committed by
Greyson Parrelli
parent
7baf8052a2
commit
dc4faf57cb
@@ -0,0 +1,117 @@
|
||||
package org.thoughtcrime.securesms.events;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import org.thoughtcrime.securesms.components.webrtc.BroadcastVideoSink;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.ringrtc.CameraState;
|
||||
import org.whispersystems.libsignal.IdentityKey;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class CallParticipant {
|
||||
|
||||
private final @NonNull CameraState cameraState;
|
||||
private final @NonNull Recipient recipient;
|
||||
private final @Nullable IdentityKey identityKey;
|
||||
private final @NonNull BroadcastVideoSink videoSink;
|
||||
private final boolean videoEnabled;
|
||||
private final boolean microphoneEnabled;
|
||||
|
||||
public static @NonNull CallParticipant createLocal(@NonNull CameraState cameraState,
|
||||
@NonNull BroadcastVideoSink renderer,
|
||||
boolean microphoneEnabled)
|
||||
{
|
||||
return new CallParticipant(Recipient.self(),
|
||||
null,
|
||||
renderer,
|
||||
cameraState,
|
||||
cameraState.isEnabled() && cameraState.getCameraCount() > 0,
|
||||
microphoneEnabled);
|
||||
}
|
||||
|
||||
public static @NonNull CallParticipant createRemote(@NonNull Recipient recipient,
|
||||
@Nullable IdentityKey identityKey,
|
||||
@NonNull BroadcastVideoSink renderer,
|
||||
boolean videoEnabled)
|
||||
{
|
||||
return new CallParticipant(recipient, identityKey, renderer, CameraState.UNKNOWN, videoEnabled, true);
|
||||
}
|
||||
|
||||
private CallParticipant(@NonNull Recipient recipient,
|
||||
@Nullable IdentityKey identityKey,
|
||||
@NonNull BroadcastVideoSink videoSink,
|
||||
@NonNull CameraState cameraState,
|
||||
boolean videoEnabled,
|
||||
boolean microphoneEnabled)
|
||||
{
|
||||
this.recipient = recipient;
|
||||
this.identityKey = identityKey;
|
||||
this.videoSink = videoSink;
|
||||
this.cameraState = cameraState;
|
||||
this.videoEnabled = videoEnabled;
|
||||
this.microphoneEnabled = microphoneEnabled;
|
||||
}
|
||||
|
||||
public @NonNull CallParticipant withIdentityKey(@NonNull IdentityKey identityKey) {
|
||||
return new CallParticipant(recipient, identityKey, videoSink, cameraState, videoEnabled, microphoneEnabled);
|
||||
}
|
||||
|
||||
public @NonNull CallParticipant withVideoEnabled(boolean videoEnabled) {
|
||||
return new CallParticipant(recipient, identityKey, videoSink, cameraState, videoEnabled, microphoneEnabled);
|
||||
}
|
||||
|
||||
public @NonNull Recipient getRecipient() {
|
||||
return recipient;
|
||||
}
|
||||
|
||||
public @Nullable IdentityKey getIdentityKey() {
|
||||
return identityKey;
|
||||
}
|
||||
|
||||
public @NonNull BroadcastVideoSink getVideoSink() {
|
||||
return videoSink;
|
||||
}
|
||||
|
||||
public @NonNull CameraState getCameraState() {
|
||||
return cameraState;
|
||||
}
|
||||
|
||||
public boolean isVideoEnabled() {
|
||||
return videoEnabled;
|
||||
}
|
||||
|
||||
public boolean isMicrophoneEnabled() {
|
||||
return microphoneEnabled;
|
||||
}
|
||||
|
||||
public @NonNull CameraState.Direction getCameraDirection() {
|
||||
if (cameraState.getActiveDirection() == CameraState.Direction.BACK) {
|
||||
return cameraState.getActiveDirection();
|
||||
}
|
||||
return CameraState.Direction.FRONT;
|
||||
}
|
||||
|
||||
public boolean isMoreThanOneCameraAvailable() {
|
||||
return cameraState.getCameraCount() > 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
CallParticipant that = (CallParticipant) o;
|
||||
return videoEnabled == that.videoEnabled &&
|
||||
microphoneEnabled == that.microphoneEnabled &&
|
||||
cameraState.equals(that.cameraState) &&
|
||||
recipient.equals(that.recipient) &&
|
||||
Objects.equals(identityKey, that.identityKey) &&
|
||||
Objects.equals(videoSink, that.videoSink);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(cameraState, recipient, identityKey, videoSink, videoEnabled, microphoneEnabled);
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,14 @@
|
||||
package org.thoughtcrime.securesms.events;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import org.thoughtcrime.securesms.components.webrtc.TextureViewRenderer;
|
||||
import com.annimon.stream.Stream;
|
||||
|
||||
import org.thoughtcrime.securesms.components.webrtc.BroadcastVideoSink;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.ringrtc.CameraState;
|
||||
import org.webrtc.SurfaceViewRenderer;
|
||||
import org.whispersystems.libsignal.IdentityKey;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class WebRtcViewModel {
|
||||
|
||||
@@ -33,70 +34,34 @@ public class WebRtcViewModel {
|
||||
CALL_ONGOING_ELSEWHERE
|
||||
}
|
||||
|
||||
|
||||
private final @NonNull State state;
|
||||
private final @NonNull Recipient recipient;
|
||||
private final @Nullable IdentityKey identityKey;
|
||||
|
||||
private final boolean remoteVideoEnabled;
|
||||
private final @NonNull State state;
|
||||
private final @NonNull Recipient recipient;
|
||||
|
||||
private final boolean isBluetoothAvailable;
|
||||
private final boolean isMicrophoneEnabled;
|
||||
private final boolean isRemoteVideoOffer;
|
||||
private final long callConnectedTime;
|
||||
|
||||
private final CameraState localCameraState;
|
||||
private final TextureViewRenderer localRenderer;
|
||||
private final TextureViewRenderer remoteRenderer;
|
||||
private final CallParticipant localParticipant;
|
||||
private final List<CallParticipant> remoteParticipants;
|
||||
|
||||
private final long callConnectedTime;
|
||||
|
||||
public WebRtcViewModel(@NonNull State state,
|
||||
@NonNull Recipient recipient,
|
||||
@NonNull CameraState localCameraState,
|
||||
@NonNull TextureViewRenderer localRenderer,
|
||||
@NonNull TextureViewRenderer remoteRenderer,
|
||||
boolean remoteVideoEnabled,
|
||||
boolean isBluetoothAvailable,
|
||||
boolean isMicrophoneEnabled,
|
||||
boolean isRemoteVideoOffer,
|
||||
long callConnectedTime)
|
||||
{
|
||||
this(state,
|
||||
recipient,
|
||||
null,
|
||||
localCameraState,
|
||||
localRenderer,
|
||||
remoteRenderer,
|
||||
remoteVideoEnabled,
|
||||
isBluetoothAvailable,
|
||||
isMicrophoneEnabled,
|
||||
isRemoteVideoOffer,
|
||||
callConnectedTime);
|
||||
}
|
||||
|
||||
public WebRtcViewModel(@NonNull State state,
|
||||
@NonNull Recipient recipient,
|
||||
@Nullable IdentityKey identityKey,
|
||||
@NonNull CameraState localCameraState,
|
||||
@NonNull TextureViewRenderer localRenderer,
|
||||
@NonNull TextureViewRenderer remoteRenderer,
|
||||
boolean remoteVideoEnabled,
|
||||
boolean isBluetoothAvailable,
|
||||
boolean isMicrophoneEnabled,
|
||||
boolean isRemoteVideoOffer,
|
||||
long callConnectedTime)
|
||||
public WebRtcViewModel(@NonNull State state,
|
||||
@NonNull Recipient recipient,
|
||||
@NonNull CameraState localCameraState,
|
||||
@NonNull BroadcastVideoSink localSink,
|
||||
boolean isBluetoothAvailable,
|
||||
boolean isMicrophoneEnabled,
|
||||
boolean isRemoteVideoOffer,
|
||||
long callConnectedTime,
|
||||
@NonNull List<CallParticipant> remoteParticipants)
|
||||
{
|
||||
this.state = state;
|
||||
this.recipient = recipient;
|
||||
this.localCameraState = localCameraState;
|
||||
this.localRenderer = localRenderer;
|
||||
this.remoteRenderer = remoteRenderer;
|
||||
this.identityKey = identityKey;
|
||||
this.remoteVideoEnabled = remoteVideoEnabled;
|
||||
this.isBluetoothAvailable = isBluetoothAvailable;
|
||||
this.isMicrophoneEnabled = isMicrophoneEnabled;
|
||||
this.isRemoteVideoOffer = isRemoteVideoOffer;
|
||||
this.callConnectedTime = callConnectedTime;
|
||||
this.remoteParticipants = remoteParticipants;
|
||||
|
||||
localParticipant = CallParticipant.createLocal(localCameraState, localSink, isMicrophoneEnabled);
|
||||
}
|
||||
|
||||
public @NonNull State getState() {
|
||||
@@ -107,50 +72,28 @@ public class WebRtcViewModel {
|
||||
return recipient;
|
||||
}
|
||||
|
||||
public @NonNull CameraState getLocalCameraState() {
|
||||
return localCameraState;
|
||||
}
|
||||
|
||||
public @Nullable IdentityKey getIdentityKey() {
|
||||
return identityKey;
|
||||
}
|
||||
|
||||
public boolean isRemoteVideoEnabled() {
|
||||
return remoteVideoEnabled;
|
||||
return Stream.of(remoteParticipants).anyMatch(CallParticipant::isVideoEnabled);
|
||||
}
|
||||
|
||||
public boolean isBluetoothAvailable() {
|
||||
return isBluetoothAvailable;
|
||||
}
|
||||
|
||||
public boolean isMicrophoneEnabled() {
|
||||
return isMicrophoneEnabled;
|
||||
}
|
||||
|
||||
public boolean isRemoteVideoOffer() {
|
||||
return isRemoteVideoOffer;
|
||||
}
|
||||
|
||||
public TextureViewRenderer getLocalRenderer() {
|
||||
return localRenderer;
|
||||
}
|
||||
|
||||
public TextureViewRenderer getRemoteRenderer() {
|
||||
return remoteRenderer;
|
||||
}
|
||||
|
||||
public long getCallConnectedTime() {
|
||||
return callConnectedTime;
|
||||
}
|
||||
|
||||
public @NonNull String toString() {
|
||||
return "[State: " + state +
|
||||
", recipient: " + recipient.getId().serialize() +
|
||||
", identity: " + identityKey +
|
||||
", remoteVideo: " + remoteVideoEnabled +
|
||||
", localVideo: " + localCameraState.isEnabled() +
|
||||
", isRemoteVideoOffer: " + isRemoteVideoOffer +
|
||||
", callConnectedTime: " + callConnectedTime +
|
||||
"]";
|
||||
public @NonNull CallParticipant getLocalParticipant() {
|
||||
return localParticipant;
|
||||
}
|
||||
|
||||
public @NonNull List<CallParticipant> getRemoteParticipants() {
|
||||
return remoteParticipants;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user