Show call full UI when group call is full.

This commit is contained in:
Cody Henthorne
2020-12-07 16:17:39 -05:00
committed by GitHub
parent 13616b9820
commit c00b0727e3
14 changed files with 178 additions and 57 deletions

View File

@@ -34,7 +34,8 @@ public final class CallParticipantsState {
WebRtcLocalRenderState.GONE,
false,
false,
false);
false,
0);
private final WebRtcViewModel.State callState;
private final WebRtcViewModel.GroupCallState groupCallState;
@@ -45,6 +46,7 @@ public final class CallParticipantsState {
private final boolean isInPipMode;
private final boolean showVideoForOutgoing;
private final boolean isViewingFocusedParticipant;
private final long remoteDevicesCount;
public CallParticipantsState(@NonNull WebRtcViewModel.State callState,
@NonNull WebRtcViewModel.GroupCallState groupCallState,
@@ -54,7 +56,8 @@ public final class CallParticipantsState {
@NonNull WebRtcLocalRenderState localRenderState,
boolean isInPipMode,
boolean showVideoForOutgoing,
boolean isViewingFocusedParticipant)
boolean isViewingFocusedParticipant,
long remoteDevicesCount)
{
this.callState = callState;
this.groupCallState = groupCallState;
@@ -65,6 +68,7 @@ public final class CallParticipantsState {
this.isInPipMode = isInPipMode;
this.showVideoForOutgoing = showVideoForOutgoing;
this.isViewingFocusedParticipant = isViewingFocusedParticipant;
this.remoteDevicesCount = remoteDevicesCount;
}
public @NonNull WebRtcViewModel.State getCallState() {
@@ -154,6 +158,10 @@ public final class CallParticipantsState {
return Stream.of(getAllRemoteParticipants()).anyMatch(p -> p.getVideoSink().needsNewRequestingSize());
}
public long getRemoteDevicesCount() {
return remoteDevicesCount;
}
public static @NonNull CallParticipantsState update(@NonNull CallParticipantsState oldState,
@NonNull WebRtcViewModel webRtcViewModel,
boolean enableVideo)
@@ -186,7 +194,8 @@ public final class CallParticipantsState {
localRenderState,
oldState.isInPipMode,
newShowVideoForOutgoing,
oldState.isViewingFocusedParticipant);
oldState.isViewingFocusedParticipant,
webRtcViewModel.getRemoteDevicesCount());
}
public static @NonNull CallParticipantsState update(@NonNull CallParticipantsState oldState, boolean isInPip) {
@@ -208,7 +217,8 @@ public final class CallParticipantsState {
localRenderState,
isInPip,
oldState.showVideoForOutgoing,
oldState.isViewingFocusedParticipant);
oldState.isViewingFocusedParticipant,
oldState.remoteDevicesCount);
}
public static @NonNull CallParticipantsState update(@NonNull CallParticipantsState oldState, @NonNull SelectedPage selectedPage) {
@@ -230,7 +240,8 @@ public final class CallParticipantsState {
localRenderState,
oldState.isInPipMode,
oldState.showVideoForOutgoing,
selectedPage == SelectedPage.FOCUSED);
selectedPage == SelectedPage.FOCUSED,
oldState.remoteDevicesCount);
}
private static @NonNull WebRtcLocalRenderState determineLocalRenderMode(@NonNull CallParticipant localParticipant,

View File

@@ -96,6 +96,7 @@ public class WebRtcCallView extends FrameLayout {
private MaterialButton startCall;
private TextView participantCount;
private Stub<FrameLayout> groupCallSpeakerHint;
private Stub<View> groupCallFullStub;
private int pagerBottomMarginDp;
private boolean controlsVisible = true;
@@ -152,6 +153,7 @@ public class WebRtcCallView extends FrameLayout {
toolbar = findViewById(R.id.call_screen_toolbar);
startCall = findViewById(R.id.call_screen_start_call_start_call);
groupCallSpeakerHint = new Stub<>(findViewById(R.id.call_screen_group_call_speaker_hint));
groupCallFullStub = new Stub<>(findViewById(R.id.group_call_call_full_view));
View topGradient = findViewById(R.id.call_screen_header_gradient);
View decline = findViewById(R.id.call_screen_decline_call);
@@ -269,7 +271,7 @@ public class WebRtcCallView extends FrameLayout {
if (state.getGroupCallState().isNotIdle() && participantCount != null) {
boolean includeSelf = state.getGroupCallState() == WebRtcViewModel.GroupCallState.CONNECTED_AND_JOINED;
participantCount.setText(String.valueOf(state.getAllRemoteParticipants().size() + (includeSelf ? 1 : 0)));
participantCount.setText(String.valueOf(state.getRemoteDevicesCount() + (includeSelf ? 1 : 0)));
}
pagerAdapter.submitList(pages);
@@ -421,7 +423,14 @@ public class WebRtcCallView extends FrameLayout {
visibleViewSet.add(startCallControls);
startCall.setText(webRtcControls.getStartCallButtonText());
startCall.setEnabled(true);
startCall.setEnabled(webRtcControls.isStartCallEnabled());
}
if (webRtcControls.displayGroupCallFull()) {
groupCallFullStub.get().setVisibility(View.VISIBLE);
((TextView) groupCallFullStub.get().findViewById(R.id.group_call_call_full_message)).setText(webRtcControls.getGroupCallFullMessage(getContext()));
} else if (groupCallFullStub.resolved()) {
groupCallFullStub.get().setVisibility(View.GONE);
}
MenuItem item = toolbar.getMenu().findItem(R.id.menu_group_call_participants_list);

View File

@@ -5,6 +5,7 @@ import android.os.Looper;
import androidx.annotation.MainThread;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.Transformations;
@@ -163,7 +164,9 @@ public class WebRtcCallViewModel extends ViewModel {
localParticipant.isMoreThanOneCameraAvailable(),
webRtcViewModel.isBluetoothAvailable(),
Util.hasItems(webRtcViewModel.getRemoteParticipants()),
repository.getAudioOutput());
repository.getAudioOutput(),
webRtcViewModel.getRemoteDevicesCount(),
webRtcViewModel.getParticipantLimit());
if (webRtcViewModel.getState() == WebRtcViewModel.State.CALL_CONNECTED && callConnectedTime == -1) {
callConnectedTime = webRtcViewModel.getCallConnectedTime();
@@ -206,7 +209,9 @@ public class WebRtcCallViewModel extends ViewModel {
boolean isMoreThanOneCameraAvailable,
boolean isBluetoothAvailable,
boolean hasAtLeastOneRemote,
@NonNull WebRtcAudioOutput audioOutput)
@NonNull WebRtcAudioOutput audioOutput,
long remoteDevicesCount,
@Nullable Long participantLimit)
{
final WebRtcControls.CallState callState;
@@ -242,7 +247,8 @@ public class WebRtcCallViewModel extends ViewModel {
break;
case CONNECTING:
case RECONNECTING:
groupCallState = WebRtcControls.GroupCallState.CONNECTING;
groupCallState = (participantLimit == null || remoteDevicesCount < participantLimit) ? WebRtcControls.GroupCallState.CONNECTING
: WebRtcControls.GroupCallState.FULL;
break;
case CONNECTED:
case CONNECTED_AND_JOINING:
@@ -262,7 +268,8 @@ public class WebRtcCallViewModel extends ViewModel {
hasAtLeastOneRemote,
callState,
groupCallState,
audioOutput));
audioOutput,
participantLimit));
}
private @NonNull WebRtcControls getRealWebRtcControls(boolean isInPipMode, @NonNull WebRtcControls controls) {

View File

@@ -1,6 +1,9 @@
package org.thoughtcrime.securesms.components.webrtc;
import android.content.Context;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import org.thoughtcrime.securesms.R;
@@ -8,7 +11,7 @@ import org.thoughtcrime.securesms.R;
public final class WebRtcControls {
public static final WebRtcControls NONE = new WebRtcControls();
public static final WebRtcControls PIP = new WebRtcControls(false, false, false, false, true, false, CallState.NONE, GroupCallState.NONE, WebRtcAudioOutput.HANDSET);
public static final WebRtcControls PIP = new WebRtcControls(false, false, false, false, true, false, CallState.NONE, GroupCallState.NONE, WebRtcAudioOutput.HANDSET, null);
private final boolean isRemoteVideoEnabled;
private final boolean isLocalVideoEnabled;
@@ -19,9 +22,10 @@ public final class WebRtcControls {
private final CallState callState;
private final GroupCallState groupCallState;
private final WebRtcAudioOutput audioOutput;
private final Long participantLimit;
private WebRtcControls() {
this(false, false, false, false, false, false, CallState.NONE, GroupCallState.NONE, WebRtcAudioOutput.HANDSET);
this(false, false, false, false, false, false, CallState.NONE, GroupCallState.NONE, WebRtcAudioOutput.HANDSET, null);
}
WebRtcControls(boolean isLocalVideoEnabled,
@@ -32,7 +36,8 @@ public final class WebRtcControls {
boolean hasAtLeastOneRemote,
@NonNull CallState callState,
@NonNull GroupCallState groupCallState,
@NonNull WebRtcAudioOutput audioOutput)
@NonNull WebRtcAudioOutput audioOutput,
@Nullable Long participantLimit)
{
this.isLocalVideoEnabled = isLocalVideoEnabled;
this.isRemoteVideoEnabled = isRemoteVideoEnabled;
@@ -43,6 +48,7 @@ public final class WebRtcControls {
this.callState = callState;
this.groupCallState = groupCallState;
this.audioOutput = audioOutput;
this.participantLimit = participantLimit;
}
boolean displayStartCallControls() {
@@ -50,12 +56,31 @@ public final class WebRtcControls {
}
@StringRes int getStartCallButtonText() {
if (isGroupCall() && hasAtLeastOneRemote) {
return R.string.WebRtcCallView__join_call;
if (isGroupCall()) {
if (groupCallState == GroupCallState.FULL) {
return R.string.WebRtcCallView__call_is_full;
} else if (hasAtLeastOneRemote) {
return R.string.WebRtcCallView__join_call;
}
}
return R.string.WebRtcCallView__start_call;
}
boolean isStartCallEnabled() {
return groupCallState != GroupCallState.FULL;
}
boolean displayGroupCallFull() {
return groupCallState == GroupCallState.FULL;
}
@NonNull String getGroupCallFullMessage(@NonNull Context context) {
if (participantLimit != null) {
return context.getString(R.string.WebRtcCallView__the_maximum_number_of_d_participants_has_been_Reached_for_this_call, participantLimit);
}
return "";
}
boolean displayGroupMembersButton() {
return groupCallState.isAtLeast(GroupCallState.CONNECTING);
}
@@ -158,6 +183,7 @@ public final class WebRtcControls {
DISCONNECTED,
RECONNECTING,
CONNECTING,
FULL,
CONNECTED;
boolean isAtLeast(@SuppressWarnings("SameParameterValue") @NonNull GroupCallState other) {

View File

@@ -90,7 +90,7 @@ public class CallParticipantsListDialog extends BottomSheetDialogFragment {
boolean includeSelf = callParticipantsState.getGroupCallState() == WebRtcViewModel.GroupCallState.CONNECTED_AND_JOINED;
items.add(new CallParticipantsListHeader(callParticipantsState.getAllRemoteParticipants().size() + (includeSelf ? 1 : 0)));
items.add(new CallParticipantsListHeader((int) callParticipantsState.getRemoteDevicesCount() + (includeSelf ? 1 : 0)));
if (includeSelf) {
items.add(new CallParticipantViewState(callParticipantsState.getLocalParticipant()));