Cleanup + Add per user store.
This commit is contained in:
parent
961d0ecdbc
commit
b9276aa60b
29 changed files with 351 additions and 202 deletions
|
|
@ -46,7 +46,7 @@ class LoggedInPresenter @Inject constructor(
|
||||||
override fun present(): LoggedInState {
|
override fun present(): LoggedInState {
|
||||||
LaunchedEffect(Unit) {
|
LaunchedEffect(Unit) {
|
||||||
// Ensure pusher is registered
|
// Ensure pusher is registered
|
||||||
pushService.registerPusher(matrixClient)
|
pushService.registerFirebasePusher(matrixClient)
|
||||||
}
|
}
|
||||||
|
|
||||||
val permissionsState = postNotificationPermissionsPresenter.present()
|
val permissionsState = postNotificationPermissionsPresenter.present()
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ interface PushService {
|
||||||
fun notificationStyleChanged()
|
fun notificationStyleChanged()
|
||||||
|
|
||||||
// Ensure pusher is registered
|
// Ensure pusher is registered
|
||||||
suspend fun registerPusher(matrixClient: MatrixClient)
|
suspend fun registerFirebasePusher(matrixClient: MatrixClient)
|
||||||
|
|
||||||
suspend fun testPush()
|
suspend fun testPush()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@
|
||||||
android:value="true" />
|
android:value="true" />
|
||||||
|
|
||||||
<service
|
<service
|
||||||
android:name="VectorFirebaseMessagingService"
|
android:name=".firebase.VectorFirebaseMessagingService"
|
||||||
android:exported="false">
|
android:exported="false">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="com.google.firebase.MESSAGING_EVENT" />
|
<action android:name="com.google.firebase.MESSAGING_EVENT" />
|
||||||
|
|
@ -35,7 +35,7 @@
|
||||||
|
|
||||||
<!-- UnifiedPush -->
|
<!-- UnifiedPush -->
|
||||||
<receiver
|
<receiver
|
||||||
android:name="VectorUnifiedPushMessagingReceiver"
|
android:name=".unifiedpush.VectorUnifiedPushMessagingReceiver"
|
||||||
android:enabled="true"
|
android:enabled="true"
|
||||||
android:exported="true">
|
android:exported="true">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
|
|
@ -48,7 +48,7 @@
|
||||||
</receiver>
|
</receiver>
|
||||||
|
|
||||||
<receiver
|
<receiver
|
||||||
android:name="KeepInternalDistributor"
|
android:name=".unifiedpush.KeepInternalDistributor"
|
||||||
android:enabled="true"
|
android:enabled="true"
|
||||||
android:exported="false">
|
android:exported="false">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
|
|
|
||||||
|
|
@ -1,49 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2021 New Vector Ltd
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package io.element.android.libraries.push.impl
|
|
||||||
|
|
||||||
import com.squareup.anvil.annotations.ContributesBinding
|
|
||||||
import io.element.android.libraries.di.AppScope
|
|
||||||
import javax.inject.Inject
|
|
||||||
|
|
||||||
// TODO Move away
|
|
||||||
/**
|
|
||||||
* This interface defines 2 flags so you can handle auto accept invites.
|
|
||||||
* At the moment we only have [CompileTimeAutoAcceptInvites] implementation.
|
|
||||||
*/
|
|
||||||
interface AutoAcceptInvites {
|
|
||||||
/**
|
|
||||||
* Enable auto-accept invites. It means, as soon as you got an invite from the sync, it will try to join it.
|
|
||||||
*/
|
|
||||||
val isEnabled: Boolean
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Hide invites from the UI (from notifications, notification count and room list). By default invites are hidden when [isEnabled] is true
|
|
||||||
*/
|
|
||||||
val hideInvites: Boolean
|
|
||||||
get() = isEnabled
|
|
||||||
}
|
|
||||||
|
|
||||||
fun AutoAcceptInvites.showInvites() = !hideInvites
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Simple compile time implementation of AutoAcceptInvites flags.
|
|
||||||
*/
|
|
||||||
@ContributesBinding(AppScope::class)
|
|
||||||
class CompileTimeAutoAcceptInvites @Inject constructor() : AutoAcceptInvites {
|
|
||||||
override val isEnabled = false
|
|
||||||
}
|
|
||||||
|
|
@ -20,13 +20,17 @@ import com.squareup.anvil.annotations.ContributesBinding
|
||||||
import io.element.android.libraries.di.AppScope
|
import io.element.android.libraries.di.AppScope
|
||||||
import io.element.android.libraries.matrix.api.MatrixClient
|
import io.element.android.libraries.matrix.api.MatrixClient
|
||||||
import io.element.android.libraries.push.api.PushService
|
import io.element.android.libraries.push.api.PushService
|
||||||
|
import io.element.android.libraries.push.impl.config.PushConfig
|
||||||
|
import io.element.android.libraries.push.impl.log.pushLoggerTag
|
||||||
import io.element.android.libraries.push.impl.notifications.NotificationDrawerManager
|
import io.element.android.libraries.push.impl.notifications.NotificationDrawerManager
|
||||||
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@ContributesBinding(AppScope::class)
|
@ContributesBinding(AppScope::class)
|
||||||
class DefaultPushService @Inject constructor(
|
class DefaultPushService @Inject constructor(
|
||||||
private val notificationDrawerManager: NotificationDrawerManager,
|
private val notificationDrawerManager: NotificationDrawerManager,
|
||||||
private val pusherManager: PushersManager,
|
private val pushersManager: PushersManager,
|
||||||
|
private val fcmHelper: FcmHelper,
|
||||||
) : PushService {
|
) : PushService {
|
||||||
override fun setCurrentRoom(roomId: String?) {
|
override fun setCurrentRoom(roomId: String?) {
|
||||||
notificationDrawerManager.setCurrentRoom(roomId)
|
notificationDrawerManager.setCurrentRoom(roomId)
|
||||||
|
|
@ -40,11 +44,14 @@ class DefaultPushService @Inject constructor(
|
||||||
notificationDrawerManager.notificationStyleChanged()
|
notificationDrawerManager.notificationStyleChanged()
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun registerPusher(matrixClient: MatrixClient) {
|
override suspend fun registerFirebasePusher(matrixClient: MatrixClient) {
|
||||||
pusherManager.registerPusher(matrixClient)
|
val pushKey = fcmHelper.getFcmToken() ?: return Unit.also {
|
||||||
|
Timber.tag(pushLoggerTag.value).w("Unable to register pusher, Firebase token is not known.")
|
||||||
|
}
|
||||||
|
pushersManager.registerPusher(matrixClient, pushKey, PushConfig.pusher_http_url)
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun testPush() {
|
override suspend fun testPush() {
|
||||||
pusherManager.testPush()
|
pushersManager.testPush()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,8 +23,12 @@ import io.element.android.libraries.matrix.api.pusher.SetHttpPusherData
|
||||||
import io.element.android.libraries.push.impl.clientsecret.PushClientSecret
|
import io.element.android.libraries.push.impl.clientsecret.PushClientSecret
|
||||||
import io.element.android.libraries.push.impl.config.PushConfig
|
import io.element.android.libraries.push.impl.config.PushConfig
|
||||||
import io.element.android.libraries.push.impl.pushgateway.PushGatewayNotifyRequest
|
import io.element.android.libraries.push.impl.pushgateway.PushGatewayNotifyRequest
|
||||||
|
import io.element.android.libraries.push.impl.userpushstore.UserPushStoreFactory
|
||||||
|
import io.element.android.libraries.push.impl.userpushstore.isFirebase
|
||||||
import io.element.android.libraries.sessionstorage.api.SessionStore
|
import io.element.android.libraries.sessionstorage.api.SessionStore
|
||||||
|
import io.element.android.libraries.sessionstorage.api.toUserList
|
||||||
import io.element.android.services.toolbox.api.appname.AppNameProvider
|
import io.element.android.services.toolbox.api.appname.AppNameProvider
|
||||||
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
internal const val DEFAULT_PUSHER_FILE_TAG = "mobile"
|
internal const val DEFAULT_PUSHER_FILE_TAG = "mobile"
|
||||||
|
|
@ -40,6 +44,7 @@ class PushersManager @Inject constructor(
|
||||||
private val pushClientSecret: PushClientSecret,
|
private val pushClientSecret: PushClientSecret,
|
||||||
private val sessionStore: SessionStore,
|
private val sessionStore: SessionStore,
|
||||||
private val matrixAuthenticationService: MatrixAuthenticationService,
|
private val matrixAuthenticationService: MatrixAuthenticationService,
|
||||||
|
private val userPushStoreFactory: UserPushStoreFactory,
|
||||||
private val fcmHelper: FcmHelper,
|
private val fcmHelper: FcmHelper,
|
||||||
) {
|
) {
|
||||||
suspend fun testPush() {
|
suspend fun testPush() {
|
||||||
|
|
@ -54,29 +59,54 @@ class PushersManager @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun enqueueRegisterPusherWithFcmKey(pushKey: String) {
|
suspend fun enqueueRegisterPusherWithFcmKey(pushKey: String) {
|
||||||
return enqueueRegisterPusher(pushKey, PushConfig.pusher_http_url)
|
// return onNewFirebaseToken(pushKey, PushConfig.pusher_http_url)
|
||||||
|
TODO()
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO Rename
|
suspend fun onNewUnifiedPushEndpoint(
|
||||||
suspend fun enqueueRegisterPusher(
|
|
||||||
pushKey: String,
|
pushKey: String,
|
||||||
gateway: String
|
gateway: String
|
||||||
) {
|
) {
|
||||||
|
TODO()
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun onNewFirebaseToken(firebaseToken: String) {
|
||||||
|
fcmHelper.storeFcmToken(firebaseToken)
|
||||||
|
|
||||||
// Register the pusher for all the sessions
|
// Register the pusher for all the sessions
|
||||||
sessionStore.getAllSessions().forEach { sessionData ->
|
sessionStore.getAllSessions().toUserList().forEach { userId ->
|
||||||
val client = matrixAuthenticationService.restoreSession(SessionId(sessionData.userId)).getOrNull()
|
val userDataStore = userPushStoreFactory.create(userId)
|
||||||
client ?: return@forEach
|
if (userDataStore.isFirebase()) {
|
||||||
client.pushersService().setHttpPusher(createHttpPusher(pushKey, gateway, sessionData.userId))
|
val client = matrixAuthenticationService.restoreSession(SessionId(userId)).getOrNull()
|
||||||
// TODO EAx Close sessions
|
client ?: return@forEach
|
||||||
|
registerPusher(client, firebaseToken, PushConfig.pusher_http_url)
|
||||||
|
// TODO EAx Close sessions
|
||||||
|
} else {
|
||||||
|
Timber.d("This session is not using Firebase pusher")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun registerPusher(matrixClient: MatrixClient) {
|
/**
|
||||||
val pushKey = fcmHelper.getFcmToken() ?: return
|
* Register a pusher to the server if not done yet.
|
||||||
// Register the pusher for the session
|
*/
|
||||||
matrixClient.pushersService().setHttpPusher(
|
suspend fun registerPusher(matrixClient: MatrixClient, pushKey: String, gateway: String) {
|
||||||
createHttpPusher(pushKey, PushConfig.pusher_http_url, matrixClient.sessionId.value)
|
val userDataStore = userPushStoreFactory.create(matrixClient.sessionId.value)
|
||||||
)
|
if (userDataStore.getCurrentRegisteredPushKey() == pushKey) {
|
||||||
|
Timber.d("Unnecessary to register again the same pusher")
|
||||||
|
} else {
|
||||||
|
// Register the pusher to the server
|
||||||
|
matrixClient.pushersService().setHttpPusher(
|
||||||
|
createHttpPusher(pushKey, gateway, matrixClient.sessionId.value)
|
||||||
|
).fold(
|
||||||
|
{
|
||||||
|
userDataStore.setCurrentRegisteredPushKey(pushKey)
|
||||||
|
},
|
||||||
|
{ throwable ->
|
||||||
|
Timber.e(throwable, "Unable to register the pusher")
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun createHttpPusher(
|
private suspend fun createHttpPusher(
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,6 @@ import org.unifiedpush.android.connector.UnifiedPush
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import java.net.URL
|
import java.net.URL
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import io.element.android.libraries.ui.strings.R as StringR
|
|
||||||
|
|
||||||
class UnifiedPushHelper @Inject constructor(
|
class UnifiedPushHelper @Inject constructor(
|
||||||
@ApplicationContext private val context: Context,
|
@ApplicationContext private val context: Context,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2022 New Vector Ltd
|
* Copyright (c) 2023 New Vector Ltd
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
@ -14,13 +14,16 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.element.android.libraries.push.impl
|
package io.element.android.libraries.push.impl.firebase
|
||||||
|
|
||||||
|
import io.element.android.libraries.push.impl.FcmHelper
|
||||||
|
import io.element.android.libraries.push.impl.PushersManager
|
||||||
|
import io.element.android.libraries.push.impl.UnifiedPushHelper
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class EnsureFcmTokenIsRetrievedUseCase @Inject constructor(
|
class EnsureFcmTokenIsRetrievedUseCase @Inject constructor(
|
||||||
private val unifiedPushHelper: UnifiedPushHelper,
|
private val unifiedPushHelper: UnifiedPushHelper,
|
||||||
private val fcmHelper: FcmHelper,
|
private val fcmHelper: FcmHelper,
|
||||||
// private val activeSessionHolder: ActiveSessionHolder,
|
// private val activeSessionHolder: ActiveSessionHolder,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
|
|
@ -0,0 +1,33 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022 New Vector Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.element.android.libraries.push.impl.firebase
|
||||||
|
|
||||||
|
import io.element.android.libraries.core.data.tryOrNull
|
||||||
|
import io.element.android.libraries.push.impl.push.PushData
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class FirebasePushParser @Inject constructor() {
|
||||||
|
fun parse(message: Map<String, String?>): PushData {
|
||||||
|
val pushDataFirebase = PushDataFirebase(
|
||||||
|
eventId = message["event_id"],
|
||||||
|
roomId = message["room_id"],
|
||||||
|
unread = message["unread"]?.let { tryOrNull { Integer.parseInt(it) } },
|
||||||
|
clientSecret = message["cs"],
|
||||||
|
)
|
||||||
|
return pushDataFirebase.toPushData()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2022 New Vector Ltd
|
* Copyright (c) 2023 New Vector Ltd
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
@ -14,9 +14,10 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.element.android.libraries.push.impl.model
|
package io.element.android.libraries.push.impl.firebase
|
||||||
|
|
||||||
import io.element.android.libraries.matrix.api.core.MatrixPatterns
|
import io.element.android.libraries.matrix.api.core.MatrixPatterns
|
||||||
|
import io.element.android.libraries.push.impl.push.PushData
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* In this case, the format is:
|
* In this case, the format is:
|
||||||
|
|
@ -31,14 +32,14 @@ import io.element.android.libraries.matrix.api.core.MatrixPatterns
|
||||||
* </pre>
|
* </pre>
|
||||||
* .
|
* .
|
||||||
*/
|
*/
|
||||||
data class PushDataFcm(
|
data class PushDataFirebase(
|
||||||
val eventId: String?,
|
val eventId: String?,
|
||||||
val roomId: String?,
|
val roomId: String?,
|
||||||
var unread: Int?,
|
var unread: Int?,
|
||||||
val clientSecret: String?
|
val clientSecret: String?
|
||||||
)
|
)
|
||||||
|
|
||||||
fun PushDataFcm.toPushData() = PushData(
|
fun PushDataFirebase.toPushData() = PushData(
|
||||||
eventId = eventId?.takeIf { MatrixPatterns.isEventId(it) },
|
eventId = eventId?.takeIf { MatrixPatterns.isEventId(it) },
|
||||||
roomId = roomId?.takeIf { MatrixPatterns.isRoomId(it) },
|
roomId = roomId?.takeIf { MatrixPatterns.isRoomId(it) },
|
||||||
unread = unread,
|
unread = unread,
|
||||||
|
|
@ -14,58 +14,50 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.element.android.libraries.push.impl
|
package io.element.android.libraries.push.impl.firebase
|
||||||
|
|
||||||
import com.google.firebase.messaging.FirebaseMessagingService
|
import com.google.firebase.messaging.FirebaseMessagingService
|
||||||
import com.google.firebase.messaging.RemoteMessage
|
import com.google.firebase.messaging.RemoteMessage
|
||||||
import io.element.android.libraries.architecture.bindings
|
import io.element.android.libraries.architecture.bindings
|
||||||
import io.element.android.libraries.core.log.logger.LoggerTag
|
import io.element.android.libraries.core.log.logger.LoggerTag
|
||||||
import io.element.android.libraries.push.api.store.PushDataStore
|
import io.element.android.libraries.push.impl.PushersManager
|
||||||
import io.element.android.libraries.push.impl.config.PushConfig
|
import io.element.android.libraries.push.impl.push.PushHandler
|
||||||
import io.element.android.libraries.push.impl.di.FirebaseMessagingServiceBindings
|
import io.element.android.libraries.push.impl.log.pushLoggerTag
|
||||||
import io.element.android.libraries.push.impl.parser.PushParser
|
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.SupervisorJob
|
import kotlinx.coroutines.SupervisorJob
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
private val loggerTag = LoggerTag("Push", LoggerTag.SYNC)
|
private val loggerTag = LoggerTag("Firebase", pushLoggerTag)
|
||||||
|
|
||||||
class VectorFirebaseMessagingService : FirebaseMessagingService() {
|
class VectorFirebaseMessagingService : FirebaseMessagingService() {
|
||||||
@Inject lateinit var fcmHelper: FcmHelper
|
|
||||||
@Inject lateinit var pushDataStore: PushDataStore
|
|
||||||
// @Inject lateinit var activeSessionHolder: ActiveSessionHolder
|
|
||||||
@Inject lateinit var pushersManager: PushersManager
|
@Inject lateinit var pushersManager: PushersManager
|
||||||
@Inject lateinit var pushParser: PushParser
|
|
||||||
@Inject lateinit var vectorPushHandler: VectorPushHandler
|
@Inject
|
||||||
@Inject lateinit var unifiedPushHelper: UnifiedPushHelper
|
lateinit var pushParser: FirebasePushParser
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
lateinit var pushHandler: PushHandler
|
||||||
|
|
||||||
private val coroutineScope = CoroutineScope(SupervisorJob())
|
private val coroutineScope = CoroutineScope(SupervisorJob())
|
||||||
|
|
||||||
override fun onCreate() {
|
override fun onCreate() {
|
||||||
super.onCreate()
|
super.onCreate()
|
||||||
applicationContext.bindings<FirebaseMessagingServiceBindings>().inject(this)
|
applicationContext.bindings<VectorFirebaseMessagingServiceBindings>().inject(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onNewToken(token: String) {
|
override fun onNewToken(token: String) {
|
||||||
Timber.tag(loggerTag.value).d("New Firebase token")
|
Timber.tag(loggerTag.value).d("New Firebase token")
|
||||||
fcmHelper.storeFcmToken(token)
|
coroutineScope.launch {
|
||||||
if (
|
pushersManager.onNewFirebaseToken(token)
|
||||||
// pushDataStore.areNotificationEnabledForDevice() &&
|
|
||||||
// TODO EAx activeSessionHolder.hasActiveSession() &&
|
|
||||||
unifiedPushHelper.isEmbeddedDistributor()
|
|
||||||
) {
|
|
||||||
coroutineScope.launch {
|
|
||||||
pushersManager.enqueueRegisterPusher(token, PushConfig.pusher_http_url)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onMessageReceived(message: RemoteMessage) {
|
override fun onMessageReceived(message: RemoteMessage) {
|
||||||
Timber.tag(loggerTag.value).d("New Firebase message")
|
Timber.tag(loggerTag.value).d("New Firebase message")
|
||||||
pushParser.parsePushDataFcm(message.data).let {
|
pushParser.parse(message.data).let {
|
||||||
vectorPushHandler.handle(it)
|
pushHandler.handle(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -14,13 +14,12 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.element.android.libraries.push.impl.di
|
package io.element.android.libraries.push.impl.firebase
|
||||||
|
|
||||||
import com.squareup.anvil.annotations.ContributesTo
|
import com.squareup.anvil.annotations.ContributesTo
|
||||||
import io.element.android.libraries.di.AppScope
|
import io.element.android.libraries.di.AppScope
|
||||||
import io.element.android.libraries.push.impl.VectorFirebaseMessagingService
|
|
||||||
|
|
||||||
@ContributesTo(AppScope::class)
|
@ContributesTo(AppScope::class)
|
||||||
interface FirebaseMessagingServiceBindings {
|
interface VectorFirebaseMessagingServiceBindings {
|
||||||
fun inject(service: VectorFirebaseMessagingService)
|
fun inject(service: VectorFirebaseMessagingService)
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023 New Vector Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.element.android.libraries.push.impl.log
|
||||||
|
|
||||||
|
import io.element.android.libraries.core.log.logger.LoggerTag
|
||||||
|
|
||||||
|
internal val pushLoggerTag = LoggerTag("Push")
|
||||||
|
|
@ -16,12 +16,7 @@
|
||||||
|
|
||||||
package io.element.android.libraries.push.impl.notifications
|
package io.element.android.libraries.push.impl.notifications
|
||||||
|
|
||||||
import io.element.android.libraries.push.impl.AutoAcceptInvites
|
import io.element.android.libraries.push.impl.notifications.model.*
|
||||||
import io.element.android.libraries.push.impl.notifications.model.InviteNotifiableEvent
|
|
||||||
import io.element.android.libraries.push.impl.notifications.model.NotifiableEvent
|
|
||||||
import io.element.android.libraries.push.impl.notifications.model.NotifiableMessageEvent
|
|
||||||
import io.element.android.libraries.push.impl.notifications.model.SimpleNotifiableEvent
|
|
||||||
import io.element.android.libraries.push.impl.notifications.model.shouldIgnoreMessageEventInRoom
|
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
|
@ -29,13 +24,12 @@ private typealias ProcessedEvents = List<ProcessedEvent<NotifiableEvent>>
|
||||||
|
|
||||||
class NotifiableEventProcessor @Inject constructor(
|
class NotifiableEventProcessor @Inject constructor(
|
||||||
private val outdatedDetector: OutdatedEventDetector,
|
private val outdatedDetector: OutdatedEventDetector,
|
||||||
private val autoAcceptInvites: AutoAcceptInvites
|
|
||||||
) {
|
) {
|
||||||
|
|
||||||
fun process(queuedEvents: List<NotifiableEvent>, currentRoomId: String?, currentThreadId: String?, renderedEvents: ProcessedEvents): ProcessedEvents {
|
fun process(queuedEvents: List<NotifiableEvent>, currentRoomId: String?, currentThreadId: String?, renderedEvents: ProcessedEvents): ProcessedEvents {
|
||||||
val processedEvents = queuedEvents.map {
|
val processedEvents = queuedEvents.map {
|
||||||
val type = when (it) {
|
val type = when (it) {
|
||||||
is InviteNotifiableEvent -> if (autoAcceptInvites.hideInvites) ProcessedEvent.Type.REMOVE else ProcessedEvent.Type.KEEP
|
is InviteNotifiableEvent -> ProcessedEvent.Type.KEEP
|
||||||
is NotifiableMessageEvent -> when {
|
is NotifiableMessageEvent -> when {
|
||||||
it.shouldIgnoreMessageEventInRoom(currentRoomId, currentThreadId) -> {
|
it.shouldIgnoreMessageEventInRoom(currentRoomId, currentThreadId) -> {
|
||||||
ProcessedEvent.Type.REMOVE
|
ProcessedEvent.Type.REMOVE
|
||||||
|
|
|
||||||
|
|
@ -1,57 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2022 New Vector Ltd
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package io.element.android.libraries.push.impl.parser
|
|
||||||
|
|
||||||
import io.element.android.libraries.core.data.tryOrNull
|
|
||||||
import io.element.android.libraries.push.impl.model.PushData
|
|
||||||
import io.element.android.libraries.push.impl.model.PushDataFcm
|
|
||||||
import io.element.android.libraries.push.impl.model.PushDataUnifiedPush
|
|
||||||
import io.element.android.libraries.push.impl.model.toPushData
|
|
||||||
import kotlinx.serialization.decodeFromString
|
|
||||||
import kotlinx.serialization.json.Json
|
|
||||||
import javax.inject.Inject
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parse the received data from Push. Json format are different depending on the source.
|
|
||||||
*
|
|
||||||
* Notifications received by FCM are formatted by the matrix gateway [1]. The data send to FCM is the content
|
|
||||||
* of the "notification" attribute of the json sent to the gateway [2][3].
|
|
||||||
* On the other side, with UnifiedPush, the content of the message received is the content posted to the push
|
|
||||||
* gateway endpoint [3].
|
|
||||||
*
|
|
||||||
* *Note*: If we want to get the same content with FCM and unifiedpush, we can do a new sygnal pusher [4].
|
|
||||||
*
|
|
||||||
* [1] https://github.com/matrix-org/sygnal/blob/main/sygnal/gcmpushkin.py
|
|
||||||
* [2] https://github.com/matrix-org/sygnal/blob/main/sygnal/gcmpushkin.py#L366
|
|
||||||
* [3] https://spec.matrix.org/latest/push-gateway-api/
|
|
||||||
* [4] https://github.com/p1gp1g/sygnal/blob/unifiedpush/sygnal/upfcmpushkin.py (Not tested for a while)
|
|
||||||
*/
|
|
||||||
class PushParser @Inject constructor() {
|
|
||||||
fun parsePushDataUnifiedPush(message: ByteArray): PushData? {
|
|
||||||
return tryOrNull { Json.decodeFromString<PushDataUnifiedPush>(String(message)) }?.toPushData()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun parsePushDataFcm(message: Map<String, String?>): PushData {
|
|
||||||
val pushDataFcm = PushDataFcm(
|
|
||||||
eventId = message["event_id"],
|
|
||||||
roomId = message["room_id"],
|
|
||||||
unread = message["unread"]?.let { tryOrNull { Integer.parseInt(it) } },
|
|
||||||
clientSecret = message["cs"],
|
|
||||||
)
|
|
||||||
return pushDataFcm.toPushData()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.element.android.libraries.push.impl.model
|
package io.element.android.libraries.push.impl.push
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represent parsed data that the app has received from a Push content.
|
* Represent parsed data that the app has received from a Push content.
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2022 New Vector Ltd
|
* Copyright (c) 2023 New Vector Ltd
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.element.android.libraries.push.impl
|
package io.element.android.libraries.push.impl.push
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
|
|
@ -30,19 +30,24 @@ import io.element.android.libraries.di.ApplicationContext
|
||||||
import io.element.android.libraries.matrix.api.auth.MatrixAuthenticationService
|
import io.element.android.libraries.matrix.api.auth.MatrixAuthenticationService
|
||||||
import io.element.android.libraries.matrix.api.core.SessionId
|
import io.element.android.libraries.matrix.api.core.SessionId
|
||||||
import io.element.android.libraries.push.api.store.PushDataStore
|
import io.element.android.libraries.push.api.store.PushDataStore
|
||||||
|
import io.element.android.libraries.push.impl.PushersManager
|
||||||
import io.element.android.libraries.push.impl.clientsecret.PushClientSecret
|
import io.element.android.libraries.push.impl.clientsecret.PushClientSecret
|
||||||
import io.element.android.libraries.push.impl.model.PushData
|
|
||||||
import io.element.android.libraries.push.impl.notifications.NotifiableEventResolver
|
import io.element.android.libraries.push.impl.notifications.NotifiableEventResolver
|
||||||
import io.element.android.libraries.push.impl.notifications.NotificationActionIds
|
import io.element.android.libraries.push.impl.notifications.NotificationActionIds
|
||||||
import io.element.android.libraries.push.impl.notifications.NotificationDrawerManager
|
import io.element.android.libraries.push.impl.notifications.NotificationDrawerManager
|
||||||
|
import io.element.android.libraries.push.impl.log.pushLoggerTag
|
||||||
import io.element.android.libraries.push.impl.store.DefaultPushDataStore
|
import io.element.android.libraries.push.impl.store.DefaultPushDataStore
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.SupervisorJob
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.runBlocking
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
private val loggerTag = LoggerTag("Push", LoggerTag.SYNC)
|
private val loggerTag = LoggerTag("Push", pushLoggerTag)
|
||||||
|
|
||||||
class VectorPushHandler @Inject constructor(
|
class PushHandler @Inject constructor(
|
||||||
private val notificationDrawerManager: NotificationDrawerManager,
|
private val notificationDrawerManager: NotificationDrawerManager,
|
||||||
private val notifiableEventResolver: NotifiableEventResolver,
|
private val notifiableEventResolver: NotifiableEventResolver,
|
||||||
// private val activeSessionHolder: ActiveSessionHolder,
|
// private val activeSessionHolder: ActiveSessionHolder,
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2021 New Vector Ltd
|
* Copyright (c) 2023 New Vector Ltd
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.element.android.libraries.push.impl
|
package io.element.android.libraries.push.impl.unifiedpush
|
||||||
|
|
||||||
import com.squareup.anvil.annotations.ContributesBinding
|
import com.squareup.anvil.annotations.ContributesBinding
|
||||||
import io.element.android.libraries.di.AppScope
|
import io.element.android.libraries.di.AppScope
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.element.android.libraries.push.impl
|
package io.element.android.libraries.push.impl.unifiedpush
|
||||||
|
|
||||||
import android.content.BroadcastReceiver
|
import android.content.BroadcastReceiver
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2022 New Vector Ltd
|
* Copyright (c) 2023 New Vector Ltd
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
@ -14,9 +14,10 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.element.android.libraries.push.impl.model
|
package io.element.android.libraries.push.impl.unifiedpush
|
||||||
|
|
||||||
import io.element.android.libraries.matrix.api.core.MatrixPatterns
|
import io.element.android.libraries.matrix.api.core.MatrixPatterns
|
||||||
|
import io.element.android.libraries.push.impl.push.PushData
|
||||||
import kotlinx.serialization.SerialName
|
import kotlinx.serialization.SerialName
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2022 New Vector Ltd
|
* Copyright (c) 2023 New Vector Ltd
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.element.android.libraries.push.impl
|
package io.element.android.libraries.push.impl.unifiedpush
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import io.element.android.libraries.di.ApplicationContext
|
import io.element.android.libraries.di.ApplicationContext
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022 New Vector Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.element.android.libraries.push.impl.unifiedpush
|
||||||
|
|
||||||
|
import io.element.android.libraries.core.data.tryOrNull
|
||||||
|
import io.element.android.libraries.push.impl.push.PushData
|
||||||
|
import kotlinx.serialization.decodeFromString
|
||||||
|
import kotlinx.serialization.json.Json
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class UnifiedPushParser @Inject constructor() {
|
||||||
|
fun parse(message: ByteArray): PushData? {
|
||||||
|
return tryOrNull { Json.decodeFromString<PushDataUnifiedPush>(String(message)) }?.toPushData()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2022 New Vector Ltd
|
* Copyright (c) 2023 New Vector Ltd
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
@ -14,12 +14,15 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.element.android.libraries.push.impl
|
package io.element.android.libraries.push.impl.unifiedpush
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import io.element.android.libraries.di.ApplicationContext
|
import io.element.android.libraries.di.ApplicationContext
|
||||||
import io.element.android.libraries.push.api.model.BackgroundSyncMode
|
import io.element.android.libraries.push.api.model.BackgroundSyncMode
|
||||||
import io.element.android.libraries.push.api.store.PushDataStore
|
import io.element.android.libraries.push.api.store.PushDataStore
|
||||||
|
import io.element.android.libraries.push.impl.PushersManager
|
||||||
|
import io.element.android.libraries.push.impl.UnifiedPushHelper
|
||||||
|
import io.element.android.libraries.push.impl.UnifiedPushStore
|
||||||
import org.unifiedpush.android.connector.UnifiedPush
|
import org.unifiedpush.android.connector.UnifiedPush
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2022 New Vector Ltd
|
* Copyright (c) 2023 New Vector Ltd
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
@ -14,18 +14,18 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.element.android.libraries.push.impl
|
package io.element.android.libraries.push.impl.unifiedpush
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import io.element.android.libraries.architecture.bindings
|
import io.element.android.libraries.architecture.bindings
|
||||||
|
|
||||||
import io.element.android.libraries.core.log.logger.LoggerTag
|
import io.element.android.libraries.core.log.logger.LoggerTag
|
||||||
import io.element.android.libraries.push.api.model.BackgroundSyncMode
|
import io.element.android.libraries.push.api.model.BackgroundSyncMode
|
||||||
import io.element.android.libraries.push.api.store.PushDataStore
|
import io.element.android.libraries.push.api.store.PushDataStore
|
||||||
import io.element.android.libraries.push.impl.di.VectorUnifiedPushMessagingReceiverBindings
|
import io.element.android.libraries.push.impl.*
|
||||||
import io.element.android.libraries.push.impl.parser.PushParser
|
import io.element.android.libraries.push.impl.log.pushLoggerTag
|
||||||
|
import io.element.android.libraries.push.impl.push.PushHandler
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.SupervisorJob
|
import kotlinx.coroutines.SupervisorJob
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
@ -34,15 +34,15 @@ import org.unifiedpush.android.connector.MessagingReceiver
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
private val loggerTag = LoggerTag("Push", LoggerTag.SYNC)
|
private val loggerTag = LoggerTag("Unified", pushLoggerTag)
|
||||||
|
|
||||||
class VectorUnifiedPushMessagingReceiver : MessagingReceiver() {
|
class VectorUnifiedPushMessagingReceiver : MessagingReceiver() {
|
||||||
@Inject lateinit var pushersManager: PushersManager
|
@Inject lateinit var pushersManager: PushersManager
|
||||||
@Inject lateinit var pushParser: PushParser
|
@Inject lateinit var pushParser: UnifiedPushParser
|
||||||
|
|
||||||
//@Inject lateinit var activeSessionHolder: ActiveSessionHolder
|
//@Inject lateinit var activeSessionHolder: ActiveSessionHolder
|
||||||
@Inject lateinit var pushDataStore: PushDataStore
|
@Inject lateinit var pushDataStore: PushDataStore
|
||||||
@Inject lateinit var vectorPushHandler: VectorPushHandler
|
@Inject lateinit var pushHandler: PushHandler
|
||||||
@Inject lateinit var guardServiceStarter: GuardServiceStarter
|
@Inject lateinit var guardServiceStarter: GuardServiceStarter
|
||||||
@Inject lateinit var unifiedPushStore: UnifiedPushStore
|
@Inject lateinit var unifiedPushStore: UnifiedPushStore
|
||||||
@Inject lateinit var unifiedPushHelper: UnifiedPushHelper
|
@Inject lateinit var unifiedPushHelper: UnifiedPushHelper
|
||||||
|
|
@ -64,8 +64,8 @@ class VectorUnifiedPushMessagingReceiver : MessagingReceiver() {
|
||||||
*/
|
*/
|
||||||
override fun onMessage(context: Context, message: ByteArray, instance: String) {
|
override fun onMessage(context: Context, message: ByteArray, instance: String) {
|
||||||
Timber.tag(loggerTag.value).d("New message")
|
Timber.tag(loggerTag.value).d("New message")
|
||||||
pushParser.parsePushDataUnifiedPush(message)?.let {
|
pushParser.parse(message)?.let {
|
||||||
vectorPushHandler.handle(it)
|
pushHandler.handle(it)
|
||||||
} ?: run {
|
} ?: run {
|
||||||
Timber.tag(loggerTag.value).w("Invalid received data Json format")
|
Timber.tag(loggerTag.value).w("Invalid received data Json format")
|
||||||
}
|
}
|
||||||
|
|
@ -82,7 +82,7 @@ class VectorUnifiedPushMessagingReceiver : MessagingReceiver() {
|
||||||
unifiedPushHelper.storeCustomOrDefaultGateway(endpoint) {
|
unifiedPushHelper.storeCustomOrDefaultGateway(endpoint) {
|
||||||
unifiedPushHelper.getPushGateway()?.let {
|
unifiedPushHelper.getPushGateway()?.let {
|
||||||
coroutineScope.launch {
|
coroutineScope.launch {
|
||||||
pushersManager.enqueueRegisterPusher(endpoint, it)
|
pushersManager.onNewUnifiedPushEndpoint(endpoint, it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -14,11 +14,10 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.element.android.libraries.push.impl.di
|
package io.element.android.libraries.push.impl.unifiedpush
|
||||||
|
|
||||||
import com.squareup.anvil.annotations.ContributesTo
|
import com.squareup.anvil.annotations.ContributesTo
|
||||||
import io.element.android.libraries.di.AppScope
|
import io.element.android.libraries.di.AppScope
|
||||||
import io.element.android.libraries.push.impl.VectorUnifiedPushMessagingReceiver
|
|
||||||
|
|
||||||
@ContributesTo(AppScope::class)
|
@ContributesTo(AppScope::class)
|
||||||
interface VectorUnifiedPushMessagingReceiverBindings {
|
interface VectorUnifiedPushMessagingReceiverBindings {
|
||||||
|
|
@ -0,0 +1,40 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023 New Vector Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.element.android.libraries.push.impl.userpushstore
|
||||||
|
|
||||||
|
const val NOTIFICATION_METHOD_FIREBASE = "NOTIFICATION_METHOD_FIREBASE"
|
||||||
|
const val NOTIFICATION_METHOD_UNIFIEDPUSH = "NOTIFICATION_METHOD_UNIFIEDPUSH"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store data related to push about a user.
|
||||||
|
*/
|
||||||
|
interface UserPushStore {
|
||||||
|
/**
|
||||||
|
* NOTIFICATION_METHOD_FIREBASE or NOTIFICATION_METHOD_UNIFIEDPUSH
|
||||||
|
*/
|
||||||
|
suspend fun getNotificationMethod(): String
|
||||||
|
|
||||||
|
suspend fun setNotificationMethod(value: String)
|
||||||
|
|
||||||
|
suspend fun getCurrentRegisteredPushKey(): String?
|
||||||
|
|
||||||
|
suspend fun setCurrentRegisteredPushKey(value: String)
|
||||||
|
|
||||||
|
suspend fun reset()
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun UserPushStore.isFirebase(): Boolean = getNotificationMethod() == NOTIFICATION_METHOD_FIREBASE
|
||||||
|
|
@ -0,0 +1,63 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023 New Vector Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.element.android.libraries.push.impl.userpushstore
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import androidx.datastore.core.DataStore
|
||||||
|
import androidx.datastore.preferences.core.Preferences
|
||||||
|
import androidx.datastore.preferences.core.edit
|
||||||
|
import androidx.datastore.preferences.core.stringPreferencesKey
|
||||||
|
import androidx.datastore.preferences.preferencesDataStore
|
||||||
|
import kotlinx.coroutines.flow.first
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store data related to push about a user.
|
||||||
|
*/
|
||||||
|
class UserPushStoreDataStore(
|
||||||
|
private val context: Context,
|
||||||
|
userId: String,
|
||||||
|
) : UserPushStore {
|
||||||
|
private val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "push_store_$userId")
|
||||||
|
private val notificationMethod = stringPreferencesKey("notificationMethod")
|
||||||
|
private val currentPushKey = stringPreferencesKey("currentPushKey")
|
||||||
|
|
||||||
|
override suspend fun getNotificationMethod(): String {
|
||||||
|
return context.dataStore.data.first()[notificationMethod] ?: NOTIFICATION_METHOD_FIREBASE
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun setNotificationMethod(value: String) {
|
||||||
|
context.dataStore.edit {
|
||||||
|
it[notificationMethod] = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun getCurrentRegisteredPushKey(): String? {
|
||||||
|
return context.dataStore.data.first()[currentPushKey]
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun setCurrentRegisteredPushKey(value: String) {
|
||||||
|
context.dataStore.edit {
|
||||||
|
it[currentPushKey] = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun reset() {
|
||||||
|
context.dataStore.edit {
|
||||||
|
it.clear()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023 New Vector Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.element.android.libraries.push.impl.userpushstore
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import io.element.android.libraries.di.ApplicationContext
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class UserPushStoreFactory @Inject constructor(
|
||||||
|
@ApplicationContext private val context: Context,
|
||||||
|
) {
|
||||||
|
fun create(userId: String): UserPushStore {
|
||||||
|
return UserPushStoreDataStore(
|
||||||
|
context = context,
|
||||||
|
userId = userId
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -26,3 +26,7 @@ interface SessionStore {
|
||||||
suspend fun getLatestSession(): SessionData?
|
suspend fun getLatestSession(): SessionData?
|
||||||
suspend fun removeSession(sessionId: String)
|
suspend fun removeSession(sessionId: String)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun List<SessionData>.toUserList(): List<String> {
|
||||||
|
return map { it.userId }
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue