mirror of
https://github.com/nextcloud/talk-android.git
synced 2024-11-26 23:25:20 +03:00
Keep track of raised hands by remote participants
Note the slight difference in naming between the signaling message ("raiseHand", the action) and the stored data ("RaisedHand", the record of the action). Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
This commit is contained in:
parent
de44370710
commit
4bd3cc826c
7 changed files with 140 additions and 2 deletions
|
@ -2124,7 +2124,7 @@ public class CallActivity extends CallBaseActivity {
|
|||
}
|
||||
|
||||
private CallParticipant addCallParticipant(String sessionId) {
|
||||
CallParticipant callParticipant = new CallParticipant(sessionId);
|
||||
CallParticipant callParticipant = new CallParticipant(sessionId, signalingMessageReceiver);
|
||||
callParticipants.put(sessionId, callParticipant);
|
||||
|
||||
SignalingMessageReceiver.CallParticipantMessageListener callParticipantMessageListener =
|
||||
|
|
|
@ -5,6 +5,7 @@ import android.os.Looper;
|
|||
import android.text.TextUtils;
|
||||
|
||||
import com.nextcloud.talk.call.CallParticipantModel;
|
||||
import com.nextcloud.talk.call.RaisedHand;
|
||||
import com.nextcloud.talk.utils.ApiUtils;
|
||||
|
||||
import org.webrtc.EglBase;
|
||||
|
@ -42,6 +43,7 @@ public class ParticipantDisplayItem {
|
|||
private MediaStream mediaStream;
|
||||
private boolean streamEnabled;
|
||||
private boolean isAudioEnabled;
|
||||
private RaisedHand raisedHand;
|
||||
|
||||
public ParticipantDisplayItem(String baseUrl, String defaultGuestNick, EglBase rootEglBase, String streamType,
|
||||
CallParticipantModel callParticipantModel) {
|
||||
|
@ -82,6 +84,8 @@ public class ParticipantDisplayItem {
|
|||
callParticipantModel.isVideoAvailable() : false;
|
||||
}
|
||||
|
||||
raisedHand = callParticipantModel.getRaisedHand();
|
||||
|
||||
participantDisplayItemNotifier.notifyChange();
|
||||
}
|
||||
|
||||
|
@ -129,6 +133,10 @@ public class ParticipantDisplayItem {
|
|||
return isAudioEnabled;
|
||||
}
|
||||
|
||||
public RaisedHand getRaisedHand() {
|
||||
return raisedHand;
|
||||
}
|
||||
|
||||
public void addObserver(Observer observer) {
|
||||
participantDisplayItemNotifier.addObserver(observer);
|
||||
}
|
||||
|
@ -148,6 +156,7 @@ public class ParticipantDisplayItem {
|
|||
", streamType='" + streamType + '\'' +
|
||||
", streamEnabled=" + streamEnabled +
|
||||
", rootEglBase=" + rootEglBase +
|
||||
", raisedHand=" + raisedHand +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
*/
|
||||
package com.nextcloud.talk.call;
|
||||
|
||||
import com.nextcloud.talk.signaling.SignalingMessageReceiver;
|
||||
import com.nextcloud.talk.webrtc.PeerConnectionWrapper;
|
||||
|
||||
import org.webrtc.MediaStream;
|
||||
|
@ -32,6 +33,18 @@ import org.webrtc.PeerConnection;
|
|||
*/
|
||||
public class CallParticipant {
|
||||
|
||||
private final SignalingMessageReceiver.CallParticipantMessageListener callParticipantMessageListener =
|
||||
new SignalingMessageReceiver.CallParticipantMessageListener() {
|
||||
@Override
|
||||
public void onRaiseHand(boolean state, long timestamp) {
|
||||
callParticipantModel.setRaisedHand(state, timestamp);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUnshareScreen() {
|
||||
}
|
||||
};
|
||||
|
||||
private final PeerConnectionWrapper.PeerConnectionObserver peerConnectionObserver =
|
||||
new PeerConnectionWrapper.PeerConnectionObserver() {
|
||||
@Override
|
||||
|
@ -99,14 +112,21 @@ public class CallParticipant {
|
|||
|
||||
private final MutableCallParticipantModel callParticipantModel;
|
||||
|
||||
private final SignalingMessageReceiver signalingMessageReceiver;
|
||||
|
||||
private PeerConnectionWrapper peerConnectionWrapper;
|
||||
private PeerConnectionWrapper screenPeerConnectionWrapper;
|
||||
|
||||
public CallParticipant(String sessionId) {
|
||||
public CallParticipant(String sessionId, SignalingMessageReceiver signalingMessageReceiver) {
|
||||
callParticipantModel = new MutableCallParticipantModel(sessionId);
|
||||
|
||||
this.signalingMessageReceiver = signalingMessageReceiver;
|
||||
signalingMessageReceiver.addListener(callParticipantMessageListener, sessionId);
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
signalingMessageReceiver.removeListener(callParticipantMessageListener);
|
||||
|
||||
if (peerConnectionWrapper != null) {
|
||||
peerConnectionWrapper.removeObserver(peerConnectionObserver);
|
||||
peerConnectionWrapper.removeListener(dataChannelMessageListener);
|
||||
|
|
|
@ -29,6 +29,9 @@ import java.util.Objects;
|
|||
/**
|
||||
* Read-only data model for (remote) call participants.
|
||||
*
|
||||
* If the hand was never raised null is returned by "getRaisedHand()". Otherwise a RaisedHand object is returned with
|
||||
* the current state (raised or not) and the timestamp when the raised hand state last changed.
|
||||
*
|
||||
* The received audio and video are available only if the participant is sending them and also has them enabled.
|
||||
* Before a connection is established it is not known whether audio and video are available or not, so null is returned
|
||||
* in that case (therefore it should not be autoboxed to a plain boolean without checking that).
|
||||
|
@ -72,6 +75,8 @@ public class CallParticipantModel {
|
|||
protected Data<String> userId;
|
||||
protected Data<String> nick;
|
||||
|
||||
protected Data<RaisedHand> raisedHand;
|
||||
|
||||
protected Data<PeerConnection.IceConnectionState> iceConnectionState;
|
||||
protected Data<MediaStream> mediaStream;
|
||||
protected Data<Boolean> audioAvailable;
|
||||
|
@ -86,6 +91,8 @@ public class CallParticipantModel {
|
|||
this.userId = new Data<>();
|
||||
this.nick = new Data<>();
|
||||
|
||||
this.raisedHand = new Data<>();
|
||||
|
||||
this.iceConnectionState = new Data<>();
|
||||
this.mediaStream = new Data<>();
|
||||
this.audioAvailable = new Data<>();
|
||||
|
@ -107,6 +114,10 @@ public class CallParticipantModel {
|
|||
return nick.getValue();
|
||||
}
|
||||
|
||||
public RaisedHand getRaisedHand() {
|
||||
return raisedHand.getValue();
|
||||
}
|
||||
|
||||
public PeerConnection.IceConnectionState getIceConnectionState() {
|
||||
return iceConnectionState.getValue();
|
||||
}
|
||||
|
|
|
@ -41,6 +41,10 @@ public class MutableCallParticipantModel extends CallParticipantModel {
|
|||
this.nick.setValue(nick);
|
||||
}
|
||||
|
||||
public void setRaisedHand(boolean state, long timestamp) {
|
||||
this.raisedHand.setValue(new RaisedHand(state, timestamp));
|
||||
}
|
||||
|
||||
public void setIceConnectionState(PeerConnection.IceConnectionState iceConnectionState) {
|
||||
this.iceConnectionState.setValue(iceConnectionState);
|
||||
}
|
||||
|
|
23
app/src/main/java/com/nextcloud/talk/call/RaisedHand.kt
Normal file
23
app/src/main/java/com/nextcloud/talk/call/RaisedHand.kt
Normal file
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* Nextcloud Talk application
|
||||
*
|
||||
* @author Daniel Calviño Sánchez
|
||||
* Copyright (C) 2023 Daniel Calviño Sánchez <danxuliu@gmail.com>
|
||||
*
|
||||
* 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.call
|
||||
|
||||
data class RaisedHand(val state: Boolean, val timestamp: Long) {
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* Nextcloud Talk application
|
||||
*
|
||||
* @author Daniel Calviño Sánchez
|
||||
* Copyright (C) 2022 Daniel Calviño Sánchez <danxuliu@gmail.com>
|
||||
*
|
||||
* 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.call;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.only;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
public class CallParticipantModelTest {
|
||||
|
||||
private MutableCallParticipantModel callParticipantModel;
|
||||
|
||||
private CallParticipantModel.Observer mockedCallParticipantModelObserver;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
callParticipantModel = new MutableCallParticipantModel("theSessionId");
|
||||
|
||||
mockedCallParticipantModelObserver = mock(CallParticipantModel.Observer.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetRaisedHand() {
|
||||
callParticipantModel.addObserver(mockedCallParticipantModelObserver);
|
||||
|
||||
callParticipantModel.setRaisedHand(true, 4815162342L);
|
||||
|
||||
verify(mockedCallParticipantModelObserver, only()).onChange();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetRaisedHandTwice() {
|
||||
callParticipantModel.addObserver(mockedCallParticipantModelObserver);
|
||||
|
||||
callParticipantModel.setRaisedHand(true, 4815162342L);
|
||||
callParticipantModel.setRaisedHand(false, 4815162342108L);
|
||||
|
||||
verify(mockedCallParticipantModelObserver, times(2)).onChange();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetRaisedHandTwiceWithSameValue() {
|
||||
callParticipantModel.addObserver(mockedCallParticipantModelObserver);
|
||||
|
||||
callParticipantModel.setRaisedHand(true, 4815162342L);
|
||||
callParticipantModel.setRaisedHand(true, 4815162342L);
|
||||
|
||||
verify(mockedCallParticipantModelObserver, only()).onChange();
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue