diff --git a/lib/Signaling/BackendNotifier.php b/lib/Signaling/BackendNotifier.php index 63597b1502b..fe884ee4b35 100644 --- a/lib/Signaling/BackendNotifier.php +++ b/lib/Signaling/BackendNotifier.php @@ -351,60 +351,70 @@ public function participantsModified(Room $room, array $sessionIds): void { * @param Room $room * @param int $flags * @param string[] $sessionIds + * @param bool $changeAll * @throws \Exception */ - public function roomInCallChanged(Room $room, int $flags, array $sessionIds): void { - $changed = []; - $users = []; + public function roomInCallChanged(Room $room, int $flags, array $sessionIds, bool $changeAll = false): void { + if ($changeAll) { + $data = [ + 'incall' => $flags, + 'all' => true + ]; + } else { + $changed = []; + $users = []; - $participants = $this->participantService->getParticipantsForAllSessions($room); - foreach ($participants as $participant) { - $session = $participant->getSession(); - if (!$session instanceof Session) { - continue; - } + $participants = $this->participantService->getParticipantsForAllSessions($room); + foreach ($participants as $participant) { + $session = $participant->getSession(); + if (!$session instanceof Session) { + continue; + } - $attendee = $participant->getAttendee(); - if ($attendee->getActorType() !== Attendee::ACTOR_USERS - && $attendee->getActorType() !== Attendee::ACTOR_GUESTS) { - continue; - } + $attendee = $participant->getAttendee(); + if ($attendee->getActorType() !== Attendee::ACTOR_USERS + && $attendee->getActorType() !== Attendee::ACTOR_GUESTS) { + continue; + } - $data = [ - 'inCall' => $session->getInCall(), - 'lastPing' => $session->getLastPing(), - 'sessionId' => $session->getSessionId(), - 'nextcloudSessionId' => $session->getSessionId(), - 'participantType' => $attendee->getParticipantType(), - 'participantPermissions' => $participant->getPermissions(), - ]; - if ($attendee->getActorType() === Attendee::ACTOR_USERS) { - $data['userId'] = $attendee->getActorId(); - } + $data = [ + 'inCall' => $session->getInCall(), + 'lastPing' => $session->getLastPing(), + 'sessionId' => $session->getSessionId(), + 'nextcloudSessionId' => $session->getSessionId(), + 'participantType' => $attendee->getParticipantType(), + 'participantPermissions' => $participant->getPermissions(), + ]; + if ($attendee->getActorType() === Attendee::ACTOR_USERS) { + $data['userId'] = $attendee->getActorId(); + } - if ($session->getInCall() !== Participant::FLAG_DISCONNECTED) { - $users[] = $data; - } + if ($session->getInCall() !== Participant::FLAG_DISCONNECTED) { + $users[] = $data; + } - if (\in_array($session->getSessionId(), $sessionIds, true)) { - $changed[] = $data; + if (\in_array($session->getSessionId(), $sessionIds, true)) { + $changed[] = $data; + } } + + $data = [ + 'incall' => $flags, + 'changed' => $changed, + 'users' => $users, + ]; } $start = microtime(true); $this->backendRequest($room, [ 'type' => 'incall', - 'incall' => [ - 'incall' => $flags, - 'changed' => $changed, - 'users' => $users - ], + 'incall' => $data, ]); $duration = microtime(true) - $start; $this->logger->debug('Room in-call status changed: {token} {flags} {users} ({duration})', [ 'token' => $room->getToken(), 'flags' => $flags, - 'users' => print_r($sessionIds, true), + 'users' => $changeAll ? 'all' : print_r($sessionIds, true), 'duration' => sprintf('%.2f', $duration), 'app' => 'spreed-hpb', ]); diff --git a/lib/Signaling/Listener.php b/lib/Signaling/Listener.php index 26af22371ec..bae1749ac96 100644 --- a/lib/Signaling/Listener.php +++ b/lib/Signaling/Listener.php @@ -318,7 +318,8 @@ protected static function registerExternalSignaling(IEventDispatcher $dispatcher $notifier->roomInCallChanged( $event->getRoom(), $event->getNewValue(), - $sessionIds + [], + true ); }); diff --git a/lib/Signaling/Manager.php b/lib/Signaling/Manager.php index 23f6048532a..a6dacceaf63 100644 --- a/lib/Signaling/Manager.php +++ b/lib/Signaling/Manager.php @@ -49,7 +49,8 @@ public function isCompatibleSignalingServer(IResponse $response): bool { $featureHeader = $response->getHeader(self::FEATURE_HEADER); $features = explode(',', $featureHeader); $features = array_map('trim', $features); - return in_array('audio-video-permissions', $features, true); + return in_array('audio-video-permissions', $features, true) + && in_array('incall-all', $features, true); } public function getSignalingServerLinkForConversation(?Room $room): string { diff --git a/src/utils/signaling.js b/src/utils/signaling.js index c0d1fbb52d4..6a47b99e4fd 100644 --- a/src/utils/signaling.js +++ b/src/utils/signaling.js @@ -977,7 +977,7 @@ Signaling.Standalone.prototype.helloResponseReceived = function(data) { } } - if (!this.hasFeature('audio-video-permissions')) { + if (!this.hasFeature('audio-video-permissions') || !this.hasFeature('incall-all')) { showError( t('spreed', 'The configured signaling server needs to be updated to be compatible with this version of Talk. Please contact your administrator.'), { @@ -1280,7 +1280,17 @@ Signaling.Standalone.prototype.processRoomListEvent = function(data) { Signaling.Standalone.prototype.processRoomParticipantsEvent = function(data) { switch (data.event.type) { case 'update': - this._trigger('usersChanged', [data.event.update.users || []]) + if (data.event.update.all) { + // With `"all": true` + if (data.event.update.incall === 0) { + this._trigger('allUsersChangedInCallToDisconnected') + } else { + console.error('Unknown room participant event', data) + } + } else { + // With updated user list + this._trigger('usersChanged', [data.event.update.users || []]) + } this._trigger('participantListChanged') break case 'flags': diff --git a/src/utils/webrtc/webrtc.js b/src/utils/webrtc/webrtc.js index 49d26814721..99a6a9079d3 100644 --- a/src/utils/webrtc/webrtc.js +++ b/src/utils/webrtc/webrtc.js @@ -543,6 +543,15 @@ export default function initWebRtc(signaling, _callParticipantCollection, _local }) usersInCallChanged(signaling, usersInCallMapping) }) + signaling.on('allUsersChangedInCallToDisconnected', function() { + if (!localUserInCall) { + return + } + + // "End meeting for all" was used, we don't have a user list but everyone disconnects from the call + usersInCallMapping = {} + usersInCallChanged(signaling, usersInCallMapping) + }) signaling.on('participantFlagsChanged', function(event) { /** * event {