sync filter params moved to matrix config

This commit is contained in:
NIkita Fedrunov 2022-12-23 11:17:21 +01:00
parent 882c58efdd
commit d20121603a
23 changed files with 21 additions and 289 deletions

1
changelog.d/filter.sdk Normal file
View File

@ -0,0 +1 @@
[Sync] Sync Filter params are moved to MatrixConfiguration and will not be stored in session realm to avoid bug when session cache is cleared

View File

@ -50,7 +50,6 @@ import org.matrix.android.sdk.api.session.room.send.SendState
import org.matrix.android.sdk.api.session.room.timeline.Timeline
import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent
import org.matrix.android.sdk.api.session.room.timeline.TimelineSettings
import org.matrix.android.sdk.api.session.sync.filter.SyncFilterBuilder
import timber.log.Timber
import java.util.UUID
import java.util.concurrent.CountDownLatch
@ -347,10 +346,6 @@ class CommonTestHelper internal constructor(context: Context, val cryptoConfig:
assertTrue(registrationResult is RegistrationResult.Success)
val session = (registrationResult as RegistrationResult.Success).session
session.open()
session.filterService().setSyncFilter(
SyncFilterBuilder()
.lazyLoadMembersForStateEvents(true)
)
if (sessionTestParams.withInitialSync) {
syncSession(session, 120_000)
}

View File

@ -16,9 +16,13 @@
package org.matrix.android.sdk.api
import org.matrix.android.sdk.api.session.sync.filter.SyncFilterParams
data class SyncConfig(
/**
* Time to keep sync connection alive for before making another request in milliseconds.
*/
val longPollTimeout: Long = 30_000L,
val syncFilterParams: SyncFilterParams = SyncFilterParams()
)

View File

@ -50,7 +50,6 @@ import org.matrix.android.sdk.api.session.securestorage.SharedSecretStorageServi
import org.matrix.android.sdk.api.session.signout.SignOutService
import org.matrix.android.sdk.api.session.space.SpaceService
import org.matrix.android.sdk.api.session.statistics.StatisticsListener
import org.matrix.android.sdk.api.session.sync.FilterService
import org.matrix.android.sdk.api.session.sync.SyncService
import org.matrix.android.sdk.api.session.terms.TermsService
import org.matrix.android.sdk.api.session.thirdparty.ThirdPartyService
@ -163,11 +162,6 @@ interface Session {
*/
fun signOutService(): SignOutService
/**
* Returns the FilterService associated with the session.
*/
fun filterService(): FilterService
/**
* Returns the PushRuleService associated with the session.
*/

View File

@ -1,27 +0,0 @@
/*
* Copyright 2020 The Matrix.org Foundation C.I.C.
*
* 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 org.matrix.android.sdk.api.session.sync
import org.matrix.android.sdk.api.session.sync.filter.SyncFilterBuilder
interface FilterService {
/**
* Configure the filter for the sync.
*/
suspend fun setSyncFilter(filterBuilder: SyncFilterBuilder)
}

View File

@ -14,9 +14,9 @@
* limitations under the License.
*/
package org.matrix.android.sdk.internal.sync.filter
package org.matrix.android.sdk.api.session.sync.filter
internal data class SyncFilterParams(
data class SyncFilterParams(
val lazyLoadMembersForStateEvents: Boolean? = null,
val lazyLoadMembersForMessageEvents: Boolean? = null,
val useThreadNotifications: Boolean? = null,

View File

@ -1,61 +0,0 @@
/*
* Copyright 2022 The Matrix.org Foundation C.I.C.
*
* 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 org.matrix.android.sdk.internal.database.mapper
import io.realm.RealmList
import org.matrix.android.sdk.internal.database.model.SyncFilterParamsEntity
import org.matrix.android.sdk.internal.sync.filter.SyncFilterParams
import javax.inject.Inject
internal class FilterParamsMapper @Inject constructor() {
fun map(entity: SyncFilterParamsEntity): SyncFilterParams {
val eventTypes = if (entity.listOfSupportedEventTypesHasBeenSet) {
entity.listOfSupportedEventTypes?.toList()
} else {
null
}
val stateEventTypes = if (entity.listOfSupportedStateEventTypesHasBeenSet) {
entity.listOfSupportedStateEventTypes?.toList()
} else {
null
}
return SyncFilterParams(
useThreadNotifications = entity.useThreadNotifications,
lazyLoadMembersForMessageEvents = entity.lazyLoadMembersForMessageEvents,
lazyLoadMembersForStateEvents = entity.lazyLoadMembersForStateEvents,
listOfSupportedEventTypes = eventTypes,
listOfSupportedStateEventTypes = stateEventTypes,
)
}
fun map(params: SyncFilterParams): SyncFilterParamsEntity {
return SyncFilterParamsEntity(
useThreadNotifications = params.useThreadNotifications,
lazyLoadMembersForMessageEvents = params.lazyLoadMembersForMessageEvents,
lazyLoadMembersForStateEvents = params.lazyLoadMembersForStateEvents,
listOfSupportedEventTypes = params.listOfSupportedEventTypes.toRealmList(),
listOfSupportedEventTypesHasBeenSet = params.listOfSupportedEventTypes != null,
listOfSupportedStateEventTypes = params.listOfSupportedStateEventTypes.toRealmList(),
listOfSupportedStateEventTypesHasBeenSet = params.listOfSupportedStateEventTypes != null,
)
}
private fun List<String>?.toRealmList(): RealmList<String>? {
return this?.toTypedArray()?.let { RealmList(*it) }
}
}

View File

@ -72,7 +72,6 @@ import org.matrix.android.sdk.internal.database.model.threads.ThreadSummaryEntit
SpaceParentSummaryEntity::class,
UserPresenceEntity::class,
ThreadSummaryEntity::class,
SyncFilterParamsEntity::class,
ThreadListPageEntity::class
]
)

View File

@ -57,7 +57,6 @@ import org.matrix.android.sdk.api.session.search.SearchService
import org.matrix.android.sdk.api.session.securestorage.SharedSecretStorageService
import org.matrix.android.sdk.api.session.signout.SignOutService
import org.matrix.android.sdk.api.session.space.SpaceService
import org.matrix.android.sdk.api.session.sync.FilterService
import org.matrix.android.sdk.api.session.sync.SyncService
import org.matrix.android.sdk.api.session.terms.TermsService
import org.matrix.android.sdk.api.session.thirdparty.ThirdPartyService
@ -97,7 +96,6 @@ internal class DefaultSession @Inject constructor(
private val roomService: Lazy<RoomService>,
private val roomDirectoryService: Lazy<RoomDirectoryService>,
private val userService: Lazy<UserService>,
private val filterService: Lazy<FilterService>,
private val federationService: Lazy<FederationService>,
private val cacheService: Lazy<CacheService>,
private val signOutService: Lazy<SignOutService>,
@ -209,7 +207,6 @@ internal class DefaultSession @Inject constructor(
override fun roomDirectoryService(): RoomDirectoryService = roomDirectoryService.get()
override fun userService(): UserService = userService.get()
override fun signOutService(): SignOutService = signOutService.get()
override fun filterService(): FilterService = filterService.get()
override fun pushRuleService(): PushRuleService = pushRuleService.get()
override fun pushersService(): PushersService = pushersService.get()
override fun eventService(): EventService = eventService.get()

View File

@ -17,20 +17,15 @@
package org.matrix.android.sdk.internal.session.filter
import com.zhuinden.monarchy.Monarchy
import io.realm.kotlin.where
import org.matrix.android.sdk.internal.database.mapper.FilterParamsMapper
import org.matrix.android.sdk.internal.database.model.FilterEntity
import org.matrix.android.sdk.internal.database.model.SyncFilterParamsEntity
import org.matrix.android.sdk.internal.database.query.get
import org.matrix.android.sdk.internal.database.query.getOrCreate
import org.matrix.android.sdk.internal.di.SessionDatabase
import org.matrix.android.sdk.internal.sync.filter.SyncFilterParams
import org.matrix.android.sdk.internal.util.awaitTransaction
import javax.inject.Inject
internal class DefaultFilterRepository @Inject constructor(
@SessionDatabase private val monarchy: Monarchy,
private val filterParamsMapper: FilterParamsMapper
) : FilterRepository {
override suspend fun storeSyncFilter(filter: Filter, filterId: String, roomEventFilter: RoomEventFilter) {
@ -69,19 +64,4 @@ internal class DefaultFilterRepository @Inject constructor(
FilterEntity.getOrCreate(it).roomEventFilterJson
}
}
override suspend fun getStoredFilterParams(): SyncFilterParams? {
return monarchy.awaitTransaction { realm ->
realm.where<SyncFilterParamsEntity>().findFirst()?.let {
filterParamsMapper.map(it)
}
}
}
override suspend fun storeFilterParams(params: SyncFilterParams) {
return monarchy.awaitTransaction { realm ->
val entity = filterParamsMapper.map(params)
realm.insertOrUpdate(entity)
}
}
}

View File

@ -1,43 +0,0 @@
/*
* Copyright 2020 The Matrix.org Foundation C.I.C.
*
* 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 org.matrix.android.sdk.internal.session.filter
import org.matrix.android.sdk.api.session.sync.FilterService
import org.matrix.android.sdk.api.session.sync.filter.SyncFilterBuilder
import org.matrix.android.sdk.internal.session.homeserver.HomeServerCapabilitiesDataSource
import javax.inject.Inject
internal class DefaultFilterService @Inject constructor(
private val saveFilterTask: SaveFilterTask,
private val filterRepository: FilterRepository,
private val homeServerCapabilitiesDataSource: HomeServerCapabilitiesDataSource,
) : FilterService {
// TODO Pass a list of support events instead
override suspend fun setSyncFilter(filterBuilder: SyncFilterBuilder) {
filterRepository.storeFilterParams(filterBuilder.extractParams())
// don't upload/store filter until homeserver capabilities are fetched
homeServerCapabilitiesDataSource.getHomeServerCapabilities()?.let { homeServerCapabilities ->
saveFilterTask.execute(
SaveFilterTask.Params(
filter = filterBuilder.build(homeServerCapabilities)
)
)
}
}
}

View File

@ -19,7 +19,6 @@ package org.matrix.android.sdk.internal.session.filter
import dagger.Binds
import dagger.Module
import dagger.Provides
import org.matrix.android.sdk.api.session.sync.FilterService
import org.matrix.android.sdk.internal.session.SessionScope
import retrofit2.Retrofit
@ -39,9 +38,6 @@ internal abstract class FilterModule {
@Binds
abstract fun bindFilterRepository(repository: DefaultFilterRepository): FilterRepository
@Binds
abstract fun bindFilterService(service: DefaultFilterService): FilterService
@Binds
abstract fun bindSaveFilterTask(task: DefaultSaveFilterTask): SaveFilterTask

View File

@ -16,8 +16,6 @@
package org.matrix.android.sdk.internal.session.filter
import org.matrix.android.sdk.internal.sync.filter.SyncFilterParams
/**
* Repository for request filters.
*/
@ -44,14 +42,4 @@ internal interface FilterRepository {
* Return the room filter.
*/
suspend fun getRoomFilterBody(): String
/**
* Returns filter params stored in local storage if it exists.
*/
suspend fun getStoredFilterParams(): SyncFilterParams?
/**
* Stores filter params to local storage.
*/
suspend fun storeFilterParams(params: SyncFilterParams)
}

View File

@ -16,9 +16,10 @@
package org.matrix.android.sdk.internal.session.filter
import org.matrix.android.sdk.api.MatrixConfiguration
import org.matrix.android.sdk.api.session.homeserver.HomeServerCapabilities
import org.matrix.android.sdk.api.session.sync.filter.SyncFilterBuilder
import org.matrix.android.sdk.internal.session.homeserver.HomeServerCapabilitiesDataSource
import org.matrix.android.sdk.internal.sync.filter.SyncFilterBuilder
import org.matrix.android.sdk.internal.task.Task
import javax.inject.Inject
@ -27,7 +28,8 @@ internal interface GetCurrentFilterTask : Task<Unit, String>
internal class DefaultGetCurrentFilterTask @Inject constructor(
private val filterRepository: FilterRepository,
private val homeServerCapabilitiesDataSource: HomeServerCapabilitiesDataSource,
private val saveFilterTask: SaveFilterTask
private val saveFilterTask: SaveFilterTask,
private val matrixConfiguration: MatrixConfiguration
) : GetCurrentFilterTask {
override suspend fun execute(params: Unit): String {
@ -35,7 +37,7 @@ internal class DefaultGetCurrentFilterTask @Inject constructor(
val storedFilterBody = filterRepository.getStoredSyncFilterBody()
val homeServerCapabilities = homeServerCapabilitiesDataSource.getHomeServerCapabilities() ?: HomeServerCapabilities()
val currentFilter = SyncFilterBuilder()
.with(filterRepository.getStoredFilterParams())
.with(matrixConfiguration.syncConfig.syncFilterParams)
.build(homeServerCapabilities)
val currentFilterBody = currentFilter.toJSONString()

View File

@ -14,15 +14,15 @@
* limitations under the License.
*/
package org.matrix.android.sdk.api.session.sync.filter
package org.matrix.android.sdk.internal.sync.filter
import org.matrix.android.sdk.api.session.homeserver.HomeServerCapabilities
import org.matrix.android.sdk.api.session.sync.filter.SyncFilterParams
import org.matrix.android.sdk.internal.session.filter.Filter
import org.matrix.android.sdk.internal.session.filter.RoomEventFilter
import org.matrix.android.sdk.internal.session.filter.RoomFilter
import org.matrix.android.sdk.internal.sync.filter.SyncFilterParams
class SyncFilterBuilder {
internal class SyncFilterBuilder {
private var lazyLoadMembersForStateEvents: Boolean? = null
private var lazyLoadMembersForMessageEvents: Boolean? = null
private var useThreadNotifications: Boolean? = null

View File

@ -21,9 +21,7 @@ import kotlinx.coroutines.test.runTest
import org.amshove.kluent.shouldBeEqualTo
import org.junit.Test
import org.matrix.android.sdk.api.session.homeserver.HomeServerCapabilities
import org.matrix.android.sdk.api.session.sync.filter.SyncFilterBuilder
import org.matrix.android.sdk.internal.session.filter.DefaultGetCurrentFilterTask
import org.matrix.android.sdk.internal.sync.filter.SyncFilterParams
import org.matrix.android.sdk.test.fakes.FakeFilterRepository
import org.matrix.android.sdk.test.fakes.FakeHomeServerCapabilitiesDataSource
import org.matrix.android.sdk.test.fakes.FakeSaveFilterTask

View File

@ -19,7 +19,6 @@ package org.matrix.android.sdk.test.fakes
import io.mockk.coEvery
import io.mockk.mockk
import org.matrix.android.sdk.internal.session.filter.FilterRepository
import org.matrix.android.sdk.internal.sync.filter.SyncFilterParams
internal class FakeFilterRepository : FilterRepository by mockk() {

View File

@ -70,11 +70,13 @@ import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.SupervisorJob
import org.matrix.android.sdk.api.Matrix
import org.matrix.android.sdk.api.MatrixConfiguration
import org.matrix.android.sdk.api.SyncConfig
import org.matrix.android.sdk.api.auth.AuthenticationService
import org.matrix.android.sdk.api.auth.HomeServerHistoryService
import org.matrix.android.sdk.api.legacy.LegacySessionImporter
import org.matrix.android.sdk.api.raw.RawService
import org.matrix.android.sdk.api.session.Session
import org.matrix.android.sdk.api.session.sync.filter.SyncFilterParams
import org.matrix.android.sdk.api.settings.LightweightSettingsStorage
import javax.inject.Singleton
@ -157,6 +159,9 @@ import javax.inject.Singleton
),
metricPlugins = vectorPlugins.plugins(),
customEventTypesProvider = vectorCustomEventTypesProvider,
syncConfig = SyncConfig(
syncFilterParams = SyncFilterParams(lazyLoadMembersForStateEvents = true, useThreadNotifications = true)
)
)
}

View File

@ -25,7 +25,6 @@ import im.vector.app.features.call.webrtc.WebRtcCallManager
import im.vector.app.features.session.coroutineScope
import im.vector.app.features.settings.VectorPreferences
import im.vector.app.features.settings.devices.v2.notification.UpdateNotificationSettingsAccountDataUseCase
import im.vector.app.features.sync.SyncUtils
import kotlinx.coroutines.launch
import org.matrix.android.sdk.api.session.Session
import timber.log.Timber
@ -43,9 +42,6 @@ class ConfigureAndStartSessionUseCase @Inject constructor(
fun execute(session: Session, startSyncing: Boolean = true) {
Timber.i("Configure and start session for ${session.myUserId}. startSyncing: $startSyncing")
session.open()
session.coroutineScope.launch {
session.filterService().setSyncFilter(SyncUtils.getSyncFilterBuilder())
}
if (startSyncing) {
session.startSyncing(context)
}

View File

@ -1,48 +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 im.vector.app.features.sync
import org.matrix.android.sdk.api.session.events.model.EventType
import org.matrix.android.sdk.api.session.sync.filter.SyncFilterBuilder
object SyncUtils {
// Get only managed types by Element
private val listOfSupportedTimelineEventTypes = listOf(
// TODO Complete the list
EventType.MESSAGE
)
// Get only managed types by Element
private val listOfSupportedStateEventTypes = listOf(
// TODO Complete the list
EventType.STATE_ROOM_MEMBER
)
fun getSyncFilterBuilder(): SyncFilterBuilder {
return SyncFilterBuilder()
.useThreadNotifications(true)
.lazyLoadMembersForStateEvents(true)
/**
* Currently we don't set [lazy_load_members = true] for Filter.room.timeline even though we set it for RoomFilter which is used later to
* fetch messages in a room. It's not clear if it's done so by mistake or intentionally, so changing it could case side effects and need
* careful testing
* */
// .lazyLoadMembersForMessageEvents(true)
// .listOfSupportedStateEventTypes(listOfSupportedStateEventTypes)
// .listOfSupportedTimelineEventTypes(listOfSupportedTimelineEventTypes)
}
}

View File

@ -20,7 +20,6 @@ import im.vector.app.core.extensions.startSyncing
import im.vector.app.core.session.clientinfo.UpdateMatrixClientInfoUseCase
import im.vector.app.features.session.coroutineScope
import im.vector.app.features.settings.devices.v2.notification.UpdateNotificationSettingsAccountDataUseCase
import im.vector.app.features.sync.SyncUtils
import im.vector.app.test.fakes.FakeContext
import im.vector.app.test.fakes.FakeNotificationsSettingUpdater
import im.vector.app.test.fakes.FakeSession
@ -87,7 +86,6 @@ class ConfigureAndStartSessionUseCaseTest {
// Then
verify { aSession.startSyncing(fakeContext.instance) }
aSession.fakeFilterService.verifySetSyncFilter(SyncUtils.getSyncFilterBuilder())
aSession.fakePushersService.verifyRefreshPushers()
fakeWebRtcCallManager.verifyCheckForProtocolsSupportIfNeeded()
coVerify {
@ -112,7 +110,6 @@ class ConfigureAndStartSessionUseCaseTest {
// Then
verify { aSession.startSyncing(fakeContext.instance) }
aSession.fakeFilterService.verifySetSyncFilter(SyncUtils.getSyncFilterBuilder())
aSession.fakePushersService.verifyRefreshPushers()
fakeWebRtcCallManager.verifyCheckForProtocolsSupportIfNeeded()
coVerify(inverse = true) {
@ -140,7 +137,6 @@ class ConfigureAndStartSessionUseCaseTest {
// Then
verify(inverse = true) { aSession.startSyncing(fakeContext.instance) }
aSession.fakeFilterService.verifySetSyncFilter(SyncUtils.getSyncFilterBuilder())
aSession.fakePushersService.verifyRefreshPushers()
fakeWebRtcCallManager.verifyCheckForProtocolsSupportIfNeeded()
coVerify {
@ -152,7 +148,6 @@ class ConfigureAndStartSessionUseCaseTest {
private fun givenASession(): FakeSession {
val fakeSession = FakeSession()
every { fakeSession.open() } just runs
fakeSession.fakeFilterService.givenSetFilterSucceeds()
every { fakeSession.startSyncing(any()) } just runs
fakeSession.fakePushersService.givenRefreshPushersSucceeds()
return fakeSession

View File

@ -1,36 +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 im.vector.app.test.fakes
import io.mockk.coEvery
import io.mockk.coVerify
import io.mockk.just
import io.mockk.mockk
import io.mockk.runs
import org.matrix.android.sdk.api.session.sync.FilterService
import org.matrix.android.sdk.api.session.sync.filter.SyncFilterBuilder
class FakeFilterService : FilterService by mockk() {
fun givenSetFilterSucceeds() {
coEvery { setSyncFilter(any()) } just runs
}
fun verifySetSyncFilter(filterBuilder: SyncFilterBuilder) {
coVerify { setSyncFilter(filterBuilder) }
}
}

View File

@ -43,8 +43,7 @@ class FakeSession(
val fakeRoomService: FakeRoomService = FakeRoomService(),
val fakePushersService: FakePushersService = FakePushersService(),
private val fakeEventService: FakeEventService = FakeEventService(),
val fakeSessionAccountDataService: FakeSessionAccountDataService = FakeSessionAccountDataService(),
val fakeFilterService: FakeFilterService = FakeFilterService(),
val fakeSessionAccountDataService: FakeSessionAccountDataService = FakeSessionAccountDataService()
) : Session by mockk(relaxed = true) {
init {
@ -63,7 +62,6 @@ class FakeSession(
override fun eventService() = fakeEventService
override fun pushersService() = fakePushersService
override fun accountDataService() = fakeSessionAccountDataService
override fun filterService() = fakeFilterService
fun givenVectorStore(vectorSessionStore: VectorSessionStore) {
coEvery {