porting pushes to chat engine

This commit is contained in:
Adam Brown 2022-10-09 21:21:38 +01:00
parent 8bbf7258be
commit 0b02e6d028
10 changed files with 56 additions and 46 deletions

View File

@ -37,7 +37,6 @@ import app.dapk.st.matrix.http.ktor.KtorMatrixHttpClientFactory
import app.dapk.st.matrix.message.*
import app.dapk.st.matrix.message.internal.ImageContentReader
import app.dapk.st.matrix.push.installPushService
import app.dapk.st.matrix.push.pushService
import app.dapk.st.matrix.room.*
import app.dapk.st.matrix.sync.*
import app.dapk.st.matrix.sync.internal.request.ApiToDeviceEvent
@ -47,13 +46,14 @@ import app.dapk.st.messenger.MessengerModule
import app.dapk.st.messenger.gallery.ImageGalleryModule
import app.dapk.st.navigator.IntentFactory
import app.dapk.st.navigator.MessageAttachment
import app.dapk.st.notifications.MatrixPushHandler
import app.dapk.st.notifications.NotificationsModule
import app.dapk.st.olm.DeviceKeyFactory
import app.dapk.st.olm.OlmPersistenceWrapper
import app.dapk.st.olm.OlmWrapper
import app.dapk.st.profile.ProfileModule
import app.dapk.st.push.PushHandler
import app.dapk.st.push.PushModule
import app.dapk.st.push.PushTokenPayload
import app.dapk.st.push.messaging.MessagingServiceAdapter
import app.dapk.st.settings.SettingsModule
import app.dapk.st.share.ShareEntryModule
@ -62,6 +62,7 @@ import app.dapk.st.work.TaskRunnerModule
import app.dapk.st.work.WorkModule
import com.squareup.sqldelight.android.AndroidSqliteDriver
import kotlinx.coroutines.Dispatchers
import kotlinx.serialization.json.Json
import java.io.InputStream
import java.time.Clock
@ -77,7 +78,6 @@ internal class AppModule(context: Application, logger: MatrixLogger) {
private val driver = AndroidSqliteDriver(DapkDb.Schema, context, "dapk.db")
private val database = DapkDb(driver)
private val clock = Clock.systemUTC()
val coroutineDispatchers = CoroutineDispatchers(Dispatchers.IO)
val base64 = AndroidBase64()
@ -97,7 +97,7 @@ internal class AppModule(context: Application, logger: MatrixLogger) {
private val imageContentReader by unsafeLazy { AndroidImageContentReader(context.contentResolver) }
private val matrixModules = MatrixModules(storeModule, trackingModule, workModule, logger, coroutineDispatchers, imageContentReader, base64, buildMeta)
val domainModules = DomainModules(matrixModules, trackingModule.errorTracker, workModule, storeModule, context, coroutineDispatchers)
val domainModules = DomainModules(matrixModules, trackingModule.errorTracker, context, coroutineDispatchers)
val coreAndroidModule = CoreAndroidModule(
intentFactory = object : IntentFactory {
@ -136,13 +136,10 @@ internal class AppModule(context: Application, logger: MatrixLogger) {
trackingModule,
coreAndroidModule,
imageLoaderModule,
imageContentReader,
context,
buildMeta,
deviceMeta,
coroutineDispatchers,
clock,
base64,
)
}
@ -153,13 +150,10 @@ internal class FeatureModules internal constructor(
private val trackingModule: TrackingModule,
private val coreAndroidModule: CoreAndroidModule,
imageLoaderModule: ImageLoaderModule,
imageContentReader: ImageContentReader,
context: Context,
buildMeta: BuildMeta,
deviceMeta: DeviceMeta,
coroutineDispatchers: CoroutineDispatchers,
clock: Clock,
base64: Base64,
) {
val directoryModule by unsafeLazy {
@ -463,7 +457,6 @@ internal class MatrixModules(
}
}
val push by unsafeLazy { matrix.pushService() }
val sync by unsafeLazy { matrix.syncService() }
val room by unsafeLazy { matrix.roomService() }
val profile by unsafeLazy { matrix.profileService() }
@ -472,20 +465,19 @@ internal class MatrixModules(
internal class DomainModules(
private val matrixModules: MatrixModules,
private val errorTracker: ErrorTracker,
private val workModule: WorkModule,
private val storeModule: Lazy<StoreModule>,
private val context: Application,
private val dispatchers: CoroutineDispatchers,
) {
val pushHandler by unsafeLazy {
val store = storeModule.value
MatrixPushHandler(
workScheduler = workModule.workScheduler(),
credentialsStore = store.credentialsStore(),
matrixModules.sync,
store.roomStore(),
)
private val pushHandler by unsafeLazy {
val enginePushHandler = matrixModules.engine.pushHandler()
object : PushHandler {
override fun onNewToken(payload: PushTokenPayload) {
enginePushHandler.onNewToken(JsonString(Json.encodeToString(PushTokenPayload.serializer(), payload)))
}
override fun onMessageReceived(eventId: EventId?, roomId: RoomId?) = enginePushHandler.onMessageReceived(eventId, roomId)
}
}
val messaging by unsafeLazy { MessagingModule(MessagingServiceAdapter(pushHandler), context) }
@ -500,7 +492,7 @@ internal class DomainModules(
messaging.messaging,
)
}
val taskRunnerModule by unsafeLazy { TaskRunnerModule(TaskRunnerAdapter(matrixModules.matrix::run, AppTaskRunner(matrixModules.push))) }
val taskRunnerModule by unsafeLazy { TaskRunnerModule(TaskRunnerAdapter(matrixModules.matrix::run, AppTaskRunner(matrixModules.engine))) }
}

View File

@ -1,13 +1,13 @@
package app.dapk.st.graph
import app.dapk.st.matrix.push.PushService
import app.dapk.st.engine.ChatEngine
import app.dapk.st.push.PushTokenPayload
import app.dapk.st.work.TaskRunner
import io.ktor.client.plugins.*
import kotlinx.serialization.json.Json
class AppTaskRunner(
private val pushService: PushService,
private val chatEngine: ChatEngine,
) {
suspend fun run(workTask: TaskRunner.RunnableWorkTask): TaskRunner.TaskResult {
@ -15,7 +15,7 @@ class AppTaskRunner(
"push_token" -> {
runCatching {
val payload = Json.decodeFromString(PushTokenPayload.serializer(), workTask.task.jsonPayload)
pushService.registerPush(payload.token, payload.gatewayUrl)
chatEngine.registerPushToken(payload.token, payload.gatewayUrl)
}.fold(
onSuccess = { TaskRunner.TaskResult.Success(workTask.source) },
onFailure = {

View File

@ -9,7 +9,7 @@ class BackgroundWorkAdapter(private val workScheduler: WorkScheduler) : Backgrou
WorkScheduler.WorkTask(
jobId = 1,
type = task.type,
jsonPayload = task.jsonPayload,
jsonPayload = task.jsonPayload.value,
)
)
}

View File

@ -1,5 +1,7 @@
package app.dapk.st.engine
import app.dapk.st.matrix.common.EventId
import app.dapk.st.matrix.common.JsonString
import app.dapk.st.matrix.common.RoomId
import kotlinx.coroutines.flow.Flow
import java.io.InputStream
@ -20,7 +22,11 @@ interface ChatEngine {
suspend fun send(message: SendMessage, room: RoomOverview)
suspend fun registerPushToken(token: String, gatewayUrl: String)
fun mediaDecrypter(): MediaDecrypter
fun pushHandler(): PushHandler
}
interface MediaDecrypter {
@ -31,4 +37,9 @@ interface MediaDecrypter {
fun collect(partial: (ByteArray) -> Unit)
}
}
}
interface PushHandler {
fun onNewToken(payload: JsonString)
fun onMessageReceived(eventId: EventId?, roomId: RoomId?)
}

View File

@ -5,7 +5,6 @@ dependencies {
implementation project(':core')
implementation project(':domains:android:core')
implementation project(':domains:store')
implementation project(':matrix:services:push')
firebase(it, "messaging")

View File

@ -1,8 +1,6 @@
applyAndroidLibraryModule(project)
dependencies {
implementation project(":matrix:services:push")
implementation project(":matrix:services:sync")
implementation project(':domains:store')
implementation project(":domains:android:work")
implementation project(':domains:android:push')

View File

@ -18,6 +18,7 @@ import app.dapk.st.matrix.http.ktor.KtorMatrixHttpClientFactory
import app.dapk.st.matrix.message.*
import app.dapk.st.matrix.message.internal.ImageContentReader
import app.dapk.st.matrix.push.installPushService
import app.dapk.st.matrix.push.pushService
import app.dapk.st.matrix.room.*
import app.dapk.st.matrix.sync.*
import app.dapk.st.matrix.sync.internal.request.ApiToDeviceEvent
@ -37,6 +38,7 @@ class MatrixEngine internal constructor(
private val timelineUseCase: Lazy<ReadMarkingTimeline>,
private val sendMessageUseCase: Lazy<SendMessageUseCase>,
private val matrixMediaDecrypter: Lazy<MatrixMediaDecrypter>,
private val matrixPushHandler: Lazy<MatrixPushHandler>,
) : ChatEngine {
override fun directory() = directoryUseCase.value.state()
@ -75,6 +77,10 @@ class MatrixEngine internal constructor(
sendMessageUseCase.value.send(message, room)
}
override suspend fun registerPushToken(token: String, gatewayUrl: String) {
matrix.value.pushService().registerPush(token, gatewayUrl)
}
override fun mediaDecrypter(): MediaDecrypter {
val mediaDecrypter = matrixMediaDecrypter.value
return object : MediaDecrypter {
@ -86,6 +92,8 @@ class MatrixEngine internal constructor(
}
}
override fun pushHandler() = matrixPushHandler.value
class Factory {
fun create(
@ -153,8 +161,9 @@ class MatrixEngine internal constructor(
}
val mediaDecrypter = unsafeLazy { MatrixMediaDecrypter(base64) }
val pushHandler = unsafeLazy { MatrixPushHandler(backgroundScheduler, credentialsStore, lazyMatrix.value.syncService(), roomStore) }
return MatrixEngine(directoryUseCase, lazyMatrix, timelineUseCase, sendMessageUseCase, mediaDecrypter)
return MatrixEngine(directoryUseCase, lazyMatrix, timelineUseCase, sendMessageUseCase, mediaDecrypter, pushHandler)
}
}

View File

@ -1,36 +1,34 @@
package app.dapk.st.notifications
package app.dapk.st.engine
import app.dapk.st.core.AppLogTag
import app.dapk.st.core.log
import app.dapk.st.matrix.common.CredentialsStore
import app.dapk.st.matrix.common.EventId
import app.dapk.st.matrix.common.JsonString
import app.dapk.st.matrix.common.RoomId
import app.dapk.st.matrix.message.BackgroundScheduler
import app.dapk.st.matrix.sync.RoomStore
import app.dapk.st.matrix.sync.SyncService
import app.dapk.st.push.PushHandler
import app.dapk.st.push.PushTokenPayload
import app.dapk.st.work.WorkScheduler
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
import kotlinx.serialization.json.Json
private var previousJob: Job? = null
@OptIn(DelicateCoroutinesApi::class)
class MatrixPushHandler(
private val workScheduler: WorkScheduler,
private val backgroundScheduler: BackgroundScheduler,
private val credentialsStore: CredentialsStore,
private val syncService: SyncService,
private val roomStore: RoomStore,
) : PushHandler {
override fun onNewToken(payload: PushTokenPayload) {
override fun onNewToken(payload: JsonString) {
log(AppLogTag.PUSH, "new push token received")
workScheduler.schedule(
WorkScheduler.WorkTask(
backgroundScheduler.schedule(
key = "2",
task = BackgroundScheduler.Task(
type = "push_token",
jobId = 2,
jsonPayload = Json.encodeToString(PushTokenPayload.serializer(), payload)
jsonPayload = payload
)
)
}
@ -82,4 +80,4 @@ class MatrixPushHandler(
}
private fun Flow<Unit>.startInstantly() = this.onStart { emit(Unit) }
}
}

View File

@ -1,9 +1,11 @@
package app.dapk.st.matrix.message
import app.dapk.st.matrix.common.JsonString
interface BackgroundScheduler {
fun schedule(key: String, task: Task)
data class Task(val type: String, val jsonPayload: String)
data class Task(val type: String, val jsonPayload: JsonString)
}

View File

@ -1,6 +1,7 @@
package app.dapk.st.matrix.message.internal
import app.dapk.st.matrix.MatrixTaskRunner
import app.dapk.st.matrix.common.JsonString
import app.dapk.st.matrix.common.RoomId
import app.dapk.st.matrix.http.MatrixHttpClient
import app.dapk.st.matrix.message.*
@ -69,13 +70,13 @@ internal class DefaultMessageService(
is MessageService.Message.TextMessage -> {
BackgroundScheduler.Task(
type = MATRIX_MESSAGE_TASK_TYPE,
Json.encodeToString(MessageService.Message.TextMessage.serializer(), this)
JsonString(Json.encodeToString(MessageService.Message.TextMessage.serializer(), this))
)
}
is MessageService.Message.ImageMessage -> BackgroundScheduler.Task(
type = MATRIX_IMAGE_MESSAGE_TASK_TYPE,
Json.encodeToString(MessageService.Message.ImageMessage.serializer(), this)
JsonString(Json.encodeToString(MessageService.Message.ImageMessage.serializer(), this))
)
}
}