diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Collaboration/Collaborators/Listener.php | 19 | ||||
-rw-r--r-- | lib/Service/BreakoutRoomService.php | 4 | ||||
-rw-r--r-- | lib/Signaling/BackendNotifier.php | 27 | ||||
-rw-r--r-- | lib/Signaling/Listener.php | 88 | ||||
-rw-r--r-- | lib/Signaling/Manager.php | 3 |
5 files changed, 136 insertions, 5 deletions
diff --git a/lib/Collaboration/Collaborators/Listener.php b/lib/Collaboration/Collaborators/Listener.php index 2f9603942..d39101d5d 100644 --- a/lib/Collaboration/Collaborators/Listener.php +++ b/lib/Collaboration/Collaborators/Listener.php @@ -32,6 +32,7 @@ use OCA\Talk\Model\Attendee; use OCA\Talk\Participant; use OCA\Talk\Room; use OCA\Talk\Service\ParticipantService; +use OCA\Talk\TalkSession; use OCP\Collaboration\AutoComplete\AutoCompleteEvent; use OCP\Collaboration\AutoComplete\IManager; use OCP\EventDispatcher\IEventDispatcher; @@ -44,19 +45,25 @@ class Listener { protected IUserManager $userManager; protected ParticipantService $participantService; protected Config $config; + protected TalkSession $talkSession; /** @var string[] */ protected array $allowedGroupIds = []; protected string $roomToken; protected ?Room $room = null; + protected ?string $userId; public function __construct(Manager $manager, IUserManager $userManager, ParticipantService $participantService, - Config $config) { + Config $config, + TalkSession $talkSession, + ?string $userId) { $this->manager = $manager; $this->userManager = $userManager; $this->participantService = $participantService; + $this->talkSession = $talkSession; $this->config = $config; + $this->userId = $userId; } public static function register(IEventDispatcher $dispatcher): void { @@ -122,10 +129,18 @@ class Listener { } protected function filterExistingParticipants(string $token, array $results): array { + $sessionId = $this->talkSession->getSessionForRoom($token); try { - $this->room = $this->manager->getRoomByToken($token); + $this->room = $this->manager->getRoomForUserByToken($token, $this->userId); + if ($this->userId !== null) { + $this->participantService->getParticipant($this->room, $this->userId, $sessionId); + } else { + $this->participantService->getParticipantBySession($this->room, $sessionId); + } } catch (RoomNotFoundException $e) { return $results; + } catch (ParticipantNotFoundException $e) { + return $results; } if (!empty($results['groups'])) { diff --git a/lib/Service/BreakoutRoomService.php b/lib/Service/BreakoutRoomService.php index 9872ecdd4..e2180124a 100644 --- a/lib/Service/BreakoutRoomService.php +++ b/lib/Service/BreakoutRoomService.php @@ -432,6 +432,8 @@ class BreakoutRoomService { throw new \InvalidArgumentException('mode'); } + $this->roomService->setBreakoutRoomStatus($parent, BreakoutRoom::STATUS_STOPPED); + $breakoutRooms = $this->manager->getMultipleRoomsByObject(BreakoutRoom::PARENT_OBJECT_TYPE, $parent->getToken()); foreach ($breakoutRooms as $breakoutRoom) { $this->roomService->setLobby($breakoutRoom, Webinary::LOBBY_NON_MODERATORS, null); @@ -441,8 +443,6 @@ class BreakoutRoomService { } } - $this->roomService->setBreakoutRoomStatus($parent, BreakoutRoom::STATUS_STOPPED); - return $breakoutRooms; } diff --git a/lib/Signaling/BackendNotifier.php b/lib/Signaling/BackendNotifier.php index 139107a9d..577cc7645 100644 --- a/lib/Signaling/BackendNotifier.php +++ b/lib/Signaling/BackendNotifier.php @@ -281,6 +281,33 @@ class BackendNotifier { } /** + * The given participants should switch to the given room. + * + * @param Room $room + * @param string $switchToRoomToken + * @param string[] $sessionIds + * @throws \Exception + */ + public function switchToRoom(Room $room, string $switchToRoomToken, array $sessionIds): void { + $start = microtime(true); + $this->backendRequest($room, [ + 'type' => 'switchto', + 'switchto' => [ + 'roomid' => $switchToRoomToken, + 'sessions' => $sessionIds, + ], + ]); + $duration = microtime(true) - $start; + $this->logger->debug('Switch to room: {token} {roomid} {sessions} ({duration})', [ + 'token' => $room->getToken(), + 'roomid' => $switchToRoomToken, + 'sessions' => print_r($sessionIds, true), + 'duration' => sprintf('%.2f', $duration), + 'app' => 'spreed-hpb', + ]); + } + + /** * The participant list of the given room has been modified. * * @param Room $room diff --git a/lib/Signaling/Listener.php b/lib/Signaling/Listener.php index 7087d49d9..76b89c074 100644 --- a/lib/Signaling/Listener.php +++ b/lib/Signaling/Listener.php @@ -37,6 +37,8 @@ use OCA\Talk\Events\RemoveParticipantEvent; use OCA\Talk\Events\RemoveUserEvent; use OCA\Talk\Events\RoomEvent; use OCA\Talk\GuestManager; +use OCA\Talk\Manager; +use OCA\Talk\Model\BreakoutRoom; use OCA\Talk\Participant; use OCA\Talk\Room; use OCA\Talk\Service\ParticipantService; @@ -81,6 +83,9 @@ class Listener { $dispatcher->addListener(Room::EVENT_AFTER_LISTABLE_SET, [self::class, 'notifyAfterRoomSettingsChanged']); $dispatcher->addListener(Room::EVENT_AFTER_LOBBY_STATE_SET, [self::class, 'notifyAfterRoomSettingsChanged']); $dispatcher->addListener(Room::EVENT_AFTER_SIP_ENABLED_SET, [self::class, 'notifyAfterRoomSettingsChanged']); + $dispatcher->addListener(Room::EVENT_AFTER_SET_CALL_RECORDING, [self::class, 'notifyAfterRoomSettingsChanged']); + $dispatcher->addListener(Room::EVENT_AFTER_SET_BREAKOUT_ROOM_MODE, [self::class, 'notifyAfterRoomSettingsChanged']); + $dispatcher->addListener(Room::EVENT_AFTER_SET_BREAKOUT_ROOM_STATUS, [self::class, 'notifyAfterRoomSettingsChanged']); // TODO remove handler with "roomModified" in favour of handler with // "participantsModified" once the clients no longer expect a // "roomModified" message for participant type changes. @@ -98,6 +103,7 @@ class Listener { $dispatcher->addListener(Room::EVENT_AFTER_END_CALL_FOR_EVERYONE, [self::class, 'sendEndCallForEveryone']); $dispatcher->addListener(Room::EVENT_AFTER_GUESTS_CLEAN, [self::class, 'notifyParticipantsAfterGuestClean']); $dispatcher->addListener(Room::EVENT_AFTER_SET_CALL_RECORDING, [self::class, 'sendSignalingMessageWhenToggleRecording']); + $dispatcher->addListener(Room::EVENT_AFTER_SET_BREAKOUT_ROOM_STATUS, [self::class, 'notifyParticipantsAfterSetBreakoutRoomStatus']); $dispatcher->addListener(GuestManager::EVENT_AFTER_NAME_UPDATE, [self::class, 'notifyParticipantsAfterNameUpdated']); $dispatcher->addListener(ChatManager::EVENT_AFTER_MESSAGE_SEND, [self::class, 'notifyUsersViaExternalSignalingToRefreshTheChat']); $dispatcher->addListener(ChatManager::EVENT_AFTER_SYSTEM_MESSAGE_SEND, [self::class, 'notifyUsersViaExternalSignalingToRefreshTheChat']); @@ -324,6 +330,88 @@ class Listener { $notifier->participantsModified($event->getRoom(), $sessionIds); } + public static function notifyParticipantsAfterSetBreakoutRoomStatus(RoomEvent $event): void { + if (self::isUsingInternalSignaling()) { + return; + } + + $room = $event->getRoom(); + if ($room->getBreakoutRoomStatus() === BreakoutRoom::STATUS_STARTED) { + self::notifyParticipantsAfterBreakoutRoomStarted($room); + } else { + self::notifyParticipantsAfterBreakoutRoomStopped($room); + } + } + + private static function notifyParticipantsAfterBreakoutRoomStarted(Room $room): void { + $manager = Server::get(Manager::class); + $breakoutRooms = $manager->getMultipleRoomsByObject(BreakoutRoom::PARENT_OBJECT_TYPE, $room->getToken()); + + $switchToData = []; + + $participantService = Server::get(ParticipantService::class); + $parentRoomParticipants = $participantService->getSessionsAndParticipantsForRoom($room); + + $notifier = Server::get(BackendNotifier::class); + + foreach ($breakoutRooms as $breakoutRoom) { + $sessionIds = []; + + $breakoutRoomParticipants = $participantService->getParticipantsForRoom($breakoutRoom); + foreach ($breakoutRoomParticipants as $breakoutRoomParticipant) { + foreach (self::getSessionIdsForNonModeratorsMatchingParticipant($breakoutRoomParticipant, $parentRoomParticipants) as $sessionId) { + $sessionIds[] = $sessionId; + } + } + + if (!empty($sessionIds)) { + $notifier->switchToRoom($room, $breakoutRoom->getToken(), $sessionIds); + } + } + } + + private static function getSessionIdsForNonModeratorsMatchingParticipant(Participant $targetParticipant, array $participants) { + $sessionIds = []; + + foreach ($participants as $participant) { + if ($participant->getAttendee()->getActorType() === $targetParticipant->getAttendee()->getActorType() && + $participant->getAttendee()->getActorId() === $targetParticipant->getAttendee()->getActorId() && + !$participant->hasModeratorPermissions()) { + $session = $participant->getSession(); + if ($session) { + $sessionIds[] = $session->getSessionId(); + } + } + } + + return $sessionIds; + } + + private static function notifyParticipantsAfterBreakoutRoomStopped(Room $room): void { + $manager = Server::get(Manager::class); + $breakoutRooms = $manager->getMultipleRoomsByObject(BreakoutRoom::PARENT_OBJECT_TYPE, $room->getToken()); + + $participantService = Server::get(ParticipantService::class); + + $notifier = Server::get(BackendNotifier::class); + + foreach ($breakoutRooms as $breakoutRoom) { + $sessionIds = []; + + $participants = $participantService->getSessionsAndParticipantsForRoom($breakoutRoom); + foreach ($participants as $participant) { + $session = $participant->getSession(); + if ($session) { + $sessionIds[] = $session->getSessionId(); + } + } + + if (!empty($sessionIds)) { + $notifier->switchToRoom($breakoutRoom, $room->getToken(), $sessionIds); + } + } + } + public static function notifyParticipantsAfterNameUpdated(ModifyParticipantEvent $event): void { if (self::isUsingInternalSignaling()) { return; diff --git a/lib/Signaling/Manager.php b/lib/Signaling/Manager.php index 87f472900..8fb6667a1 100644 --- a/lib/Signaling/Manager.php +++ b/lib/Signaling/Manager.php @@ -55,7 +55,8 @@ class Manager { $features = array_map('trim', $features); return in_array('audio-video-permissions', $features, true) && in_array('incall-all', $features, true) - && in_array('hello-v2', $features, true); + && in_array('hello-v2', $features, true) + && in_array('switchto', $features, true); } public function getSignalingServerLinkForConversation(?Room $room): string { |