Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
28e7ab4
Handle the raw ICE connection state in the views
danxuliu Nov 24, 2022
44584b5
Remove unused getters and setters
danxuliu Nov 25, 2022
f186d24
Declare attributes set just once in constructor as "final"
danxuliu Nov 25, 2022
67ab30c
Reorder attributes
danxuliu Nov 25, 2022
8c0d08c
Notify that data set changed automatically when display item changes
danxuliu Nov 25, 2022
5dc374d
Add model for (remote) call participants
danxuliu Nov 25, 2022
69fa1f7
Update ParticipantDisplayItem from CallParticipantModel
danxuliu Nov 25, 2022
d2fd8ad
Keep track of the stream in the peer connection
danxuliu Nov 26, 2022
a0fa841
Move handling of call participants to its own class
danxuliu Nov 26, 2022
0336944
Create and destroy helper listeners based on call participants
danxuliu Nov 29, 2022
af44522
Rename methods to add and remove ParticipantDisplayItems
danxuliu Nov 27, 2022
1f1fb02
Create and destroy ParticipantDisplayItems based on call participants
danxuliu Nov 27, 2022
23866f0
Do not handle connection state changes to "closed"
danxuliu Nov 28, 2022
1dfe196
Observe only the self peer connection
danxuliu Nov 28, 2022
dbe9d03
Add helper class to keep track of the participants in a call
danxuliu Nov 29, 2022
feebfbd
Use helper class to keep track of the participants in a call
danxuliu Nov 29, 2022
073ec2a
Extract methods to add and remove call participants
danxuliu Nov 29, 2022
7760ed0
Split call participants and peer connections
danxuliu Nov 29, 2022
9cbca5b
Simplify ending the peer connections
danxuliu Nov 29, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
566 changes: 236 additions & 330 deletions app/src/main/java/com/nextcloud/talk/activities/CallActivity.java

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,65 +1,104 @@
package com.nextcloud.talk.adapters;

import android.os.Handler;
import android.os.Looper;
import android.text.TextUtils;

import com.nextcloud.talk.call.CallParticipantModel;
import com.nextcloud.talk.utils.ApiUtils;

import org.webrtc.EglBase;
import org.webrtc.MediaStream;
import org.webrtc.PeerConnection;

