Skip to content

Commit

Permalink
Merge pull request #8130 from vector-im/feature/fre/poll_sync_push_ru…
Browse files Browse the repository at this point in the history
…les_after_creation

[Poll] Synchronize polls and message push rules after creation (PSG-1137)
  • Loading branch information
Florian14 authored Feb 17, 2023
2 parents f887acd + 8bf46b1 commit 7d16c86
Show file tree
Hide file tree
Showing 13 changed files with 317 additions and 33 deletions.
1 change: 1 addition & 0 deletions changelog.d/8130.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[Poll] Synchronize polls and message push rules
Original file line number Diff line number Diff line change
Expand Up @@ -61,22 +61,4 @@ object RuleIds {
const val RULE_ID_FALLBACK = ".m.rule.fallback"

const val RULE_ID_REACTION = ".m.rule.reaction"

fun getSyncedRules(ruleId: String): List<String> {
return when (ruleId) {
RULE_ID_ONE_TO_ONE_ROOM -> listOf(
RULE_ID_POLL_START_ONE_TO_ONE,
RULE_ID_POLL_START_ONE_TO_ONE_UNSTABLE,
RULE_ID_POLL_END_ONE_TO_ONE,
RULE_ID_POLL_END_ONE_TO_ONE_UNSTABLE,
)
RULE_ID_ALL_OTHER_MESSAGES_ROOMS -> listOf(
RULE_ID_POLL_START,
RULE_ID_POLL_START_UNSTABLE,
RULE_ID_POLL_END,
RULE_ID_POLL_END_UNSTABLE,
)
else -> emptyList()
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* 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 im.vector.app.core.notification

import im.vector.app.features.session.coroutineScope
import im.vector.app.features.settings.notifications.usecase.UpdatePushRulesIfNeededUseCase
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
import org.matrix.android.sdk.api.session.Session
import org.matrix.android.sdk.api.session.accountdata.UserAccountDataTypes
import org.matrix.android.sdk.flow.flow
import javax.inject.Inject
import javax.inject.Singleton

/**
* Listen changes in Account Data to update the push rules if needed.
*/
@Singleton
class PushRulesUpdater @Inject constructor(
private val updatePushRulesIfNeededUseCase: UpdatePushRulesIfNeededUseCase,
) {

private var job: Job? = null

fun onSessionStarted(session: Session) {
updatePushRulesOnChange(session)
}

private fun updatePushRulesOnChange(session: Session) {
job?.cancel()
job = session.coroutineScope.launch {
session.flow()
.liveUserAccountData(UserAccountDataTypes.TYPE_PUSH_RULES)
.onEach { updatePushRulesIfNeededUseCase.execute(session) }
.collect()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import android.content.Context
import dagger.hilt.android.qualifiers.ApplicationContext
import im.vector.app.core.extensions.startSyncing
import im.vector.app.core.notification.NotificationsSettingUpdater
import im.vector.app.core.notification.PushRulesUpdater
import im.vector.app.core.session.clientinfo.UpdateMatrixClientInfoUseCase
import im.vector.app.features.call.webrtc.WebRtcCallManager
import im.vector.app.features.session.coroutineScope
Expand All @@ -37,6 +38,7 @@ class ConfigureAndStartSessionUseCase @Inject constructor(
private val vectorPreferences: VectorPreferences,
private val notificationsSettingUpdater: NotificationsSettingUpdater,
private val updateNotificationSettingsAccountDataUseCase: UpdateNotificationSettingsAccountDataUseCase,
private val pushRulesUpdater: PushRulesUpdater,
) {

fun execute(session: Session, startSyncing: Boolean = true) {
Expand All @@ -50,6 +52,7 @@ class ConfigureAndStartSessionUseCase @Inject constructor(
updateMatrixClientInfoIfNeeded(session)
createNotificationSettingsAccountDataIfNeeded(session)
notificationsSettingUpdater.onSessionStarted(session)
pushRulesUpdater.onSessionStarted(session)
}

private fun updateMatrixClientInfoIfNeeded(session: Session) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* 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 im.vector.app.features.settings.notifications

import org.matrix.android.sdk.api.session.pushrules.RuleIds

fun RuleIds.getSyncedRules(ruleId: String): List<String> {
return when (ruleId) {
RULE_ID_ONE_TO_ONE_ROOM -> listOf(
RULE_ID_POLL_START_ONE_TO_ONE,
RULE_ID_POLL_START_ONE_TO_ONE_UNSTABLE,
RULE_ID_POLL_END_ONE_TO_ONE,
RULE_ID_POLL_END_ONE_TO_ONE_UNSTABLE,
)
RULE_ID_ALL_OTHER_MESSAGES_ROOMS -> listOf(
RULE_ID_POLL_START,
RULE_ID_POLL_START_UNSTABLE,
RULE_ID_POLL_END,
RULE_ID_POLL_END_UNSTABLE,
)
else -> emptyList()
}
}

fun RuleIds.getParentRule(ruleId: String): String? {
return when (ruleId) {
RULE_ID_POLL_START_ONE_TO_ONE,
RULE_ID_POLL_START_ONE_TO_ONE_UNSTABLE,
RULE_ID_POLL_END_ONE_TO_ONE,
RULE_ID_POLL_END_ONE_TO_ONE_UNSTABLE -> RULE_ID_ONE_TO_ONE_ROOM
RULE_ID_POLL_START,
RULE_ID_POLL_START_UNSTABLE,
RULE_ID_POLL_END,
RULE_ID_POLL_END_UNSTABLE -> RULE_ID_ALL_OTHER_MESSAGES_ROOMS
else -> null
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* 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 im.vector.app.features.settings.notifications.usecase

import im.vector.app.features.settings.notifications.getParentRule
import org.matrix.android.sdk.api.session.Session
import org.matrix.android.sdk.api.session.pushrules.RuleIds
import org.matrix.android.sdk.api.session.pushrules.getActions
import org.matrix.android.sdk.api.session.pushrules.rest.PushRule
import org.matrix.android.sdk.api.session.pushrules.rest.PushRuleAndKind
import javax.inject.Inject

class UpdatePushRulesIfNeededUseCase @Inject constructor() {

suspend fun execute(session: Session) {
val ruleSet = session.pushRuleService().getPushRules()
val pushRules = ruleSet.getAllRules()
val rulesToUpdate = pushRules.mapNotNull { rule ->
val parent = RuleIds.getParentRule(rule.ruleId)?.let { ruleId -> ruleSet.findDefaultRule(ruleId) }
if (parent != null && (rule.enabled != parent.pushRule.enabled || rule.actions != parent.pushRule.actions)) {
PushRuleWithParent(rule, parent)
} else {
null
}
}

rulesToUpdate.forEach {
session.pushRuleService().updatePushRuleActions(
kind = it.parent.kind,
ruleId = it.rule.ruleId,
enable = it.parent.pushRule.enabled,
actions = it.parent.pushRule.getActions(),
)
}
}

private data class PushRuleWithParent(
val rule: PushRule,
val parent: PushRuleAndKind,
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import im.vector.app.features.session.coroutineScope
import im.vector.app.features.settings.devices.v2.notification.UpdateNotificationSettingsAccountDataUseCase
import im.vector.app.test.fakes.FakeContext
import im.vector.app.test.fakes.FakeNotificationsSettingUpdater
import im.vector.app.test.fakes.FakePushRulesUpdater
import im.vector.app.test.fakes.FakeSession
import im.vector.app.test.fakes.FakeVectorPreferences
import im.vector.app.test.fakes.FakeWebRtcCallManager
Expand All @@ -47,6 +48,7 @@ class ConfigureAndStartSessionUseCaseTest {
private val fakeUpdateMatrixClientInfoUseCase = mockk<UpdateMatrixClientInfoUseCase>()
private val fakeVectorPreferences = FakeVectorPreferences()
private val fakeNotificationsSettingUpdater = FakeNotificationsSettingUpdater()
private val fakePushRulesUpdater = FakePushRulesUpdater()
private val fakeUpdateNotificationSettingsAccountDataUseCase = mockk<UpdateNotificationSettingsAccountDataUseCase>()

private val configureAndStartSessionUseCase = ConfigureAndStartSessionUseCase(
Expand All @@ -56,6 +58,7 @@ class ConfigureAndStartSessionUseCaseTest {
vectorPreferences = fakeVectorPreferences.instance,
notificationsSettingUpdater = fakeNotificationsSettingUpdater.instance,
updateNotificationSettingsAccountDataUseCase = fakeUpdateNotificationSettingsAccountDataUseCase,
pushRulesUpdater = fakePushRulesUpdater.instance,
)

@Before
Expand All @@ -78,7 +81,8 @@ class ConfigureAndStartSessionUseCaseTest {
coJustRun { fakeUpdateMatrixClientInfoUseCase.execute(any()) }
coJustRun { fakeUpdateNotificationSettingsAccountDataUseCase.execute(any()) }
fakeVectorPreferences.givenIsClientInfoRecordingEnabled(isEnabled = true)
fakeNotificationsSettingUpdater.givenOnSessionsStarted(aSession)
fakeNotificationsSettingUpdater.givenOnSessionStarted(aSession)
fakePushRulesUpdater.givenOnSessionStarted(aSession)

// When
configureAndStartSessionUseCase.execute(aSession, startSyncing = true)
Expand All @@ -102,7 +106,8 @@ class ConfigureAndStartSessionUseCaseTest {
fakeWebRtcCallManager.givenCheckForProtocolsSupportIfNeededSucceeds()
coJustRun { fakeUpdateNotificationSettingsAccountDataUseCase.execute(any()) }
fakeVectorPreferences.givenIsClientInfoRecordingEnabled(isEnabled = false)
fakeNotificationsSettingUpdater.givenOnSessionsStarted(aSession)
fakeNotificationsSettingUpdater.givenOnSessionStarted(aSession)
fakePushRulesUpdater.givenOnSessionStarted(aSession)

// When
configureAndStartSessionUseCase.execute(aSession, startSyncing = true)
Expand All @@ -129,7 +134,8 @@ class ConfigureAndStartSessionUseCaseTest {
coJustRun { fakeUpdateMatrixClientInfoUseCase.execute(any()) }
coJustRun { fakeUpdateNotificationSettingsAccountDataUseCase.execute(any()) }
fakeVectorPreferences.givenIsClientInfoRecordingEnabled(isEnabled = true)
fakeNotificationsSettingUpdater.givenOnSessionsStarted(aSession)
fakeNotificationsSettingUpdater.givenOnSessionStarted(aSession)
fakePushRulesUpdater.givenOnSessionStarted(aSession)

// When
configureAndStartSessionUseCase.execute(aSession, startSyncing = false)
Expand Down
Original file line number Diff line number Diff line change
@@ -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");
* you may not use this file except in compliance with the License.
Expand All @@ -14,11 +14,9 @@
* limitations under the License.
*/

package im.vector.app.features.settings.notifications
package im.vector.app.features.settings.notifications.usecase

import im.vector.app.core.pushers.UnregisterUnifiedPushUseCase
import im.vector.app.features.settings.notifications.usecase.DisableNotificationsForCurrentSessionUseCase
import im.vector.app.features.settings.notifications.usecase.ToggleNotificationsForCurrentSessionUseCase
import im.vector.app.test.fakes.FakePushersManager
import io.mockk.coJustRun
import io.mockk.coVerify
Expand Down
Original file line number Diff line number Diff line change
@@ -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");
* you may not use this file except in compliance with the License.
Expand All @@ -14,12 +14,10 @@
* limitations under the License.
*/

package im.vector.app.features.settings.notifications
package im.vector.app.features.settings.notifications.usecase

import im.vector.app.core.pushers.EnsureFcmTokenIsRetrievedUseCase
import im.vector.app.core.pushers.RegisterUnifiedPushUseCase
import im.vector.app.features.settings.notifications.usecase.EnableNotificationsForCurrentSessionUseCase
import im.vector.app.features.settings.notifications.usecase.ToggleNotificationsForCurrentSessionUseCase
import im.vector.app.test.fakes.FakePushersManager
import io.mockk.coJustRun
import io.mockk.coVerify
Expand Down
Original file line number Diff line number Diff line change
@@ -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");
* you may not use this file except in compliance with the License.
Expand All @@ -14,12 +14,11 @@
* limitations under the License.
*/

package im.vector.app.features.settings.notifications
package im.vector.app.features.settings.notifications.usecase

import im.vector.app.features.settings.devices.v2.notification.CheckIfCanToggleNotificationsViaPusherUseCase
import im.vector.app.features.settings.devices.v2.notification.DeleteNotificationSettingsAccountDataUseCase
import im.vector.app.features.settings.devices.v2.notification.SetNotificationSettingsAccountDataUseCase
import im.vector.app.features.settings.notifications.usecase.ToggleNotificationsForCurrentSessionUseCase
import im.vector.app.test.fakes.FakeActiveSessionHolder
import im.vector.app.test.fakes.FakeUnifiedPushHelper
import im.vector.app.test.fixtures.PusherFixture
Expand Down
Loading

0 comments on commit 7d16c86

Please sign in to comment.