-
-
Notifications
You must be signed in to change notification settings - Fork 293
Split call participants and peer connections #2600
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
8308d06 to
c31299c
Compare
0f357b0 to
7549569
Compare
|
The two new issues reported by SpotBugs are both related to this code: The Performance - PSC: Presize Collection - Method does not presize the allocation of a collection seems to assume that The Dodgy code - UAA: Use Add All - Method uses simple loop to copy contents of one collection to another is technically right, but it seems to ignore that the loop does other things with the added elements. Therefore, even if |
|
/rebase |
7549569 to
695de97
Compare
|
/rebase |
695de97 to
07e0b6b
Compare
|
tested with sermo, removed mic and video permissions of caller and also set mic and video to "none" when starting the call. |
timkrueger
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Spinning wheel still exists.
07e0b6b to
f439825
Compare
|
Fixed. I do not know what I was thinking on 🤦 Besides the scenario described above now the connection is not established either in voice only calls if the remote participant is publishing video but not audio. I was going to prevent establishing screen sharing connections in voice only calls, but the problem is that since some versions ago screen shares can also include sound (for example, if the participant is sharing a browser tab with sound). It is not possible to differentiate from the call flags between a video-only screen share and an audio and video screen share in order to establish or not to establish the connection, so... for now the connection is also established in voice only calls when a participant shares the screen, although in most cases the result will be just a loading spinner because the screen share connection only has a video track and that video track was explicitly stopped due to being in a voice only call 🤷 It might be possible to detect that specific case and prevent showing the loading spinner, but... something for the future ;-) |
|
calling from my local machine without hpb with the "none" devices scenario, then the avatar of the android participant is spinning in the webbrowser |
f439825 to
35ed03a
Compare
Partially fixed (when the session ID of the Android app participant is higher than the session ID of the browser participant, which was a regression introduced in this pull request). When the session ID of the browser participant is the higher one the connection will still fail if the browser participant is not sending media; this was an existing issue and requires further refactorings so, for now, it is not fixed and tracked in #2679 |
|
/rebase |
Rather than just providing a coarse "connected" or "not connected" value now the views receive the raw ICE connection state. Combined with other properties this will make possible to show a finer grained status (like done in the WebUI), although for now just "connected" or "not connected" is still shown as before. Signed-off-by: Daniel Calviño Sánchez <[email protected]>
Note that the session ID, user ID and the stream type attributes are still kept, as they can be useful to identify the instance when debugging. Signed-off-by: Daniel Calviño Sánchez <[email protected]>
Signed-off-by: Daniel Calviño Sánchez <[email protected]>
Generic final attributes first, followed by object specific final attributes and then other object attributes. Signed-off-by: Daniel Calviño Sánchez <[email protected]>
Instead of explicitly calling "notifyDataSetChanged" after setting values on a ParticipantDisplayItem now the adapter observes all its items and calls "notifyDataSetChanged" automatically when any of them changes. Although this adds some boilerplate code it will make possible to update the ParticipantDisplayItems and automatically propagate the changes to the adapter when a model changes, rather than having to explicitly do it from the CallActivity. Signed-off-by: Daniel Calviño Sánchez <[email protected]>
Clients that modify the model would define the variables using the mutable subclass, while clients that only need to access the model are expected to use the read-only base class. The read-only class provides an observer; as it is expected that the model will be modified from background threads but observed from the main thread the observer can be registered along a handler to be notified on its thread, independently of on which thread the values were set. Currently there does not seem to be a need to observe each value on its own, so the observer is notified in a coarse way when any value changes. Signed-off-by: Daniel Calviño Sánchez <[email protected]>
Instead of explicitly setting the values on the ParticipantDisplayItems now the values are set on the CallParticipantModels, and the items are automatically updated from their model when they change. Different items are still used for the audio/video and screen shares of the same participant, so the type is used to select from which properties of the model is the item updated. As the model may be updated from background threads it is explicitly observed by the items from the main thread using a Handler shared by all the items. Signed-off-by: Daniel Calviño Sánchez <[email protected]>
Signed-off-by: Daniel Calviño Sánchez <[email protected]>
CallParticipant provides a read-only CallParticipantModel and internally handles the data channel and peer connection events that modify the model. Nevertheless, the CallParticipant requires certain properties to be externally set, like the userId or the peer connections. Signed-off-by: Daniel Calviño Sánchez <[email protected]>
The listeners for call participant messages and for the call participant nick provided by offers / answers were created and destroyed based on the peer connections, although they were implicitly associated to a call participant. Now they are explicitly created and destroyed based on its associated call participant. Signed-off-by: Daniel Calviño Sánchez <[email protected]>
Signed-off-by: Daniel Calviño Sánchez <[email protected]>
The ParticipantDisplayItems were created and destroyed based on the peer connections. Now a ParticipantDisplayItem of "video" type is associated to a call participant, while an additional item is created and destroyed depending on the state of the screen peer connection of the call participant. Signed-off-by: Daniel Calviño Sánchez <[email protected]>
The connection state changes to "closed" only when the connection is closed. However, closing a connection does not fire any event (not even the "iceConnectionStateChanged" event), so the event handler can be removed as it will never be executed. Signed-off-by: Daniel Calviño Sánchez <[email protected]>
The observers were created for any peer connection, but after recent changes they ignored all changes but those from the self peer connection. Therefore it is enough to just add an explicit listener on that peer connection rather than on all of them. Signed-off-by: Daniel Calviño Sánchez <[email protected]>
For now only the same signaling messages that were already handled are still handled; in the future it could be extended to handle other messages, like the one sent by the external signaling server when a participant leaves the room (in some cases no participants update message is sent if the participant leaves the call and room at the same time, which causes the participants to still be seen as in call until a new update is received). Signed-off-by: Daniel Calviño Sánchez <[email protected]>
As CallParticipantList starts listening on the signaling messages as soon as it is created it needs to be created and destroyed right before entering and exiting a call. Otherwise it could receive messages on other states (for example, while the "connection timeout" message is shown) and thus once the local participant joined the event would not include the other participants already in the call as joined (although they would be anyway reported as unchanged). Signed-off-by: Daniel Calviño Sánchez <[email protected]>
Signed-off-by: Daniel Calviño Sánchez <[email protected]>
Instead of trying to create a video peer connection for any joined participant now only a call participant is created for any joined participant, and a video peer connection is created only for those participants that are publishing audio or video. If a call participants does not have a video peer connection the call participant is now seen as "connected" from the UI, as there is no need to show a progress bar for that participant. Signed-off-by: Daniel Calviño Sánchez <[email protected]>
The peer connections will be of either "video" or "screen" type, so they can be simply removed based on the session id and an explicit type. Signed-off-by: Daniel Calviño Sánchez <[email protected]>
35ed03a to
67e259f
Compare
|
APK file: https://www.kaminsky.me/nc-dev/android-artifacts/2600-talk.apk |
|
/backport to stable-15.1 |

Fixes #2544
Requires #2590 (so the first commit of this pull request is Handle the raw ICE connection state in the views)It is highly recommended to review this commit by commit rather than all at once ;-) Commit messages may also provide additional context.
Model classes for call participants were added.
CallParticipantis the main model class, which observes the changes in its peer connections and data channels and updates a data object that keeps track of the state*. This data object is the one exposed to the view classes through a read-only object (CallParticipantModel) that can be also observed for changes on specific threads. Thanks to that theParticipantDisplayItemsare now automatically updated in the main thread when the model changes, and they also propagate the changes to the adapter (sonotifiyDataSetChangedis automatically called when any item changed).*In the future it should also listen to signaling messages, for example for raised hands, but also for audio/video enabled/disabled events, as they are also sent through signaling messages besides the data channels just in case the data channel connection could not be established.
Besides that, a helper class is now used to keep track of the participants in the call based on the signaling messages, instead of based on the peer connections. For now it just uses the same signaling messages as before, but in the future this could be used to also handle the message sent by the external signaling server when a participant leaves the room, which implicitly means that the participant left the call (if a participant abruptly leaves the call and the room at the same time no message for leaving the call is sent, only about leaving the room).
With all this now call participants are added and removed when they join and leave the call, and peer connections are only started when the joined participant is publishing media (according to the call flags of the participant for audio/video, and based on the offers received for screen shares). Updating the peer connections of an existing call participant when the flags change during the call is still needed for proper renegotiation support, and it will be done in a follow up.
The steps below should be tested with HPB; without HPB, as the Android app is publishing media, a peer connection is anyway needed to send it to the other participant even if that participant is not publishing.
How to test
Result with this pull request
The Android app does not try to establish a peer connection with the other participant, and no progess bar is shown on that other participant
Result without this pull request
The Andoid app tries to establish a peer connection with the other participant to receive media (and the external signaling server logs eventually shows that an offer could not be requested), and a progress bar is always shown on that other participant