public class ParticipantDisplayItem {
private String baseUrl;

public interface Observer {
void onChange();
}

/**
* Shared handler to receive change notifications from the model on the main thread.
*/
private static final Handler handler = new Handler(Looper.getMainLooper());

private final ParticipantDisplayItemNotifier participantDisplayItemNotifier = new ParticipantDisplayItemNotifier();

private final String baseUrl;
private final String defaultGuestNick;
private final EglBase rootEglBase;

private final String session;
private final String streamType;

private final CallParticipantModel callParticipantModel;

private final CallParticipantModel.Observer callParticipantModelObserver = this::updateFromModel;

private String userId;
private String session;
private boolean connected;
private PeerConnection.IceConnectionState iceConnectionState;
private String nick;
private final String defaultGuestNick;
private String urlForAvatar;
private MediaStream mediaStream;
private String streamType;
private boolean streamEnabled;
private EglBase rootEglBase;
private boolean isAudioEnabled;

public ParticipantDisplayItem(String baseUrl, String userId, String session, boolean connected, String nick, String defaultGuestNick, MediaStream mediaStream, String streamType, boolean streamEnabled, EglBase rootEglBase) {
public ParticipantDisplayItem(String baseUrl, String defaultGuestNick, EglBase rootEglBase, String streamType,
CallParticipantModel callParticipantModel) {
this.baseUrl = baseUrl;
this.userId = userId;
this.session = session;
this.connected = connected;
this.nick = nick;
this.defaultGuestNick = defaultGuestNick;
this.mediaStream = mediaStream;
this.streamType = streamType;
this.streamEnabled = streamEnabled;
this.rootEglBase = rootEglBase;

this.updateUrlForAvatar();
this.session = callParticipantModel.getSessionId();
this.streamType = streamType;

this.callParticipantModel = callParticipantModel;
this.callParticipantModel.addObserver(callParticipantModelObserver, handler);

updateFromModel();
}

public String getUserId() {
return userId;
public void destroy() {
this.callParticipantModel.removeObserver(callParticipantModelObserver);
}

public void setUserId(String userId) {
this.userId = userId;
private void updateFromModel() {
userId = callParticipantModel.getUserId();
nick = callParticipantModel.getNick();

this.updateUrlForAvatar();
}

public String getSession() {
return session;
}
if ("screen".equals(streamType)) {
iceConnectionState = callParticipantModel.getScreenIceConnectionState();
mediaStream = callParticipantModel.getScreenMediaStream();
isAudioEnabled = true;
streamEnabled = true;
} else {
iceConnectionState = callParticipantModel.getIceConnectionState();
mediaStream = callParticipantModel.getMediaStream();
isAudioEnabled = callParticipantModel.isAudioAvailable() != null ?
callParticipantModel.isAudioAvailable() : false;
streamEnabled = callParticipantModel.isVideoAvailable() != null ?
callParticipantModel.isVideoAvailable() : false;
}

public void setSession(String session) {
this.session = session;
participantDisplayItemNotifier.notifyChange();
}

public boolean isConnected() {
return connected;
private void updateUrlForAvatar() {
if (!TextUtils.isEmpty(userId)) {
urlForAvatar = ApiUtils.getUrlForAvatar(baseUrl, userId, true);
} else {
urlForAvatar = ApiUtils.getUrlForGuestAvatar(baseUrl, getNick(), true);
}
}

public void setConnected(boolean connected) {
this.connected = connected;
public boolean isConnected() {
return iceConnectionState == PeerConnection.IceConnectionState.CONNECTED ||
iceConnectionState == PeerConnection.IceConnectionState.COMPLETED ||
// If there is no connection state that means that no connection is needed, so it is a special case that is
// also seen as "connected".
iceConnectionState == null;
}

public String getNick() {
Expand All @@ -70,62 +109,32 @@ public String getNick() {
return nick;
}

public void setNick(String nick) {
this.nick = nick;

this.updateUrlForAvatar();
}

public String getUrlForAvatar() {
return urlForAvatar;
}

private void updateUrlForAvatar() {
if (!TextUtils.isEmpty(userId)) {
urlForAvatar = ApiUtils.getUrlForAvatar(baseUrl, userId, true);
} else {
urlForAvatar = ApiUtils.getUrlForGuestAvatar(baseUrl, getNick(), true);
}
}

public MediaStream getMediaStream() {
return mediaStream;
}

public void setMediaStream(MediaStream mediaStream) {
this.mediaStream = mediaStream;
}

public String getStreamType() {
return streamType;
}

public void setStreamType(String streamType) {
this.streamType = streamType;
}

public boolean isStreamEnabled() {
return streamEnabled;
}

public void setStreamEnabled(boolean streamEnabled) {
this.streamEnabled = streamEnabled;
}

public EglBase getRootEglBase() {
return rootEglBase;
}

public void setRootEglBase(EglBase rootEglBase) {
this.rootEglBase = rootEglBase;
}

public boolean isAudioEnabled() {
return isAudioEnabled;
}

public void setAudioEnabled(boolean audioEnabled) {
isAudioEnabled = audioEnabled;
public void addObserver(Observer observer) {
participantDisplayItemNotifier.addObserver(observer);
}

public void removeObserver(Observer observer) {
participantDisplayItemNotifier.removeObserver(observer);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* Nextcloud Talk application
*
* @author Daniel Calviño Sánchez
* Copyright (C) 2022 Daniel Calviño Sánchez <[email protected]>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.nextcloud.talk.adapters;

import com.nextcloud.talk.signaling.SignalingMessageReceiver;

import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.Set;

/**
* Helper class to register and notify ParticipantDisplayItem.Observers.
*
* This class is only meant for internal use by ParticipantDisplayItem; observers must register themselves against a
* ParticipantDisplayItem rather than against a ParticipantDisplayItemNotifier.
*/
class ParticipantDisplayItemNotifier {

private final Set<ParticipantDisplayItem.Observer> participantDisplayItemObservers = new LinkedHashSet<>();

public synchronized void addObserver(ParticipantDisplayItem.Observer observer) {
if (observer == null) {
throw new IllegalArgumentException("ParticipantDisplayItem.Observer can not be null");
}

participantDisplayItemObservers.add(observer);
}

public synchronized void removeObserver(ParticipantDisplayItem.Observer observer) {
participantDisplayItemObservers.remove(observer);
}

public synchronized void notifyChange() {
for (ParticipantDisplayItem.Observer observer : new ArrayList<>(participantDisplayItemObservers)) {
observer.onChange();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ public class ParticipantsAdapter extends BaseAdapter {

private static final String TAG = "ParticipantsAdapter";

private final ParticipantDisplayItem.Observer participantDisplayItemObserver = this::notifyDataSetChanged;

private final Context mContext;
private final ArrayList<ParticipantDisplayItem> participantDisplayItems;
private final RelativeLayout gridViewWrapper;
Expand All @@ -50,8 +52,17 @@ public ParticipantsAdapter(Context mContext,

this.participantDisplayItems = new ArrayList<>();
this.participantDisplayItems.addAll(participantDisplayItems.values());

for (ParticipantDisplayItem participantDisplayItem : this.participantDisplayItems) {
participantDisplayItem.addObserver(participantDisplayItemObserver);
}
}

public void destroy() {
for (ParticipantDisplayItem participantDisplayItem : participantDisplayItems) {
participantDisplayItem.removeObserver(participantDisplayItemObserver);
}
}

@Override
public int getCount() {
Expand Down
Loading