From f01abdc00d4435a29889adf9e8b234e397faa3dd Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 14 Aug 2026 09:33:16 +0200 Subject: [PATCH] Add KDoc to the `libraries/push` API interfaces Document PushService, GetCurrentPushProvider, NotificationCleaner and NotificationBitmapLoader along with their members, and add the missing @param entries across the notification interfaces. The NotificationCleaner docs record the behaviour shared by all its methods, which is not visible in the signatures: each one also removes the grouping summary notification once it has no children left. Co-Authored-By: Claude Opus 5 (1M context) --- .../push/api/GetCurrentPushProvider.kt | 10 +++++ .../android/libraries/push/api/PushService.kt | 31 +++++++++++++ .../notifications/NotificationBitmapLoader.kt | 3 ++ .../api/notifications/NotificationCleaner.kt | 44 +++++++++++++++++++ .../notifications/NotificationSoundUpdater.kt | 12 +++++ .../OnMissedCallNotificationHandler.kt | 4 ++ .../NotificationConversationService.kt | 12 +++++ .../sound/NotificationSoundCopier.kt | 6 +++ 8 files changed, 122 insertions(+) diff --git a/libraries/push/api/src/main/kotlin/io/element/android/libraries/push/api/GetCurrentPushProvider.kt b/libraries/push/api/src/main/kotlin/io/element/android/libraries/push/api/GetCurrentPushProvider.kt index a6fbb47173..eb2ce09545 100644 --- a/libraries/push/api/src/main/kotlin/io/element/android/libraries/push/api/GetCurrentPushProvider.kt +++ b/libraries/push/api/src/main/kotlin/io/element/android/libraries/push/api/GetCurrentPushProvider.kt @@ -10,6 +10,16 @@ package io.element.android.libraries.push.api import io.element.android.libraries.matrix.api.core.SessionId +/** + * Reads the name of the push provider a session is currently registered with. + * + * This is the low-level accessor used where depending on the whole push feature would be too much; prefer [PushService.getCurrentPushProvider] otherwise. + */ interface GetCurrentPushProvider { + /** + * Returns the stored provider name, or `null` when the session has no push provider selected yet. + * + * @param sessionId the session to read the provider of. + */ suspend fun getCurrentPushProvider(sessionId: SessionId): String? } diff --git a/libraries/push/api/src/main/kotlin/io/element/android/libraries/push/api/PushService.kt b/libraries/push/api/src/main/kotlin/io/element/android/libraries/push/api/PushService.kt index a43ee36403..4a5037d17f 100644 --- a/libraries/push/api/src/main/kotlin/io/element/android/libraries/push/api/PushService.kt +++ b/libraries/push/api/src/main/kotlin/io/element/android/libraries/push/api/PushService.kt @@ -16,9 +16,14 @@ import io.element.android.libraries.pushproviders.api.Distributor import io.element.android.libraries.pushproviders.api.PushProvider import kotlinx.coroutines.flow.Flow +/** + * Entry point for push notification setup: choosing a push provider, registering a pusher with the homeserver, and inspecting the push history. + */ interface PushService { /** * Return the current push provider, or null if none. + * + * @param sessionId the session to read the provider of. */ suspend fun getCurrentPushProvider(sessionId: SessionId): PushProvider? @@ -31,6 +36,10 @@ interface PushService { * Will unregister any previous pusher and register a new one with the provided [PushProvider]. * * The method has effect only if the [PushProvider] is different than the current one. + * + * @param matrixClient the session to register the pusher for. + * @param pushProvider the provider to switch to. + * @param distributor the distributor of that provider to use, which matters for providers such as UnifiedPush. */ suspend fun registerWith( matrixClient: MatrixClient, @@ -42,6 +51,8 @@ interface PushService { * Ensure that the pusher with the current push provider and distributor is registered. * If there is no current config, the default push provider with the default distributor will be used. * Error can be [PusherRegistrationFailure]. + * + * @param matrixClient the session to ensure the pusher of. */ suspend fun ensurePusherIsRegistered( matrixClient: MatrixClient, @@ -50,17 +61,35 @@ interface PushService { /** * Store the given push provider as the current one, but do not register. * To be used when there is no distributor available. + * + * @param sessionId the session to store the provider for. + * @param pushProvider the provider to remember. */ suspend fun selectPushProvider( sessionId: SessionId, pushProvider: PushProvider, ) + /** + * Whether the user has asked not to be warned about pusher registration failures for this session. + * + * @param sessionId the session to read the preference of. + */ fun ignoreRegistrationError(sessionId: SessionId): Flow + + /** + * Remembers whether pusher registration failures should be reported to the user for this session. + * + * @param sessionId the session to store the preference for. + * @param ignore true to stop warning the user about registration failures. + */ suspend fun setIgnoreRegistrationError(sessionId: SessionId, ignore: Boolean) /** + * Asks the homeserver to send a test push, so the user can check that the whole chain works. * Return false in case of early error. + * + * @param sessionId the session to test the push setup of. */ suspend fun testPush(sessionId: SessionId): Boolean @@ -86,6 +115,8 @@ interface PushService { /** * Notify the user that the service is un-registered. + * + * @param userId the user whose push service is no longer registered. */ suspend fun onServiceUnregistered(userId: UserId) } diff --git a/libraries/push/api/src/main/kotlin/io/element/android/libraries/push/api/notifications/NotificationBitmapLoader.kt b/libraries/push/api/src/main/kotlin/io/element/android/libraries/push/api/notifications/NotificationBitmapLoader.kt index bded69991b..9dd53ade09 100644 --- a/libraries/push/api/src/main/kotlin/io/element/android/libraries/push/api/notifications/NotificationBitmapLoader.kt +++ b/libraries/push/api/src/main/kotlin/io/element/android/libraries/push/api/notifications/NotificationBitmapLoader.kt @@ -14,6 +14,9 @@ import coil3.ImageLoader import io.element.android.libraries.designsystem.components.avatar.AvatarData import io.element.android.libraries.matrix.ui.media.AVATAR_THUMBNAIL_SIZE_IN_PIXEL +/** + * Loads the avatars used to decorate notifications, since the notification APIs need bitmaps rather than Compose images. + */ interface NotificationBitmapLoader { /** * Get icon of a room. diff --git a/libraries/push/api/src/main/kotlin/io/element/android/libraries/push/api/notifications/NotificationCleaner.kt b/libraries/push/api/src/main/kotlin/io/element/android/libraries/push/api/notifications/NotificationCleaner.kt index 0a4e35c697..95966f8eb1 100644 --- a/libraries/push/api/src/main/kotlin/io/element/android/libraries/push/api/notifications/NotificationCleaner.kt +++ b/libraries/push/api/src/main/kotlin/io/element/android/libraries/push/api/notifications/NotificationCleaner.kt @@ -13,12 +13,56 @@ import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.core.SessionId import io.element.android.libraries.matrix.api.core.ThreadId +/** + * Dismisses notifications that are already displayed, typically because the user has now seen the events elsewhere. + * + * Every method also removes the grouping summary notification when it is left without children. + */ interface NotificationCleaner { + /** + * Dismisses every message notification of a session. + * + * @param sessionId the session whose notifications are dismissed. + */ fun clearAllMessagesEvents(sessionId: SessionId) + + /** + * Dismisses the message notifications of one room. + * + * @param sessionId the session the room belongs to. + * @param roomId the room whose notifications are dismissed. + */ fun clearMessagesForRoom(sessionId: SessionId, roomId: RoomId) + + /** + * Dismisses the message notifications of one thread, leaving the rest of the room's notifications in place. + * + * @param sessionId the session the room belongs to. + * @param roomId the room the thread belongs to. + * @param threadId the thread whose notifications are dismissed. + */ fun clearMessagesForThread(sessionId: SessionId, roomId: RoomId, threadId: ThreadId) + + /** + * Dismisses the notification of a single event. + * + * @param sessionId the session the event belongs to. + * @param eventId the event whose notification is dismissed. + */ fun clearEvent(sessionId: SessionId, eventId: EventId) + /** + * Dismisses every membership notification of a session, i.e. the invitations and the join requests. + * + * @param sessionId the session whose notifications are dismissed. + */ fun clearMembershipNotificationForSession(sessionId: SessionId) + + /** + * Dismisses the membership notifications of one room. + * + * @param sessionId the session the room belongs to. + * @param roomId the room whose notifications are dismissed. + */ fun clearMembershipNotificationForRoom(sessionId: SessionId, roomId: RoomId) } diff --git a/libraries/push/api/src/main/kotlin/io/element/android/libraries/push/api/notifications/NotificationSoundUpdater.kt b/libraries/push/api/src/main/kotlin/io/element/android/libraries/push/api/notifications/NotificationSoundUpdater.kt index b23c4122ad..91f50abc07 100644 --- a/libraries/push/api/src/main/kotlin/io/element/android/libraries/push/api/notifications/NotificationSoundUpdater.kt +++ b/libraries/push/api/src/main/kotlin/io/element/android/libraries/push/api/notifications/NotificationSoundUpdater.kt @@ -14,8 +14,20 @@ import io.element.android.libraries.preferences.api.store.NotificationSound * versioned channel because Android forbids mutating sound after creation. */ interface NotificationSoundUpdater { + /** + * Recreates the message notification channel so it uses [sound]. + * + * @param sound the sound the new channel should play. + * @param version bumped on every change, since a new channel id is the only way to change a channel's sound. + */ fun recreateNoisyChannel(sound: NotificationSound, version: Int) + /** + * Recreates the ringing call notification channel so it uses [sound]; see [recreateNoisyChannel] for why a version is needed. + * + * @param sound the sound the new channel should play. + * @param version bumped on every change to force a new channel id. + */ fun recreateRingingCallChannel(sound: NotificationSound, version: Int) /** Current channel sound classified into [NotificationSound]. Null when the channel doesn't exist. */ diff --git a/libraries/push/api/src/main/kotlin/io/element/android/libraries/push/api/notifications/OnMissedCallNotificationHandler.kt b/libraries/push/api/src/main/kotlin/io/element/android/libraries/push/api/notifications/OnMissedCallNotificationHandler.kt index 2ba61925c5..d4e051ebf2 100644 --- a/libraries/push/api/src/main/kotlin/io/element/android/libraries/push/api/notifications/OnMissedCallNotificationHandler.kt +++ b/libraries/push/api/src/main/kotlin/io/element/android/libraries/push/api/notifications/OnMissedCallNotificationHandler.kt @@ -18,6 +18,10 @@ import io.element.android.libraries.matrix.api.core.SessionId interface OnMissedCallNotificationHandler { /** * Adds a missed call notification. + * + * @param sessionId the session the call was received on. + * @param roomId the room the call took place in. + * @param eventId the call notification event that went unanswered. */ suspend fun addMissedCallNotification( sessionId: SessionId, diff --git a/libraries/push/api/src/main/kotlin/io/element/android/libraries/push/api/notifications/conversations/NotificationConversationService.kt b/libraries/push/api/src/main/kotlin/io/element/android/libraries/push/api/notifications/conversations/NotificationConversationService.kt index 4ea80e4ce8..b3bffc0147 100644 --- a/libraries/push/api/src/main/kotlin/io/element/android/libraries/push/api/notifications/conversations/NotificationConversationService.kt +++ b/libraries/push/api/src/main/kotlin/io/element/android/libraries/push/api/notifications/conversations/NotificationConversationService.kt @@ -18,6 +18,12 @@ interface NotificationConversationService { /** * Called when a new message is received in a room. * It should create a new conversation shortcut for this room. + * + * @param sessionId the session the message belongs to. + * @param roomId the room the message was received in. + * @param roomName the name to show on the shortcut, or `null` when the room has none. + * @param roomIsDirect whether the room is a direct message, which changes how the shortcut is presented. + * @param roomAvatarUrl the avatar to show on the shortcut, or `null` when the room has none. */ suspend fun onSendMessage( sessionId: SessionId, @@ -30,12 +36,18 @@ interface NotificationConversationService { /** * Called when a room is left. * It should remove the conversation shortcut for this room. + * + * @param sessionId the session the room belongs to. + * @param roomId the room that was left. */ suspend fun onLeftRoom(sessionId: SessionId, roomId: RoomId) /** * Called when the list of available rooms changes. * It should update the conversation shortcuts accordingly, removing shortcuts for no longer joined rooms. + * + * @param sessionId the session the rooms belong to. + * @param roomIds the rooms the user is currently joined to. */ suspend fun onAvailableRoomsChanged(sessionId: SessionId, roomIds: Set) } diff --git a/libraries/push/api/src/main/kotlin/io/element/android/libraries/push/api/notifications/sound/NotificationSoundCopier.kt b/libraries/push/api/src/main/kotlin/io/element/android/libraries/push/api/notifications/sound/NotificationSoundCopier.kt index 2268198353..ad3d73656f 100644 --- a/libraries/push/api/src/main/kotlin/io/element/android/libraries/push/api/notifications/sound/NotificationSoundCopier.kt +++ b/libraries/push/api/src/main/kotlin/io/element/android/libraries/push/api/notifications/sound/NotificationSoundCopier.kt @@ -12,6 +12,12 @@ package io.element.android.libraries.push.api.notifications.sound * FileProvider, so the persisted reference outlives the original source. */ interface NotificationSoundCopier { + /** + * Copies the picked sound into app-private storage, replacing any file previously stored for [slot]. + * + * @param sourceUriString the uri of the sound the user picked. + * @param slot which of the two sounds is being set, since each keeps its own copy. + */ suspend fun copyToAppFiles(sourceUriString: String, slot: SoundSlot): CopyResult /**