Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
25 changes: 19 additions & 6 deletions docs/events.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,30 @@ See the general [Nextcloud Developers - Events](https://docs.nextcloud.com/serve
* After event: `OCA\Talk\Events\LobbyModifiedEvent`
* Since: 18.0.0

### Call started

* Before event: `OCA\Talk\Events\BeforeCallStartedEvent`
* After event: `OCA\Talk\Events\CallStartedEvent`
The after event might be skipped if the request lost the race to update the database.
A parallel request will have triggered the before and after events in the meantime.
* Since: 20.0.0

### Call ended for everyone

* Before event: `OCA\Talk\Events\BeforeCallEndedForEveryoneEvent`
* After event: `OCA\Talk\Events\CallEndedForEveryoneEvent`
* Since: 18.0.0
* Since: 20.0.0 Extends the abstract `ACallEndedEvent`

### Call ended

When the last participant is leaving the call, the session expired or the participant was removed.

* Before event: `OCA\Talk\Events\BeforeCallEndedEvent`
* After event: `OCA\Talk\Events\CallEndedEvent`
The after event might be skipped if the request lost the race to update the database.
A parallel request will have triggered the before and after events in the meantime.
* Since: 20.0.0

### Conversation password verify

Expand All @@ -47,12 +66,6 @@ Allows to verify a password and set a redirect URL for the invalid case
* Event: `OCA\Talk\Events\RoomPasswordVerifyEvent`
* Since: 18.0.0

### Active since modified

* Before event: `OCA\Talk\Events\BeforeActiveSinceModifiedEvent`
* After event: `OCA\Talk\Events\ActiveSinceModifiedEvent`
* Since: 20.0.0

## Participant related events

### Attendees added
Expand Down
93 changes: 18 additions & 75 deletions lib/Activity/Listener.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,18 @@
namespace OCA\Talk\Activity;

use OCA\Talk\Chat\ChatManager;
use OCA\Talk\Events\AParticipantModifiedEvent;
use OCA\Talk\Events\ACallEndedEvent;
use OCA\Talk\Events\ARoomEvent;
use OCA\Talk\Events\AttendeeRemovedEvent;
use OCA\Talk\Events\AttendeesAddedEvent;
use OCA\Talk\Events\BeforeCallEndedForEveryoneEvent;
use OCA\Talk\Events\ParticipantModifiedEvent;
use OCA\Talk\Events\SessionLeftRoomEvent;
use OCA\Talk\Events\CallEndedEvent;
use OCA\Talk\Events\CallEndedForEveryoneEvent;
use OCA\Talk\Model\Attendee;
use OCA\Talk\Participant;
use OCA\Talk\Room;
use OCA\Talk\Service\ParticipantService;
use OCA\Talk\Service\RecordingService;
use OCA\Talk\Service\RoomService;
use OCP\Activity\Exceptions\InvalidValueException;
use OCP\Activity\IManager;
use OCP\AppFramework\Utility\ITimeFactory;
use OCP\EventDispatcher\Event;
Expand Down Expand Up @@ -53,85 +52,31 @@ public function handle(Event $event): void {
}

match (get_class($event)) {
BeforeCallEndedForEveryoneEvent::class => $this->generateCallActivity($event->getRoom(), true, $event->getActor()),
SessionLeftRoomEvent::class,
AttendeeRemovedEvent::class => $this->generateCallActivity($event->getRoom()),
ParticipantModifiedEvent::class => $this->handleParticipantModified($event),
CallEndedEvent::class,
CallEndedForEveryoneEvent::class => $this->generateCallActivity($event),
AttendeesAddedEvent::class => $this->generateInvitationActivity($event->getRoom(), $event->getAttendees()),
};
}

protected function setActive(ParticipantModifiedEvent $event): void {
if ($event->getProperty() !== AParticipantModifiedEvent::PROPERTY_IN_CALL) {
return;
}

if ($event->getOldValue() !== Participant::FLAG_DISCONNECTED
|| $event->getNewValue() === Participant::FLAG_DISCONNECTED) {
return;
}

$participant = $event->getParticipant();
$this->roomService->setActiveSince(
$event->getRoom(),
$this->timeFactory->getDateTime(),
$participant->getSession() ? $participant->getSession()->getInCall() : Participant::FLAG_DISCONNECTED
);
}

