mirror of
https://github.com/nextcloud/talk-android.git
synced 2024-11-23 21:45:42 +03:00
Merge pull request #2390 from nextcloud/provide-visual-feeback-when-a-participant-is-not-connected
Provide visual feeback when a participant is not connected
This commit is contained in:
commit
e47de0afc9
8 changed files with 98 additions and 11 deletions
|
@ -1843,6 +1843,14 @@ public class CallActivity extends CallBaseActivity {
|
||||||
for (String sessionId : newSessions) {
|
for (String sessionId : newSessions) {
|
||||||
Log.d(TAG, " newSession joined: " + sessionId);
|
Log.d(TAG, " newSession joined: " + sessionId);
|
||||||
getOrCreatePeerConnectionWrapperForSessionIdAndType(sessionId, VIDEO_STREAM_TYPE_VIDEO, false);
|
getOrCreatePeerConnectionWrapperForSessionIdAndType(sessionId, VIDEO_STREAM_TYPE_VIDEO, false);
|
||||||
|
|
||||||
|
runOnUiThread(() -> {
|
||||||
|
setupVideoStreamForLayout(
|
||||||
|
null,
|
||||||
|
sessionId,
|
||||||
|
false,
|
||||||
|
VIDEO_STREAM_TYPE_VIDEO);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newSessions.size() > 0 && !currentCallStatus.equals(CallStatus.IN_CONVERSATION)) {
|
if (newSessions.size() > 0 && !currentCallStatus.equals(CallStatus.IN_CONVERSATION)) {
|
||||||
|
@ -2019,6 +2027,17 @@ public class CallActivity extends CallBaseActivity {
|
||||||
updateSelfVideoViewPosition();
|
updateSelfVideoViewPosition();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateSelfVideoViewConnected(boolean connected) {
|
||||||
|
// FIXME In voice only calls there is no video view, so the progress bar would appear floating in the middle of
|
||||||
|
// nowhere. However, a way to signal that the local participant is not connected to the HPB is still need in
|
||||||
|
// that case.
|
||||||
|
if (!connected && !isVoiceOnlyCall) {
|
||||||
|
binding.selfVideoViewProgressBar.setVisibility(View.VISIBLE);
|
||||||
|
} else {
|
||||||
|
binding.selfVideoViewProgressBar.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void updateSelfVideoViewPosition() {
|
private void updateSelfVideoViewPosition() {
|
||||||
Log.d(TAG, "updateSelfVideoViewPosition");
|
Log.d(TAG, "updateSelfVideoViewPosition");
|
||||||
if (!isInPipMode) {
|
if (!isInPipMode) {
|
||||||
|
@ -2061,6 +2080,22 @@ public class CallActivity extends CallBaseActivity {
|
||||||
String sessionId = peerConnectionEvent.getSessionId();
|
String sessionId = peerConnectionEvent.getSessionId();
|
||||||
|
|
||||||
if (peerConnectionEvent.getPeerConnectionEventType() ==
|
if (peerConnectionEvent.getPeerConnectionEventType() ==
|
||||||
|
PeerConnectionEvent.PeerConnectionEventType.PEER_CONNECTED) {
|
||||||
|
if (webSocketClient != null && webSocketClient.getSessionId() == sessionId) {
|
||||||
|
updateSelfVideoViewConnected(true);
|
||||||
|
} else if (participantDisplayItems.get(sessionId) != null) {
|
||||||
|
participantDisplayItems.get(sessionId).setConnected(true);
|
||||||
|
participantsAdapter.notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
} else if (peerConnectionEvent.getPeerConnectionEventType() ==
|
||||||
|
PeerConnectionEvent.PeerConnectionEventType.PEER_DISCONNECTED) {
|
||||||
|
if (webSocketClient != null && webSocketClient.getSessionId() == sessionId) {
|
||||||
|
updateSelfVideoViewConnected(false);
|
||||||
|
} else if (participantDisplayItems.get(sessionId) != null) {
|
||||||
|
participantDisplayItems.get(sessionId).setConnected(false);
|
||||||
|
participantsAdapter.notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
} else if (peerConnectionEvent.getPeerConnectionEventType() ==
|
||||||
PeerConnectionEvent.PeerConnectionEventType.PEER_CLOSED) {
|
PeerConnectionEvent.PeerConnectionEventType.PEER_CLOSED) {
|
||||||
endPeerConnection(sessionId, VIDEO_STREAM_TYPE_SCREEN.equals(peerConnectionEvent.getVideoStreamType()));
|
endPeerConnection(sessionId, VIDEO_STREAM_TYPE_SCREEN.equals(peerConnectionEvent.getVideoStreamType()));
|
||||||
} else if (peerConnectionEvent.getPeerConnectionEventType() ==
|
} else if (peerConnectionEvent.getPeerConnectionEventType() ==
|
||||||
|
@ -2081,23 +2116,20 @@ public class CallActivity extends CallBaseActivity {
|
||||||
PeerConnectionEvent.PeerConnectionEventType.NICK_CHANGE) {
|
PeerConnectionEvent.PeerConnectionEventType.NICK_CHANGE) {
|
||||||
if (participantDisplayItems.get(sessionId) != null) {
|
if (participantDisplayItems.get(sessionId) != null) {
|
||||||
participantDisplayItems.get(sessionId).setNick(peerConnectionEvent.getNick());
|
participantDisplayItems.get(sessionId).setNick(peerConnectionEvent.getNick());
|
||||||
}
|
|
||||||
participantsAdapter.notifyDataSetChanged();
|
participantsAdapter.notifyDataSetChanged();
|
||||||
|
}
|
||||||
} else if (peerConnectionEvent.getPeerConnectionEventType() ==
|
} else if (peerConnectionEvent.getPeerConnectionEventType() ==
|
||||||
PeerConnectionEvent.PeerConnectionEventType.VIDEO_CHANGE && !isVoiceOnlyCall) {
|
PeerConnectionEvent.PeerConnectionEventType.VIDEO_CHANGE && !isVoiceOnlyCall) {
|
||||||
if (participantDisplayItems.get(sessionId) != null) {
|
if (participantDisplayItems.get(sessionId) != null) {
|
||||||
participantDisplayItems.get(sessionId).setStreamEnabled(peerConnectionEvent.getChangeValue());
|
participantDisplayItems.get(sessionId).setStreamEnabled(peerConnectionEvent.getChangeValue());
|
||||||
}
|
|
||||||
participantsAdapter.notifyDataSetChanged();
|
participantsAdapter.notifyDataSetChanged();
|
||||||
|
}
|
||||||
} else if (peerConnectionEvent.getPeerConnectionEventType() ==
|
} else if (peerConnectionEvent.getPeerConnectionEventType() ==
|
||||||
PeerConnectionEvent.PeerConnectionEventType.AUDIO_CHANGE) {
|
PeerConnectionEvent.PeerConnectionEventType.AUDIO_CHANGE) {
|
||||||
if (participantDisplayItems.get(sessionId) != null) {
|
if (participantDisplayItems.get(sessionId) != null) {
|
||||||
participantDisplayItems.get(sessionId).setAudioEnabled(peerConnectionEvent.getChangeValue());
|
participantDisplayItems.get(sessionId).setAudioEnabled(peerConnectionEvent.getChangeValue());
|
||||||
}
|
|
||||||
participantsAdapter.notifyDataSetChanged();
|
participantsAdapter.notifyDataSetChanged();
|
||||||
|
}
|
||||||
} else if (peerConnectionEvent.getPeerConnectionEventType() ==
|
} else if (peerConnectionEvent.getPeerConnectionEventType() ==
|
||||||
PeerConnectionEvent.PeerConnectionEventType.PUBLISHER_FAILED) {
|
PeerConnectionEvent.PeerConnectionEventType.PUBLISHER_FAILED) {
|
||||||
currentCallStatus = CallStatus.PUBLISHER_FAILED;
|
currentCallStatus = CallStatus.PUBLISHER_FAILED;
|
||||||
|
@ -2253,12 +2285,20 @@ public class CallActivity extends CallBaseActivity {
|
||||||
String session,
|
String session,
|
||||||
boolean videoStreamEnabled,
|
boolean videoStreamEnabled,
|
||||||
String videoStreamType) {
|
String videoStreamType) {
|
||||||
|
PeerConnectionWrapper peerConnectionWrapper = getPeerConnectionWrapperForSessionIdAndType(session,
|
||||||
|
videoStreamType);
|
||||||
|
|
||||||
|
boolean connected = false;
|
||||||
|
if (peerConnectionWrapper != null) {
|
||||||
|
PeerConnection.IceConnectionState iceConnectionState = peerConnectionWrapper.getPeerConnection().iceConnectionState();
|
||||||
|
connected = iceConnectionState == PeerConnection.IceConnectionState.CONNECTED ||
|
||||||
|
iceConnectionState == PeerConnection.IceConnectionState.COMPLETED;
|
||||||
|
}
|
||||||
|
|
||||||
String nick;
|
String nick;
|
||||||
if (hasExternalSignalingServer) {
|
if (hasExternalSignalingServer) {
|
||||||
nick = webSocketClient.getDisplayNameForSession(session);
|
nick = webSocketClient.getDisplayNameForSession(session);
|
||||||
} else {
|
} else {
|
||||||
PeerConnectionWrapper peerConnectionWrapper = getPeerConnectionWrapperForSessionIdAndType(session,
|
|
||||||
videoStreamType);
|
|
||||||
nick = peerConnectionWrapper != null ? peerConnectionWrapper.getNick() : "";
|
nick = peerConnectionWrapper != null ? peerConnectionWrapper.getNick() : "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2282,6 +2322,7 @@ public class CallActivity extends CallBaseActivity {
|
||||||
|
|
||||||
ParticipantDisplayItem participantDisplayItem = new ParticipantDisplayItem(userId,
|
ParticipantDisplayItem participantDisplayItem = new ParticipantDisplayItem(userId,
|
||||||
session,
|
session,
|
||||||
|
connected,
|
||||||
nick,
|
nick,
|
||||||
urlForAvatar,
|
urlForAvatar,
|
||||||
mediaStream,
|
mediaStream,
|
||||||
|
|
|
@ -6,6 +6,7 @@ import org.webrtc.MediaStream;
|
||||||
public class ParticipantDisplayItem {
|
public class ParticipantDisplayItem {
|
||||||
private String userId;
|
private String userId;
|
||||||
private String session;
|
private String session;
|
||||||
|
private boolean connected;
|
||||||
private String nick;
|
private String nick;
|
||||||
private String urlForAvatar;
|
private String urlForAvatar;
|
||||||
private MediaStream mediaStream;
|
private MediaStream mediaStream;
|
||||||
|
@ -14,9 +15,10 @@ public class ParticipantDisplayItem {
|
||||||
private EglBase rootEglBase;
|
private EglBase rootEglBase;
|
||||||
private boolean isAudioEnabled;
|
private boolean isAudioEnabled;
|
||||||
|
|
||||||
public ParticipantDisplayItem(String userId, String session, String nick, String urlForAvatar, MediaStream mediaStream, String streamType, boolean streamEnabled, EglBase rootEglBase) {
|
public ParticipantDisplayItem(String userId, String session, boolean connected, String nick, String urlForAvatar, MediaStream mediaStream, String streamType, boolean streamEnabled, EglBase rootEglBase) {
|
||||||
this.userId = userId;
|
this.userId = userId;
|
||||||
this.session = session;
|
this.session = session;
|
||||||
|
this.connected = connected;
|
||||||
this.nick = nick;
|
this.nick = nick;
|
||||||
this.urlForAvatar = urlForAvatar;
|
this.urlForAvatar = urlForAvatar;
|
||||||
this.mediaStream = mediaStream;
|
this.mediaStream = mediaStream;
|
||||||
|
@ -41,6 +43,14 @@ public class ParticipantDisplayItem {
|
||||||
this.session = session;
|
this.session = session;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isConnected() {
|
||||||
|
return connected;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setConnected(boolean connected) {
|
||||||
|
this.connected = connected;
|
||||||
|
}
|
||||||
|
|
||||||
public String getNick() {
|
public String getNick() {
|
||||||
return nick;
|
return nick;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ import android.view.ViewGroup;
|
||||||
import android.widget.BaseAdapter;
|
import android.widget.BaseAdapter;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
|
import android.widget.ProgressBar;
|
||||||
import android.widget.RelativeLayout;
|
import android.widget.RelativeLayout;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
@ -96,6 +97,13 @@ public class ParticipantsAdapter extends BaseAdapter {
|
||||||
surfaceViewRenderer = convertView.findViewById(R.id.surface_view);
|
surfaceViewRenderer = convertView.findViewById(R.id.surface_view);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ProgressBar progressBar = convertView.findViewById(R.id.participant_progress_bar);
|
||||||
|
if (!participantDisplayItem.isConnected()) {
|
||||||
|
progressBar.setVisibility(View.VISIBLE);
|
||||||
|
} else {
|
||||||
|
progressBar.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
|
||||||
ViewGroup.LayoutParams layoutParams = convertView.getLayoutParams();
|
ViewGroup.LayoutParams layoutParams = convertView.getLayoutParams();
|
||||||
layoutParams.height = scaleGridViewItemHeight();
|
layoutParams.height = scaleGridViewItemHeight();
|
||||||
convertView.setLayoutParams(layoutParams);
|
convertView.setLayoutParams(layoutParams);
|
||||||
|
|
|
@ -120,6 +120,6 @@ public class PeerConnectionEvent {
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum PeerConnectionEventType {
|
public enum PeerConnectionEventType {
|
||||||
PEER_CONNECTED, PEER_CLOSED, SENSOR_FAR, SENSOR_NEAR, NICK_CHANGE, AUDIO_CHANGE, VIDEO_CHANGE, PUBLISHER_FAILED
|
PEER_CONNECTED, PEER_DISCONNECTED, PEER_CLOSED, SENSOR_FAR, SENSOR_NEAR, NICK_CHANGE, AUDIO_CHANGE, VIDEO_CHANGE, PUBLISHER_FAILED
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -344,6 +344,8 @@ public class PeerConnectionWrapper {
|
||||||
|
|
||||||
Log.d("iceConnectionChangeTo: ", iceConnectionState.name() + " over " + peerConnection.hashCode() + " " + sessionId);
|
Log.d("iceConnectionChangeTo: ", iceConnectionState.name() + " over " + peerConnection.hashCode() + " " + sessionId);
|
||||||
if (iceConnectionState.equals(PeerConnection.IceConnectionState.CONNECTED)) {
|
if (iceConnectionState.equals(PeerConnection.IceConnectionState.CONNECTED)) {
|
||||||
|
EventBus.getDefault().post(new PeerConnectionEvent(PeerConnectionEvent.PeerConnectionEventType.PEER_CONNECTED,
|
||||||
|
sessionId, null, null, null));
|
||||||
|
|
||||||
if (!isMCUPublisher) {
|
if (!isMCUPublisher) {
|
||||||
EventBus.getDefault().post(new MediaStreamEvent(remoteStream, sessionId, videoStreamType));
|
EventBus.getDefault().post(new MediaStreamEvent(remoteStream, sessionId, videoStreamType));
|
||||||
|
@ -352,11 +354,20 @@ public class PeerConnectionWrapper {
|
||||||
if (hasInitiated) {
|
if (hasInitiated) {
|
||||||
sendInitialMediaStatus();
|
sendInitialMediaStatus();
|
||||||
}
|
}
|
||||||
|
} else if (iceConnectionState.equals(PeerConnection.IceConnectionState.COMPLETED)) {
|
||||||
|
EventBus.getDefault().post(new PeerConnectionEvent(PeerConnectionEvent.PeerConnectionEventType.PEER_CONNECTED,
|
||||||
|
sessionId, null, null, null));
|
||||||
} else if (iceConnectionState.equals(PeerConnection.IceConnectionState.CLOSED)) {
|
} else if (iceConnectionState.equals(PeerConnection.IceConnectionState.CLOSED)) {
|
||||||
EventBus.getDefault().post(new PeerConnectionEvent(PeerConnectionEvent.PeerConnectionEventType
|
EventBus.getDefault().post(new PeerConnectionEvent(PeerConnectionEvent.PeerConnectionEventType
|
||||||
.PEER_CLOSED, sessionId, null, null, videoStreamType));
|
.PEER_CLOSED, sessionId, null, null, videoStreamType));
|
||||||
|
} else if (iceConnectionState.equals(PeerConnection.IceConnectionState.DISCONNECTED) ||
|
||||||
|
iceConnectionState.equals(PeerConnection.IceConnectionState.NEW) ||
|
||||||
|
iceConnectionState.equals(PeerConnection.IceConnectionState.CHECKING)) {
|
||||||
|
EventBus.getDefault().post(new PeerConnectionEvent(PeerConnectionEvent.PeerConnectionEventType.PEER_DISCONNECTED,
|
||||||
|
sessionId, null, null, null));
|
||||||
} else if (iceConnectionState.equals(PeerConnection.IceConnectionState.FAILED)) {
|
} else if (iceConnectionState.equals(PeerConnection.IceConnectionState.FAILED)) {
|
||||||
|
EventBus.getDefault().post(new PeerConnectionEvent(PeerConnectionEvent.PeerConnectionEventType.PEER_DISCONNECTED,
|
||||||
|
sessionId, null, null, null));
|
||||||
if (isMCUPublisher) {
|
if (isMCUPublisher) {
|
||||||
EventBus.getDefault().post(new PeerConnectionEvent(PeerConnectionEvent.PeerConnectionEventType.PUBLISHER_FAILED, sessionId, null, null, null));
|
EventBus.getDefault().post(new PeerConnectionEvent(PeerConnectionEvent.PeerConnectionEventType.PUBLISHER_FAILED, sessionId, null, null, null));
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,6 +77,14 @@
|
||||||
android:layout_marginBottom="20dp"
|
android:layout_marginBottom="20dp"
|
||||||
app:placeholderImage="@drawable/ic_switch_video_white_24px"
|
app:placeholderImage="@drawable/ic_switch_video_white_24px"
|
||||||
app:roundAsCircle="true" />
|
app:roundAsCircle="true" />
|
||||||
|
|
||||||
|
<ProgressBar
|
||||||
|
android:id="@+id/selfVideoViewProgressBar"
|
||||||
|
style="?android:attr/progressBarStyle"
|
||||||
|
android:layout_width="@dimen/call_self_participant_progress_bar_size"
|
||||||
|
android:layout_height="@dimen/call_self_participant_progress_bar_size"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:visibility="gone" />
|
||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
|
|
|
@ -71,4 +71,11 @@
|
||||||
android:visibility="invisible"
|
android:visibility="invisible"
|
||||||
tools:visibility="visible" />
|
tools:visibility="visible" />
|
||||||
|
|
||||||
|
<ProgressBar
|
||||||
|
android:id="@+id/participant_progress_bar"
|
||||||
|
style="?android:attr/progressBarStyle"
|
||||||
|
android:layout_width="@dimen/call_participant_progress_bar_size"
|
||||||
|
android:layout_height="@dimen/call_participant_progress_bar_size"
|
||||||
|
android:layout_centerInParent="@bool/value_true" />
|
||||||
|
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
|
|
@ -67,6 +67,8 @@
|
||||||
<dimen name="call_self_video_short_side_length">80dp</dimen>
|
<dimen name="call_self_video_short_side_length">80dp</dimen>
|
||||||
<dimen name="call_grid_item_min_height">180dp</dimen>
|
<dimen name="call_grid_item_min_height">180dp</dimen>
|
||||||
<dimen name="call_controls_height">110dp</dimen>
|
<dimen name="call_controls_height">110dp</dimen>
|
||||||
|
<dimen name="call_participant_progress_bar_size">48dp</dimen>
|
||||||
|
<dimen name="call_self_participant_progress_bar_size">48dp</dimen>
|
||||||
<dimen name="zero">0dp</dimen>
|
<dimen name="zero">0dp</dimen>
|
||||||
|
|
||||||
<dimen name="online_status_item_height">52dp</dimen>
|
<dimen name="online_status_item_height">52dp</dimen>
|
||||||
|
|
Loading…
Reference in a new issue