Transition full screen call UX to terminal state when call handled by linked device.

This commit is contained in:
Cody Henthorne
2024-04-04 11:53:29 -04:00
committed by Greyson Parrelli
parent 16588c401e
commit dd28523b05
8 changed files with 27 additions and 17 deletions

View File

@@ -34,7 +34,7 @@ public class CallParticipantsLayout extends FlexboxLayout {
private CallParticipant focusedParticipant = null; private CallParticipant focusedParticipant = null;
private boolean shouldRenderInPip; private boolean shouldRenderInPip;
private boolean isPortrait; private boolean isPortrait;
private boolean isIncomingRing; private boolean hideAvatar;
private int navBarBottomInset; private int navBarBottomInset;
private LayoutStrategy layoutStrategy; private LayoutStrategy layoutStrategy;
@@ -54,7 +54,7 @@ public class CallParticipantsLayout extends FlexboxLayout {
@NonNull CallParticipant focusedParticipant, @NonNull CallParticipant focusedParticipant,
boolean shouldRenderInPip, boolean shouldRenderInPip,
boolean isPortrait, boolean isPortrait,
boolean isIncomingRing, boolean hideAvatar,
int navBarBottomInset, int navBarBottomInset,
@NonNull LayoutStrategy layoutStrategy) @NonNull LayoutStrategy layoutStrategy)
{ {
@@ -62,7 +62,7 @@ public class CallParticipantsLayout extends FlexboxLayout {
this.focusedParticipant = focusedParticipant; this.focusedParticipant = focusedParticipant;
this.shouldRenderInPip = shouldRenderInPip; this.shouldRenderInPip = shouldRenderInPip;
this.isPortrait = isPortrait; this.isPortrait = isPortrait;
this.isIncomingRing = isIncomingRing; this.hideAvatar = hideAvatar;
this.navBarBottomInset = navBarBottomInset; this.navBarBottomInset = navBarBottomInset;
this.layoutStrategy = layoutStrategy; this.layoutStrategy = layoutStrategy;
@@ -134,7 +134,7 @@ public class CallParticipantsLayout extends FlexboxLayout {
callParticipantView.setBottomInset(navBarBottomInset); callParticipantView.setBottomInset(navBarBottomInset);
} }
if (isIncomingRing) { if (hideAvatar) {
callParticipantView.hideAvatar(); callParticipantView.hideAvatar();
} else { } else {
callParticipantView.showAvatar(); callParticipantView.showAvatar();

View File

@@ -49,7 +49,7 @@ data class CallParticipantsState(
val allRemoteParticipants: List<CallParticipant> = remoteParticipants.allParticipants val allRemoteParticipants: List<CallParticipant> = remoteParticipants.allParticipants
val isFolded: Boolean = foldableState.isFolded val isFolded: Boolean = foldableState.isFolded
val isLargeVideoGroup: Boolean = allRemoteParticipants.size > SMALL_GROUP_MAX && !isInPipMode && !isFolded val isLargeVideoGroup: Boolean = allRemoteParticipants.size > SMALL_GROUP_MAX && !isInPipMode && !isFolded
val isIncomingRing: Boolean = callState == WebRtcViewModel.State.CALL_INCOMING val hideAvatar: Boolean = callState.isIncomingOrHandledElsewhere
val raisedHands: List<GroupCallRaiseHandEvent> val raisedHands: List<GroupCallRaiseHandEvent>
get() { get() {

View File

@@ -16,7 +16,7 @@ class WebRtcCallParticipantsPage {
private final boolean isRenderInPip; private final boolean isRenderInPip;
private final boolean isPortrait; private final boolean isPortrait;
private final boolean isLandscapeEnabled; private final boolean isLandscapeEnabled;
private final boolean isIncomingRing; private final boolean hideAvatar;
private final int navBarBottomInset; private final int navBarBottomInset;
static WebRtcCallParticipantsPage forMultipleParticipants(@NonNull List<CallParticipant> callParticipants, static WebRtcCallParticipantsPage forMultipleParticipants(@NonNull List<CallParticipant> callParticipants,
@@ -24,10 +24,10 @@ class WebRtcCallParticipantsPage {
boolean isRenderInPip, boolean isRenderInPip,
boolean isPortrait, boolean isPortrait,
boolean isLandscapeEnabled, boolean isLandscapeEnabled,
boolean isIncomingRing, boolean hideAvatar,
int navBarBottomInset) int navBarBottomInset)
{ {
return new WebRtcCallParticipantsPage(callParticipants, focusedParticipant, false, isRenderInPip, isPortrait, isLandscapeEnabled, isIncomingRing, navBarBottomInset); return new WebRtcCallParticipantsPage(callParticipants, focusedParticipant, false, isRenderInPip, isPortrait, isLandscapeEnabled, hideAvatar, navBarBottomInset);
} }
static WebRtcCallParticipantsPage forSingleParticipant(@NonNull CallParticipant singleParticipant, static WebRtcCallParticipantsPage forSingleParticipant(@NonNull CallParticipant singleParticipant,
@@ -44,7 +44,7 @@ class WebRtcCallParticipantsPage {
boolean isRenderInPip, boolean isRenderInPip,
boolean isPortrait, boolean isPortrait,
boolean isLandscapeEnabled, boolean isLandscapeEnabled,
boolean isIncomingRing, boolean hideAvatar,
int navBarBottomInset) int navBarBottomInset)
{ {
this.callParticipants = callParticipants; this.callParticipants = callParticipants;
@@ -53,7 +53,7 @@ class WebRtcCallParticipantsPage {
this.isRenderInPip = isRenderInPip; this.isRenderInPip = isRenderInPip;
this.isPortrait = isPortrait; this.isPortrait = isPortrait;
this.isLandscapeEnabled = isLandscapeEnabled; this.isLandscapeEnabled = isLandscapeEnabled;
this.isIncomingRing = isIncomingRing; this.hideAvatar = hideAvatar;
this.navBarBottomInset = navBarBottomInset; this.navBarBottomInset = navBarBottomInset;
} }
@@ -77,8 +77,8 @@ class WebRtcCallParticipantsPage {
return isPortrait; return isPortrait;
} }
public boolean isIncomingRing() { public boolean shouldHideAvatar() {
return isIncomingRing; return hideAvatar;
} }
public int getNavBarBottomInset() { public int getNavBarBottomInset() {
@@ -98,7 +98,7 @@ class WebRtcCallParticipantsPage {
isRenderInPip == that.isRenderInPip && isRenderInPip == that.isRenderInPip &&
isPortrait == that.isPortrait && isPortrait == that.isPortrait &&
isLandscapeEnabled == that.isLandscapeEnabled && isLandscapeEnabled == that.isLandscapeEnabled &&
isIncomingRing == that.isIncomingRing && hideAvatar == that.hideAvatar &&
callParticipants.equals(that.callParticipants) && callParticipants.equals(that.callParticipants) &&
focusedParticipant.equals(that.focusedParticipant) && focusedParticipant.equals(that.focusedParticipant) &&
navBarBottomInset == that.navBarBottomInset; navBarBottomInset == that.navBarBottomInset;
@@ -106,6 +106,6 @@ class WebRtcCallParticipantsPage {
@Override @Override
public int hashCode() { public int hashCode() {
return Objects.hash(callParticipants, focusedParticipant, isSpeaker, isRenderInPip, isPortrait, isLandscapeEnabled, isIncomingRing, navBarBottomInset); return Objects.hash(callParticipants, focusedParticipant, isSpeaker, isRenderInPip, isPortrait, isLandscapeEnabled, hideAvatar, navBarBottomInset);
} }
} }

View File

@@ -86,7 +86,7 @@ class WebRtcCallParticipantsPagerAdapter extends ListAdapter<WebRtcCallParticipa
@Override @Override
void bind(WebRtcCallParticipantsPage page) { void bind(WebRtcCallParticipantsPage page) {
callParticipantsLayout.update(page.getCallParticipants(), page.getFocusedParticipant(), page.isRenderInPip(), page.isPortrait(), page.isIncomingRing(), page.getNavBarBottomInset(), page.getLayoutStrategy()); callParticipantsLayout.update(page.getCallParticipants(), page.getFocusedParticipant(), page.isRenderInPip(), page.isPortrait(), page.shouldHideAvatar(), page.getNavBarBottomInset(), page.getLayoutStrategy());
} }
} }

View File

@@ -429,7 +429,7 @@ public class WebRtcCallView extends InsetAwareConstraintLayout {
List<WebRtcCallParticipantsPage> pages = new ArrayList<>(2); List<WebRtcCallParticipantsPage> pages = new ArrayList<>(2);
if (!state.getGridParticipants().isEmpty()) { if (!state.getGridParticipants().isEmpty()) {
pages.add(WebRtcCallParticipantsPage.forMultipleParticipants(state.getGridParticipants(), state.getFocusedParticipant(), state.isInPipMode(), isPortrait, isLandscapeEnabled, state.isIncomingRing(), navBarBottomInset)); pages.add(WebRtcCallParticipantsPage.forMultipleParticipants(state.getGridParticipants(), state.getFocusedParticipant(), state.isInPipMode(), isPortrait, isLandscapeEnabled, state.getHideAvatar(), navBarBottomInset));
} }
if (state.getFocusedParticipant() != CallParticipant.EMPTY && state.getAllRemoteParticipants().size() > 1) { if (state.getFocusedParticipant() != CallParticipant.EMPTY && state.getAllRemoteParticipants().size() > 1) {

View File

@@ -416,6 +416,8 @@ public class WebRtcCallViewModel extends ViewModel {
case CALL_ACCEPTED_ELSEWHERE: case CALL_ACCEPTED_ELSEWHERE:
case CALL_DECLINED_ELSEWHERE: case CALL_DECLINED_ELSEWHERE:
case CALL_ONGOING_ELSEWHERE: case CALL_ONGOING_ELSEWHERE:
callState = WebRtcControls.CallState.HANDLED_ELSEWHERE;
break;
case CALL_NEEDS_PERMISSION: case CALL_NEEDS_PERMISSION:
case CALL_BUSY: case CALL_BUSY:
case CALL_DISCONNECTED: case CALL_DISCONNECTED:

View File

@@ -105,7 +105,7 @@ public final class WebRtcControls {
* This is only true at the very start of a call and will then never be true again * This is only true at the very start of a call and will then never be true again
*/ */
public boolean hideControlsSheetInitially() { public boolean hideControlsSheetInitially() {
return displayIncomingCallButtons() || callState == CallState.NONE; return displayIncomingCallButtons() || callState == CallState.NONE || isHandledElsewhere();
} }
public boolean displayErrorControls() { public boolean displayErrorControls() {
@@ -263,6 +263,10 @@ public final class WebRtcControls {
return callState == CallState.INCOMING; return callState == CallState.INCOMING;
} }
private boolean isHandledElsewhere() {
return callState == CallState.HANDLED_ELSEWHERE;
}
private boolean isAtLeastOutgoing() { private boolean isAtLeastOutgoing() {
return callState.isAtLeast(CallState.OUTGOING); return callState.isAtLeast(CallState.OUTGOING);
} }
@@ -284,6 +288,7 @@ public final class WebRtcControls {
public enum CallState { public enum CallState {
NONE, NONE,
ERROR, ERROR,
HANDLED_ELSEWHERE,
PRE_JOIN, PRE_JOIN,
RECONNECTING, RECONNECTING,
INCOMING, INCOMING,

View File

@@ -51,6 +51,9 @@ class WebRtcViewModel(state: WebRtcServiceState) {
val inOngoingCall: Boolean val inOngoingCall: Boolean
get() = this == CALL_INCOMING || this == CALL_OUTGOING || this == CALL_CONNECTED || this == CALL_RINGING || this == CALL_RECONNECTING get() = this == CALL_INCOMING || this == CALL_OUTGOING || this == CALL_CONNECTED || this == CALL_RINGING || this == CALL_RECONNECTING
val isIncomingOrHandledElsewhere
get() = this == CALL_INCOMING || this == CALL_ACCEPTED_ELSEWHERE || this == CALL_DECLINED_ELSEWHERE || this == CALL_ONGOING_ELSEWHERE
} }
enum class GroupCallState { enum class GroupCallState {