protected function handleParticipantModified(ParticipantModifiedEvent $event): void {
if ($event->getProperty() !== AParticipantModifiedEvent::PROPERTY_IN_CALL) {
return;
}

if ($event->getOldValue() === Participant::FLAG_DISCONNECTED
|| $event->getNewValue() !== Participant::FLAG_DISCONNECTED) {
$this->setActive($event);
return;
}

if ($event->getDetail(AParticipantModifiedEvent::DETAIL_IN_CALL_END_FOR_EVERYONE)) {
// The call activity was generated already if the call is ended
// for everyone
return;
}

$this->generateCallActivity($event->getRoom());
}

/**
* Call activity: "You attended a call with {user1} and {user2}"
*
* @param Room $room
* @param bool $endForEveryone
* @param Participant|null $actor
* @return bool True if activity was generated, false otherwise
*/
protected function generateCallActivity(Room $room, bool $endForEveryone = false, ?Participant $actor = null): bool {
$activeSince = $room->getActiveSince();
if (!$activeSince instanceof \DateTime || (!$endForEveryone && $this->participantService->hasActiveSessionsInCall($room))) {
return false;
}
protected function generateCallActivity(ACallEndedEvent $event): void {
$room = $event->getRoom();
$actor = $event->getActor();
$activeSince = $event->getOldValue();

$duration = $this->timeFactory->getTime() - $activeSince->getTimestamp();
$userIds = $this->participantService->getParticipantUserIds($room, $activeSince);
$numGuests = $this->participantService->getGuestCount($room, $activeSince);

$message = 'call_ended';
if ($endForEveryone) {
if ($event instanceof CallEndedForEveryoneEvent) {
$message = 'call_ended_everyone';
} elseif (($room->getType() === Room::TYPE_ONE_TO_ONE || $room->getType() === Room::TYPE_ONE_TO_ONE_FORMER) && \count($userIds) === 1) {
$message = 'call_missed';
}

if (!$this->roomService->resetActiveSince($room)) {
// Race-condition, the room was already reset.
return false;
}

if ($room->getCallRecording() !== Room::RECORDING_NONE && $room->getCallRecording() !== Room::RECORDING_FAILED) {
$this->recordingService->stop($room);
}
if ($actor instanceof Participant) {
$actorId = $actor->getAttendee()->getActorId();
$actorType = $actor->getAttendee()->getActorType();
Expand All @@ -149,12 +94,12 @@ protected function generateCallActivity(Room $room, bool $endForEveryone = false
]), $this->timeFactory->getDateTime(), false);

if (empty($userIds)) {
return false;
return;
}

$event = $this->activityManager->generateEvent();
$activity = $this->activityManager->generateEvent();
try {
$event->setApp('spreed')
$activity->setApp('spreed')
->setType('spreed')
->setAuthor('')
->setObject('room', $room->getId())
Expand All @@ -165,21 +110,19 @@ protected function generateCallActivity(Room $room, bool $endForEveryone = false
'guests' => $numGuests,
'duration' => $duration,
]);
} catch (\InvalidArgumentException $e) {
} catch (InvalidValueException $e) {
$this->logger->error($e->getMessage(), ['exception' => $e]);
return false;
return;
}

foreach ($userIds as $userId) {
try {
$event->setAffectedUser($userId);
$this->activityManager->publish($event);
$activity->setAffectedUser($userId);
$this->activityManager->publish($activity);
} catch (\Throwable $e) {
$this->logger->error($e->getMessage(), ['exception' => $e]);
}
}

return true;
}

/**
Expand Down
21 changes: 12 additions & 9 deletions lib/AppInfo/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,12 @@
use OCA\Talk\Config;
use OCA\Talk\Dashboard\TalkWidget;
use OCA\Talk\Deck\DeckPluginLoader;
use OCA\Talk\Events\ActiveSinceModifiedEvent;
use OCA\Talk\Events\AttendeeRemovedEvent;
use OCA\Talk\Events\AttendeesAddedEvent;
use OCA\Talk\Events\AttendeesRemovedEvent;
use OCA\Talk\Events\BeforeAttendeeRemovedEvent;
use OCA\Talk\Events\BeforeAttendeesAddedEvent;
use OCA\Talk\Events\BeforeCallEndedForEveryoneEvent;
use OCA\Talk\Events\BeforeCallStartedEvent;
use OCA\Talk\Events\BeforeDuplicateShareSentEvent;
use OCA\Talk\Events\BeforeGuestJoinedRoomEvent;
use OCA\Talk\Events\BeforeParticipantModifiedEvent;
Expand All @@ -48,8 +47,10 @@
use OCA\Talk\Events\BotEnabledEvent;
use OCA\Talk\Events\BotInstallEvent;
use OCA\Talk\Events\BotUninstallEvent;
use OCA\Talk\Events\CallEndedEvent;
use OCA\Talk\Events\CallEndedForEveryoneEvent;
use OCA\Talk\Events\CallNotificationSendEvent;
use OCA\Talk\Events\CallStartedEvent;
use OCA\Talk\Events\ChatMessageSentEvent;
use OCA\Talk\Events\EmailInvitationSentEvent;
use OCA\Talk\Events\GuestJoinedRoomEvent;
Expand Down Expand Up @@ -171,10 +172,8 @@ public function register(IRegistrationContext $context): void {

// Activity listeners
$context->registerEventListener(AttendeesAddedEvent::class, ActivityListener::class);
$context->registerEventListener(AttendeeRemovedEvent::class, ActivityListener::class);
$context->registerEventListener(BeforeCallEndedForEveryoneEvent::class, ActivityListener::class);
$context->registerEventListener(ParticipantModifiedEvent::class, ActivityListener::class, 75);
$context->registerEventListener(SessionLeftRoomEvent::class, ActivityListener::class, -100);
$context->registerEventListener(CallEndedEvent::class, ActivityListener::class);
$context->registerEventListener(CallEndedForEveryoneEvent::class, ActivityListener::class);

// Bot listeners
$context->registerEventListener(BotDisabledEvent::class, BotListener::class);
Expand Down Expand Up @@ -246,8 +245,8 @@ public function register(IRegistrationContext $context): void {

// Notification listeners
$context->registerEventListener(AttendeesAddedEvent::class, NotificationListener::class);
$context->registerEventListener(ActiveSinceModifiedEvent::class, NotificationListener::class);
$context->registerEventListener(BeforeParticipantModifiedEvent::class, NotificationListener::class);
$context->registerEventListener(BeforeCallStartedEvent::class, NotificationListener::class);
$context->registerEventListener(CallStartedEvent::class, NotificationListener::class);
$context->registerEventListener(CallNotificationSendEvent::class, NotificationListener::class);
$context->registerEventListener(ParticipantModifiedEvent::class, NotificationListener::class);
$context->registerEventListener(UserJoinedRoomEvent::class, NotificationListener::class);
Expand All @@ -260,12 +259,16 @@ public function register(IRegistrationContext $context): void {

// Recording listeners
$context->registerEventListener(RoomDeletedEvent::class, RecordingListener::class);
$context->registerEventListener(CallEndedEvent::class, RecordingListener::class);
$context->registerEventListener(CallEndedForEveryoneEvent::class, RecordingListener::class);
$context->registerEventListener(TranscriptionSuccessfulEvent::class, RecordingListener::class);
$context->registerEventListener(TranscriptionFailedEvent::class, RecordingListener::class);

// Federation listeners
$context->registerEventListener(BeforeRoomDeletedEvent::class, TalkV1BeforeRoomDeletedListener::class);
$context->registerEventListener(ActiveSinceModifiedEvent::class, TalkV1RoomModifiedListener::class);
$context->registerEventListener(CallEndedEvent::class, TalkV1RoomModifiedListener::class);
$context->registerEventListener(CallEndedForEveryoneEvent::class, TalkV1RoomModifiedListener::class);
$context->registerEventListener(CallStartedEvent::class, TalkV1RoomModifiedListener::class);
$context->registerEventListener(LobbyModifiedEvent::class, TalkV1RoomModifiedListener::class);
$context->registerEventListener(RoomModifiedEvent::class, TalkV1RoomModifiedListener::class);
$context->registerEventListener(ChatMessageSentEvent::class, TalkV1MessageSentListener::class);
Expand Down
22 changes: 16 additions & 6 deletions lib/Controller/CallController.php
Original file line number Diff line number Diff line change
Expand Up @@ -163,10 +163,11 @@ public function joinCall(?int $flags = null, ?int $forcePermissions = null, bool
$this->roomService->setPermissions($this->room, 'call', Attendee::PERMISSIONS_MODIFY_SET, $forcePermissions, true);
}

$joined = $this->participantService->changeInCall($this->room, $this->participant, $flags, false, $silent);

if (!$joined) {
return new DataResponse([], Http::STATUS_BAD_REQUEST);
try {
$this->participantService->changeInCall($this->room, $this->participant, $flags, silent: $silent);
$this->roomService->setActiveSince($this->room, $this->participant, $this->timeFactory->getDateTime(), $flags, silent: $silent);
} catch (\InvalidArgumentException $e) {
return new DataResponse(['error' => $e->getMessage()], Http::STATUS_BAD_REQUEST);
}
return new DataResponse();
}
Expand Down Expand Up @@ -226,8 +227,10 @@ public function joinFederatedCall(string $sessionId, ?int $flags = null, bool $s
return new DataResponse(['error' => 'consent'], Http::STATUS_BAD_REQUEST);
}

$joined = $this->participantService->changeInCall($this->room, $this->participant, $flags, false, $silent);
if (!$joined) {
try {
$this->participantService->changeInCall($this->room, $this->participant, $flags, false, $silent);
$this->roomService->setActiveSince($this->room, $this->participant, $this->timeFactory->getDateTime(), $flags, silent: $silent);
} catch (\InvalidArgumentException $e) {
return new DataResponse([], Http::STATUS_BAD_REQUEST);
}

Expand Down Expand Up @@ -414,8 +417,12 @@ public function leaveCall(bool $all = false): DataResponse {

if ($all && $this->participant->hasModeratorPermissions()) {
$this->participantService->endCallForEveryone($this->room, $this->participant);
$this->roomService->resetActiveSince($this->room, $this->participant, true);
} else {
$this->participantService->changeInCall($this->room, $this->participant, Participant::FLAG_DISCONNECTED);
if (!$this->participantService->hasActiveSessionsInCall($this->room)) {
$this->roomService->resetActiveSince($this->room, $this->participant);
}
}

return new DataResponse();
Expand Down Expand Up @@ -443,6 +450,9 @@ public function leaveFederatedCall(string $sessionId): DataResponse {
}

$this->participantService->changeInCall($this->room, $this->participant, Participant::FLAG_DISCONNECTED);
if (!$this->participantService->hasActiveSessionsInCall($this->room)) {
$this->roomService->resetActiveSince($this->room, $this->participant);
}

return new DataResponse();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,29 +8,28 @@

namespace OCA\Talk\Events;

use OCA\Talk\Participant;
use OCA\Talk\Room;

abstract class AActiveSinceModifiedEvent extends ARoomModifiedEvent {
/**
* @psalm-method \DateTime getOldValue()
*/
abstract class ACallEndedEvent extends ARoomModifiedEvent {
public function __construct(
Room $room,
?\DateTime $newValue,
?\DateTime $oldValue,
protected int $callFlag,
protected int $oldCallFlag,
?Participant $actor,
\DateTime $oldActiveSince,
) {
parent::__construct(
$room,
self::PROPERTY_ACTIVE_SINCE,
$newValue,
$oldValue,
null,
$oldActiveSince,
$actor
);
}

public function getCallFlag(): int {
return $this->callFlag;
}

public function getOldCallFlag(): int {
return $this->oldCallFlag;
return Participant::FLAG_DISCONNECTED;
}
}
17 changes: 1 addition & 16 deletions lib/Events/ACallEndedForEveryoneEvent.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,5 @@

namespace OCA\Talk\Events;

use OCA\Talk\Participant;
use OCA\Talk\Room;

abstract class ACallEndedForEveryoneEvent extends ARoomModifiedEvent {
public function __construct(
Room $room,
?Participant $actor = null,
) {
parent::__construct(
$room,
self::PROPERTY_IN_CALL,
Participant::FLAG_DISCONNECTED,
null,
$actor
);
}
abstract class ACallEndedForEveryoneEvent extends ACallEndedEvent {
}
Loading