Merge pull request #283 from vector-im/feature/check_pushrule_on_sync_only

Check Push rule on sync only + fix bad room name in notif
This commit is contained in:
Valere 2019-07-03 12:37:49 +02:00 committed by GitHub
commit 39070820be
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 62 additions and 80 deletions

View File

@ -35,7 +35,6 @@ import im.vector.matrix.android.internal.di.Unauthenticated
import im.vector.matrix.android.internal.network.AccessTokenInterceptor import im.vector.matrix.android.internal.network.AccessTokenInterceptor
import im.vector.matrix.android.internal.network.RetrofitFactory import im.vector.matrix.android.internal.network.RetrofitFactory
import im.vector.matrix.android.internal.session.group.GroupSummaryUpdater import im.vector.matrix.android.internal.session.group.GroupSummaryUpdater
import im.vector.matrix.android.internal.session.notification.BingRuleWatcher
import im.vector.matrix.android.internal.session.room.EventRelationsAggregationUpdater import im.vector.matrix.android.internal.session.room.EventRelationsAggregationUpdater
import im.vector.matrix.android.internal.session.room.prune.EventsPruner import im.vector.matrix.android.internal.session.room.prune.EventsPruner
import im.vector.matrix.android.internal.session.user.UserEntityUpdater import im.vector.matrix.android.internal.session.user.UserEntityUpdater
@ -129,10 +128,6 @@ internal abstract class SessionModule {
@IntoSet @IntoSet
abstract fun bindEventRelationsAggregationUpdater(groupSummaryUpdater: EventRelationsAggregationUpdater): LiveEntityObserver abstract fun bindEventRelationsAggregationUpdater(groupSummaryUpdater: EventRelationsAggregationUpdater): LiveEntityObserver


@Binds
@IntoSet
abstract fun bindBingRuleWatcher(bingRuleWatcher: BingRuleWatcher): LiveEntityObserver

@Binds @Binds
@IntoSet @IntoSet
abstract fun bindUserEntityUpdater(groupSummaryUpdater: UserEntityUpdater): LiveEntityObserver abstract fun bindUserEntityUpdater(groupSummaryUpdater: UserEntityUpdater): LiveEntityObserver

View File

@ -1,62 +0,0 @@
/*
* Copyright 2019 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 im.vector.matrix.android.internal.session.notification

import com.zhuinden.monarchy.Monarchy
import im.vector.matrix.android.api.auth.data.SessionParams
import im.vector.matrix.android.api.session.events.model.EventType
import im.vector.matrix.android.internal.database.RealmLiveEntityObserver
import im.vector.matrix.android.internal.database.mapper.asDomain
import im.vector.matrix.android.internal.database.model.EventEntity
import im.vector.matrix.android.internal.database.query.types
import im.vector.matrix.android.internal.session.sync.SyncTokenStore
import im.vector.matrix.android.internal.task.TaskExecutor
import im.vector.matrix.android.internal.task.configureWith
import javax.inject.Inject


internal class BingRuleWatcher @Inject constructor(monarchy: Monarchy,
private val task: ProcessEventForPushTask,
private val defaultPushRuleService: DefaultPushRuleService,
private val sessionParams: SessionParams,
private val tokenStore: SyncTokenStore,
private val taskExecutor: TaskExecutor) :
RealmLiveEntityObserver<EventEntity>(monarchy) {

override val query = Monarchy.Query<EventEntity> {

EventEntity.types(it, listOf(
EventType.MESSAGE,
EventType.REDACTION,
EventType.ENCRYPTED)
)

}

override fun processChanges(inserted: List<EventEntity>, updated: List<EventEntity>, deleted: List<EventEntity>) {
if (tokenStore.getLastToken() == null) return //no notif on initial sync
// TODO Use const for "global"
val rules = defaultPushRuleService.getPushRules("global")
inserted.map { it.asDomain() }
.filter { it.senderId != sessionParams.credentials.userId }
.let { events ->
task.configureWith(ProcessEventForPushTask.Params(events, rules))
.executeBy(taskExecutor)
}
}


}

View File

@ -20,15 +20,17 @@ import arrow.core.Try
import im.vector.matrix.android.api.auth.data.SessionParams import im.vector.matrix.android.api.auth.data.SessionParams
import im.vector.matrix.android.api.pushrules.rest.PushRule import im.vector.matrix.android.api.pushrules.rest.PushRule
import im.vector.matrix.android.api.session.events.model.Event import im.vector.matrix.android.api.session.events.model.Event
import im.vector.matrix.android.api.session.events.model.EventType
import im.vector.matrix.android.api.session.room.RoomService import im.vector.matrix.android.api.session.room.RoomService
import im.vector.matrix.android.internal.session.pushers.DefaultConditionResolver import im.vector.matrix.android.internal.session.pushers.DefaultConditionResolver
import im.vector.matrix.android.internal.session.sync.model.RoomsSyncResponse
import im.vector.matrix.android.internal.task.Task import im.vector.matrix.android.internal.task.Task
import timber.log.Timber import timber.log.Timber
import javax.inject.Inject import javax.inject.Inject


internal interface ProcessEventForPushTask : Task<ProcessEventForPushTask.Params, Unit> { internal interface ProcessEventForPushTask : Task<ProcessEventForPushTask.Params, Unit> {
data class Params( data class Params(
val events: List<Event>, val syncResponse: RoomsSyncResponse,
val rules: List<PushRule> val rules: List<PushRule>
) )
} }
@ -42,9 +44,35 @@ internal class DefaultProcessEventForPushTask @Inject constructor(


override suspend fun execute(params: ProcessEventForPushTask.Params): Try<Unit> { override suspend fun execute(params: ProcessEventForPushTask.Params): Try<Unit> {
return Try { return Try {
params.events.forEach { event -> val newJoinEvents = params.syncResponse.join
.map { entries ->
entries.value.timeline?.events?.map { it.copy(roomId = entries.key) }
}
.fold(emptyList<Event>(), { acc, next ->
acc + (next ?: emptyList())
})
val inviteEvents = params.syncResponse.invite
.map { entries ->
entries.value.inviteState?.events?.map { it.copy(roomId = entries.key) }
}
.fold(emptyList<Event>(), { acc, next ->
acc + (next ?: emptyList())
})
val allEvents = (newJoinEvents + inviteEvents).filter { event ->
when (event.type) {
EventType.MESSAGE,
EventType.REDACTION,
EventType.ENCRYPTED,
EventType.STATE_ROOM_MEMBER -> true
else -> false
}
}.filter {
it.senderId != sessionParams.credentials.userId
}
Timber.v("[PushRules] Found ${allEvents.size} out of ${(newJoinEvents + inviteEvents).size} to check for push rules with ${params.rules.size} rules")
allEvents.forEach { event ->
fulfilledBingRule(event, params.rules)?.let { fulfilledBingRule(event, params.rules)?.let {
Timber.v("Rule $it match for event ${event.eventId}") Timber.v("[PushRules] Rule $it match for event ${event.eventId}")
defaultPushRuleService.dispatchBing(event, it) defaultPushRuleService.dispatchBing(event, it)
} }
} }

View File

@ -73,7 +73,7 @@ internal class DefaultRoom @Inject constructor(override val roomId: String,


override fun roomSummary(fetchLastEvent: Boolean): RoomSummary? { override fun roomSummary(fetchLastEvent: Boolean): RoomSummary? {
return monarchy.fetchAllMappedSync( return monarchy.fetchAllMappedSync(
{ realm -> RoomSummaryEntity.where(realm).isNotEmpty(RoomSummaryEntityFields.DISPLAY_NAME) }, { realm -> RoomSummaryEntity.where(realm, roomId).isNotEmpty(RoomSummaryEntityFields.DISPLAY_NAME) },
{ roomSummaryMapper.map(it, fetchLastEvent) } { roomSummaryMapper.map(it, fetchLastEvent) }
).firstOrNull() ).firstOrNull()
} }

View File

@ -32,13 +32,13 @@ import im.vector.matrix.android.internal.database.model.RoomEntity
import im.vector.matrix.android.internal.database.query.find import im.vector.matrix.android.internal.database.query.find
import im.vector.matrix.android.internal.database.query.findLastLiveChunkFromRoom import im.vector.matrix.android.internal.database.query.findLastLiveChunkFromRoom
import im.vector.matrix.android.internal.database.query.where import im.vector.matrix.android.internal.database.query.where
import im.vector.matrix.android.internal.session.notification.DefaultPushRuleService
import im.vector.matrix.android.internal.session.notification.ProcessEventForPushTask
import im.vector.matrix.android.internal.session.room.RoomSummaryUpdater import im.vector.matrix.android.internal.session.room.RoomSummaryUpdater
import im.vector.matrix.android.internal.session.room.timeline.PaginationDirection import im.vector.matrix.android.internal.session.room.timeline.PaginationDirection
import im.vector.matrix.android.internal.session.sync.model.InvitedRoomSync import im.vector.matrix.android.internal.session.sync.model.*
import im.vector.matrix.android.internal.session.sync.model.RoomSync import im.vector.matrix.android.internal.task.TaskExecutor
import im.vector.matrix.android.internal.session.sync.model.RoomSyncAccountData import im.vector.matrix.android.internal.task.configureWith
import im.vector.matrix.android.internal.session.sync.model.RoomSyncEphemeral
import im.vector.matrix.android.internal.session.sync.model.RoomsSyncResponse
import io.realm.Realm import io.realm.Realm
import io.realm.kotlin.createObject import io.realm.kotlin.createObject
import timber.log.Timber import timber.log.Timber
@ -48,7 +48,11 @@ internal class RoomSyncHandler @Inject constructor(private val monarchy: Monarch
private val readReceiptHandler: ReadReceiptHandler, private val readReceiptHandler: ReadReceiptHandler,
private val roomSummaryUpdater: RoomSummaryUpdater, private val roomSummaryUpdater: RoomSummaryUpdater,
private val roomTagHandler: RoomTagHandler, private val roomTagHandler: RoomTagHandler,
private val cryptoManager: CryptoManager) { private val cryptoManager: CryptoManager,
private val tokenStore: SyncTokenStore,
private val pushRuleService: DefaultPushRuleService,
private val processForPushTask: ProcessEventForPushTask,
private val taskExecutor: TaskExecutor) {


sealed class HandlingStrategy { sealed class HandlingStrategy {
data class JOINED(val data: Map<String, RoomSync>) : HandlingStrategy() data class JOINED(val data: Map<String, RoomSync>) : HandlingStrategy()
@ -62,6 +66,23 @@ internal class RoomSyncHandler @Inject constructor(private val monarchy: Monarch
handleRoomSync(realm, HandlingStrategy.INVITED(roomsSyncResponse.invite)) handleRoomSync(realm, HandlingStrategy.INVITED(roomsSyncResponse.invite))
handleRoomSync(realm, HandlingStrategy.LEFT(roomsSyncResponse.leave)) handleRoomSync(realm, HandlingStrategy.LEFT(roomsSyncResponse.leave))
} }

//handle event for bing rule checks
checkPushRules(roomsSyncResponse)

}

private fun checkPushRules(roomsSyncResponse: RoomsSyncResponse) {
Timber.v("[PushRules] --> checkPushRules")
if (tokenStore.getLastToken() == null) {
Timber.v("[PushRules] <-- No push tule check on initial sync")
return
} //nothing on initial sync

val rules = pushRuleService.getPushRules("global")
processForPushTask.configureWith(ProcessEventForPushTask.Params(roomsSyncResponse, rules))
.executeBy(taskExecutor)
Timber.v("[PushRules] <-- Push task scheduled")
} }


// PRIVATE METHODS ***************************************************************************** // PRIVATE METHODS *****************************************************************************
@ -82,7 +103,7 @@ internal class RoomSyncHandler @Inject constructor(private val monarchy: Monarch
Timber.v("Handle join sync for room $roomId") Timber.v("Handle join sync for room $roomId")


val roomEntity = RoomEntity.where(realm, roomId).findFirst() val roomEntity = RoomEntity.where(realm, roomId).findFirst()
?: realm.createObject(roomId) ?: realm.createObject(roomId)


if (roomEntity.membership == Membership.INVITE) { if (roomEntity.membership == Membership.INVITE) {
roomEntity.chunks.deleteAllFromRealm() roomEntity.chunks.deleteAllFromRealm()
@ -153,7 +174,7 @@ internal class RoomSyncHandler @Inject constructor(private val monarchy: Monarch
InvitedRoomSync): RoomEntity { InvitedRoomSync): RoomEntity {
Timber.v("Handle invited sync for room $roomId") Timber.v("Handle invited sync for room $roomId")
val roomEntity = RoomEntity.where(realm, roomId).findFirst() val roomEntity = RoomEntity.where(realm, roomId).findFirst()
?: realm.createObject(roomId) ?: realm.createObject(roomId)
roomEntity.membership = Membership.INVITE roomEntity.membership = Membership.INVITE
if (roomSync.inviteState != null && roomSync.inviteState.events.isNotEmpty()) { if (roomSync.inviteState != null && roomSync.inviteState.events.isNotEmpty()) {
val chunkEntity = handleTimelineEvents(realm, roomId, roomSync.inviteState.events) val chunkEntity = handleTimelineEvents(realm, roomId, roomSync.inviteState.events)
@ -167,7 +188,7 @@ internal class RoomSyncHandler @Inject constructor(private val monarchy: Monarch
roomId: String, roomId: String,
roomSync: RoomSync): RoomEntity { roomSync: RoomSync): RoomEntity {
val roomEntity = RoomEntity.where(realm, roomId).findFirst() val roomEntity = RoomEntity.where(realm, roomId).findFirst()
?: realm.createObject(roomId) ?: realm.createObject(roomId)


roomEntity.membership = Membership.LEAVE roomEntity.membership = Membership.LEAVE
roomEntity.chunks.deleteAllFromRealm() roomEntity.chunks.deleteAllFromRealm()