Simplify push notification flow by using locally stored values for pending pushes (#6258)
* Create `PushRequest` in push history DB: this will be used to store requests for push notifications, either pending or completed ones. * Rename `WorkManagerRequest` to `WorkManagerRequestBuilder`: make its `build` method return a list of `WorkManagerRequestWrapper`, which can be used to enqueue normal or unique workers. * Rename `PerformDatabaseVacuumRequestBuilder` and adapt it to the new API. * Adjust other components using `WorkManagerRequest`. * Replace `SyncNotificationWorkManagerRequestBuilder` with `SyncPendingNotificationsRequestBuilder` and `FetchNotificationsWorker` with `FetchPendingNotificationsWorker`: this new pair of request builder and worker allow enqueuing requests for a session id and, once the worker runs, retrieve all the pending request data and use it to fetch the associated events. This simplifies quite a bit how this data had to be passed or grouped, since it's no longer necessary to do so * Add new methods to `PushHistoryService` to modify the `PushDatabase`: - insertOrUpdatePushRequest - insertOrUpdatePushRequests - getPendingPushRequests - removeOldPushRequests * Make `PushHandler` just handle incoming pushes: those will be inserted into the pending push request table in DB, then handled by the new worker. Once the process finished, a new `NotificationResultProcessor` will handle the results and what needs to be done with them (call ringing, displaying notifications, etc.) * Add `requestType` optional parameter to `WorkManagerScheduler.cancel` so we can decide to only cancel some kinds of requests. * Add migration to remove existing work manager requests for fetching notifications, since the previous worker class no longer exists.
This commit is contained in:
parent
a8c66381f2
commit
721add707c
48 changed files with 1715 additions and 1892 deletions
|
|
@ -1,15 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2025 Element Creations Ltd.
|
||||
* Copyright 2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.libraries.workmanager.api
|
||||
|
||||
import androidx.work.WorkRequest
|
||||
|
||||
interface WorkManagerRequest {
|
||||
fun build(): Result<List<WorkRequest>>
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Copyright (c) 2025 Element Creations Ltd.
|
||||
* Copyright 2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.libraries.workmanager.api
|
||||
|
||||
import androidx.work.ExistingWorkPolicy
|
||||
import androidx.work.WorkRequest
|
||||
|
||||
/**
|
||||
* A base class that can be customized to [build] work requests to schedule in `WorkManager`.
|
||||
*/
|
||||
interface WorkManagerRequestBuilder {
|
||||
/**
|
||||
* Builds a work request wrapper using the provided data.
|
||||
*/
|
||||
suspend fun build(): Result<List<WorkManagerRequestWrapper>>
|
||||
}
|
||||
|
||||
/**
|
||||
* A wrapper that allows us to avoid using Android APIs directly when scheduling workers.
|
||||
*/
|
||||
data class WorkManagerRequestWrapper(
|
||||
val request: WorkRequest,
|
||||
val type: WorkManagerWorkerType = WorkManagerWorkerType.Default,
|
||||
)
|
||||
|
||||
/**
|
||||
* The type of worker to use when scheduling the task.
|
||||
*/
|
||||
sealed interface WorkManagerWorkerType {
|
||||
/**
|
||||
* This allows a single worker instance with the [name] id to run at the same time. Its [policy] can be customized.
|
||||
*/
|
||||
data class Unique(val name: String, val policy: ExistingWorkPolicy) : WorkManagerWorkerType
|
||||
|
||||
/**
|
||||
* The default worker type, with no custom rules.
|
||||
*/
|
||||
data object Default : WorkManagerWorkerType
|
||||
}
|
||||
|
|
@ -11,9 +11,21 @@ package io.element.android.libraries.workmanager.api
|
|||
import io.element.android.libraries.matrix.api.core.SessionId
|
||||
|
||||
interface WorkManagerScheduler {
|
||||
fun submit(workManagerRequest: WorkManagerRequest)
|
||||
/**
|
||||
* Submits a new work request built from [workManagerRequestBuilder] to run in `WorkManager`.
|
||||
*/
|
||||
suspend fun submit(workManagerRequestBuilder: WorkManagerRequestBuilder)
|
||||
|
||||
/**
|
||||
* Checks if there are any pending requests scheduled for the provided [sessionId] and [requestType].
|
||||
*/
|
||||
fun hasPendingWork(sessionId: SessionId, requestType: WorkManagerRequestType): Boolean
|
||||
fun cancel(sessionId: SessionId)
|
||||
|
||||
/**
|
||||
* Cancel pending work requests for the session [SessionId].
|
||||
* If [requestType] is provided, it will only cancel requests for that type, otherwise it will cancel all requests.
|
||||
*/
|
||||
fun cancel(sessionId: SessionId, requestType: WorkManagerRequestType? = null)
|
||||
}
|
||||
|
||||
fun workManagerTag(sessionId: SessionId, requestType: WorkManagerRequestType): String {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue