Merge pull request #1001 from vector-im/feature/pusher_service

Cleanup pusher service and improve API
This commit is contained in:
Benoit Marty 2020-02-13 08:02:33 +01:00 committed by GitHub
commit 5191cbaf93
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 133 additions and 90 deletions

View file

@ -8,18 +8,22 @@ Improvements 🙌:
- Show confirmation dialog before deleting a message (#967)
- Open room member profile from reactions list and read receipts list (#875)
Other changes:
-
Bugfix 🐛:
- Fix crash by removing all notifications after clearing cache (#878)
Translations 🗣:
-
SDK API changes 🔞:
- Javadoc improved for PushersService
- PushersService.pushers() has been renamed to PushersService.getPushers()
Build 🧱:
-
Other changes:
-
Changes in RiotX 0.15.0 (2020-02-10)
===================================================
@ -385,15 +389,18 @@ Features ✨:
Improvements 🙌:
-
Other changes:
-
Bugfix 🐛:
-
Translations 🗣:
-
SDK API changes 🔞:
-
Build 🧱:
-
Other changes:
-

View file

@ -17,6 +17,7 @@ package im.vector.matrix.android.api.session.pushers
import androidx.lifecycle.LiveData
import im.vector.matrix.android.api.MatrixCallback
import im.vector.matrix.android.api.util.Cancelable
import java.util.UUID
interface PushersService {
@ -28,19 +29,32 @@ interface PushersService {
/**
* Add a new HTTP pusher.
* Note that only `http` kind is supported by the SDK for now.
* Ref: https://matrix.org/docs/spec/client_server/latest#post-matrix-client-r0-pushers-set
*
* @param pushkey the pushkey
* @param pushkey This is a unique identifier for this pusher. The value you should use for
* this is the routing or destination address information for the notification,
* for example, the APNS token for APNS or the Registration ID for GCM. If your
* notification client has no such concept, use any unique identifier. Max length, 512 chars.
* If the kind is "email", this is the email address to send notifications to.
* @param appId the application id
* @param profileTag the profile tag
* @param lang the language
* @param appDisplayName a human-readable application name
* @param deviceDisplayName a human-readable device name
* @param url the URL that should be used to send notifications
* @param append append the pusher
* @param withEventIdOnly true to limit the push content
* This is a reverse-DNS style identifier for the application. It is recommended
* that this end with the platform, such that different platform versions get
* different app identifiers. Max length, 64 chars.
* @param profileTag This string determines which set of device specific rules this pusher executes.
* @param lang The preferred language for receiving notifications (e.g. "en" or "en-US").
* @param appDisplayName A human readable string that will allow the user to identify what application owns this pusher.
* @param deviceDisplayName A human readable string that will allow the user to identify what device owns this pusher.
* @param url The URL to use to send notifications to. MUST be an HTTPS URL with a path of /_matrix/push/v1/notify.
* @param append If true, the homeserver should add another pusher with the given pushkey and App ID in addition
* to any others with different user IDs. Otherwise, the homeserver must remove any other pushers
* with the same App ID and pushkey for different users.
* @param withEventIdOnly true to limit the push content to only id and not message content
* Ref: https://matrix.org/docs/spec/push_gateway/r0.1.1#homeserver-behaviour
*
* @return A work request uuid. Can be used to listen to the status
* (LiveData<WorkInfo> status = workManager.getWorkInfoByIdLiveData(<UUID>))
* @return A work request uuid. Can be used to listen to the status
* (LiveData<WorkInfo> status = workManager.getWorkInfoByIdLiveData(<UUID>))
* @throws [InvalidParameterException] if a parameter is not correct
*/
fun addHttpPusher(pushkey: String,
appId: String,
@ -52,13 +66,18 @@ interface PushersService {
append: Boolean,
withEventIdOnly: Boolean): UUID
fun removeHttpPusher(pushkey: String, appId: String, callback: MatrixCallback<Unit>)
companion object {
const val EVENT_ID_ONLY = "event_id_only"
}
/**
* Remove the http pusher
*/
fun removeHttpPusher(pushkey: String, appId: String, callback: MatrixCallback<Unit>): Cancelable
/**
* Get the current pushers, as a LiveData
*/
fun getPushersLive(): LiveData<List<Pusher>>
fun pushers() : List<Pusher>
/**
* Get the current pushers
*/
fun getPushers(): List<Pusher>
}

View file

@ -154,97 +154,95 @@ internal abstract class CryptoModule {
}
@Binds
abstract fun bindCryptoService(cryptoService: DefaultCryptoService): CryptoService
abstract fun bindCryptoService(service: DefaultCryptoService): CryptoService
@Binds
abstract fun bindDeleteDeviceTask(deleteDeviceTask: DefaultDeleteDeviceTask): DeleteDeviceTask
abstract fun bindDeleteDeviceTask(task: DefaultDeleteDeviceTask): DeleteDeviceTask
@Binds
abstract fun bindGetDevicesTask(getDevicesTask: DefaultGetDevicesTask): GetDevicesTask
abstract fun bindGetDevicesTask(task: DefaultGetDevicesTask): GetDevicesTask
@Binds
abstract fun bindGetDeviceInfoTask(task: DefaultGetDeviceInfoTask): GetDeviceInfoTask
@Binds
abstract fun bindSetDeviceNameTask(setDeviceNameTask: DefaultSetDeviceNameTask): SetDeviceNameTask
abstract fun bindSetDeviceNameTask(task: DefaultSetDeviceNameTask): SetDeviceNameTask
@Binds
abstract fun bindUploadKeysTask(uploadKeysTask: DefaultUploadKeysTask): UploadKeysTask
abstract fun bindUploadKeysTask(task: DefaultUploadKeysTask): UploadKeysTask
@Binds
abstract fun bindUploadSigningKeysTask(uploadKeysTask: DefaultUploadSigningKeysTask): UploadSigningKeysTask
abstract fun bindUploadSigningKeysTask(task: DefaultUploadSigningKeysTask): UploadSigningKeysTask
@Binds
abstract fun bindUploadSignaturesTask(uploadSignaturesTask: DefaultUploadSignaturesTask): UploadSignaturesTask
abstract fun bindUploadSignaturesTask(task: DefaultUploadSignaturesTask): UploadSignaturesTask
@Binds
abstract fun bindDownloadKeysForUsersTask(downloadKeysForUsersTask: DefaultDownloadKeysForUsers): DownloadKeysForUsersTask
abstract fun bindDownloadKeysForUsersTask(task: DefaultDownloadKeysForUsers): DownloadKeysForUsersTask
@Binds
abstract fun bindCreateKeysBackupVersionTask(createKeysBackupVersionTask: DefaultCreateKeysBackupVersionTask): CreateKeysBackupVersionTask
abstract fun bindCreateKeysBackupVersionTask(task: DefaultCreateKeysBackupVersionTask): CreateKeysBackupVersionTask
@Binds
abstract fun bindDeleteBackupTask(deleteBackupTask: DefaultDeleteBackupTask): DeleteBackupTask
abstract fun bindDeleteBackupTask(task: DefaultDeleteBackupTask): DeleteBackupTask
@Binds
abstract fun bindDeleteRoomSessionDataTask(deleteRoomSessionDataTask: DefaultDeleteRoomSessionDataTask): DeleteRoomSessionDataTask
abstract fun bindDeleteRoomSessionDataTask(task: DefaultDeleteRoomSessionDataTask): DeleteRoomSessionDataTask
@Binds
abstract fun bindDeleteRoomSessionsDataTask(deleteRoomSessionsDataTask: DefaultDeleteRoomSessionsDataTask): DeleteRoomSessionsDataTask
abstract fun bindDeleteRoomSessionsDataTask(task: DefaultDeleteRoomSessionsDataTask): DeleteRoomSessionsDataTask
@Binds
abstract fun bindDeleteSessionsDataTask(deleteSessionsDataTask: DefaultDeleteSessionsDataTask): DeleteSessionsDataTask
abstract fun bindDeleteSessionsDataTask(task: DefaultDeleteSessionsDataTask): DeleteSessionsDataTask
@Binds
abstract fun bindGetKeysBackupLastVersionTask(getKeysBackupLastVersionTask: DefaultGetKeysBackupLastVersionTask): GetKeysBackupLastVersionTask
abstract fun bindGetKeysBackupLastVersionTask(task: DefaultGetKeysBackupLastVersionTask): GetKeysBackupLastVersionTask
@Binds
abstract fun bindGetKeysBackupVersionTask(getKeysBackupVersionTask: DefaultGetKeysBackupVersionTask): GetKeysBackupVersionTask
abstract fun bindGetKeysBackupVersionTask(task: DefaultGetKeysBackupVersionTask): GetKeysBackupVersionTask
@Binds
abstract fun bindGetRoomSessionDataTask(getRoomSessionDataTask: DefaultGetRoomSessionDataTask): GetRoomSessionDataTask
abstract fun bindGetRoomSessionDataTask(task: DefaultGetRoomSessionDataTask): GetRoomSessionDataTask
@Binds
abstract fun bindGetRoomSessionsDataTask(getRoomSessionsDataTask: DefaultGetRoomSessionsDataTask): GetRoomSessionsDataTask
abstract fun bindGetRoomSessionsDataTask(task: DefaultGetRoomSessionsDataTask): GetRoomSessionsDataTask
@Binds
abstract fun bindGetSessionsDataTask(getSessionsDataTask: DefaultGetSessionsDataTask): GetSessionsDataTask
abstract fun bindGetSessionsDataTask(task: DefaultGetSessionsDataTask): GetSessionsDataTask
@Binds
abstract fun bindStoreRoomSessionDataTask(storeRoomSessionDataTask: DefaultStoreRoomSessionDataTask): StoreRoomSessionDataTask
abstract fun bindStoreRoomSessionDataTask(task: DefaultStoreRoomSessionDataTask): StoreRoomSessionDataTask
@Binds
abstract fun bindStoreRoomSessionsDataTask(storeRoomSessionsDataTask: DefaultStoreRoomSessionsDataTask): StoreRoomSessionsDataTask
abstract fun bindStoreRoomSessionsDataTask(task: DefaultStoreRoomSessionsDataTask): StoreRoomSessionsDataTask
@Binds
abstract fun bindStoreSessionsDataTask(storeSessionsDataTask: DefaultStoreSessionsDataTask): StoreSessionsDataTask
abstract fun bindStoreSessionsDataTask(task: DefaultStoreSessionsDataTask): StoreSessionsDataTask
@Binds
abstract fun bindUpdateKeysBackupVersionTask(updateKeysBackupVersionTask: DefaultUpdateKeysBackupVersionTask): UpdateKeysBackupVersionTask
abstract fun bindUpdateKeysBackupVersionTask(task: DefaultUpdateKeysBackupVersionTask): UpdateKeysBackupVersionTask
@Binds
abstract fun bindSendToDeviceTask(sendToDeviceTask: DefaultSendToDeviceTask): SendToDeviceTask
abstract fun bindSendToDeviceTask(task: DefaultSendToDeviceTask): SendToDeviceTask
@Binds
abstract fun bindEncryptEventTask(encryptEventTask: DefaultEncryptEventTask): EncryptEventTask
abstract fun bindEncryptEventTask(task: DefaultEncryptEventTask): EncryptEventTask
@Binds
abstract fun bindSendVerificationMessageTask(sendDefaultSendVerificationMessageTask: DefaultSendVerificationMessageTask): SendVerificationMessageTask
abstract fun bindSendVerificationMessageTask(task: DefaultSendVerificationMessageTask): SendVerificationMessageTask
@Binds
abstract fun bindClaimOneTimeKeysForUsersDeviceTask(claimOneTimeKeysForUsersDevice: DefaultClaimOneTimeKeysForUsersDevice)
: ClaimOneTimeKeysForUsersDeviceTask
abstract fun bindClaimOneTimeKeysForUsersDeviceTask(task: DefaultClaimOneTimeKeysForUsersDevice): ClaimOneTimeKeysForUsersDeviceTask
@Binds
abstract fun bindDeleteDeviceWithUserPasswordTask(deleteDeviceWithUserPasswordTask: DefaultDeleteDeviceWithUserPasswordTask)
: DeleteDeviceWithUserPasswordTask
abstract fun bindDeleteDeviceWithUserPasswordTask(task: DefaultDeleteDeviceWithUserPasswordTask): DeleteDeviceWithUserPasswordTask
@Binds
abstract fun bindCrossSigningService(crossSigningService: DefaultCrossSigningService): CrossSigningService
abstract fun bindCrossSigningService(service: DefaultCrossSigningService): CrossSigningService
@Binds
abstract fun bindCryptoStore(realmCryptoStore: RealmCryptoStore): IMXCryptoStore
abstract fun bindCryptoStore(store: RealmCryptoStore): IMXCryptoStore
@Binds
abstract fun bindComputeShieldTrustTask(defaultShieldTrustUpdater: DefaultComputeTrustTask): ComputeTrustTask
abstract fun bindComputeShieldTrustTask(task: DefaultComputeTrustTask): ComputeTrustTask
}

View file

@ -37,5 +37,5 @@ internal abstract class CacheModule {
}
@Binds
abstract fun bindCacheService(cacheService: DefaultCacheService): CacheService
abstract fun bindCacheService(service: DefaultCacheService): CacheService
}

View file

@ -37,11 +37,11 @@ internal abstract class FilterModule {
}
@Binds
abstract fun bindFilterRepository(filterRepository: DefaultFilterRepository): FilterRepository
abstract fun bindFilterRepository(repository: DefaultFilterRepository): FilterRepository
@Binds
abstract fun bindFilterService(filterService: DefaultFilterService): FilterService
abstract fun bindFilterService(service: DefaultFilterService): FilterService
@Binds
abstract fun bindSaveFilterTask(saveFilterTask: DefaultSaveFilterTask): SaveFilterTask
abstract fun bindSaveFilterTask(task: DefaultSaveFilterTask): SaveFilterTask
}

View file

@ -37,8 +37,8 @@ internal abstract class GroupModule {
}
@Binds
abstract fun bindGetGroupDataTask(getGroupDataTask: DefaultGetGroupDataTask): GetGroupDataTask
abstract fun bindGetGroupDataTask(task: DefaultGetGroupDataTask): GetGroupDataTask
@Binds
abstract fun bindGroupService(groupService: DefaultGroupService): GroupService
abstract fun bindGroupService(service: DefaultGroupService): GroupService
}

View file

@ -36,5 +36,5 @@ internal abstract class HomeServerCapabilitiesModule {
}
@Binds
abstract fun bindGetHomeServerCapabilitiesTask(getHomeServerCapabilitiesTask: DefaultGetHomeServerCapabilitiesTask): GetHomeServerCapabilitiesTask
abstract fun bindGetHomeServerCapabilitiesTask(task: DefaultGetHomeServerCapabilitiesTask): GetHomeServerCapabilitiesTask
}

View file

@ -21,6 +21,7 @@ import com.zhuinden.monarchy.Monarchy
import im.vector.matrix.android.api.MatrixCallback
import im.vector.matrix.android.api.session.pushers.Pusher
import im.vector.matrix.android.api.session.pushers.PushersService
import im.vector.matrix.android.api.util.Cancelable
import im.vector.matrix.android.internal.database.mapper.asDomain
import im.vector.matrix.android.internal.database.model.PusherEntity
import im.vector.matrix.android.internal.database.query.where
@ -29,11 +30,12 @@ import im.vector.matrix.android.internal.di.WorkManagerProvider
import im.vector.matrix.android.internal.task.TaskExecutor
import im.vector.matrix.android.internal.task.configureWith
import im.vector.matrix.android.internal.worker.WorkerParamsFactory
import java.util.*
import java.security.InvalidParameterException
import java.util.UUID
import java.util.concurrent.TimeUnit
import javax.inject.Inject
internal class DefaultPusherService @Inject constructor(
internal class DefaultPushersService @Inject constructor(
private val workManagerProvider: WorkManagerProvider,
private val monarchy: Monarchy,
@SessionId private val sessionId: String,
@ -48,10 +50,21 @@ internal class DefaultPusherService @Inject constructor(
.executeBy(taskExecutor)
}
override fun addHttpPusher(pushkey: String, appId: String, profileTag: String,
lang: String, appDisplayName: String, deviceDisplayName: String,
url: String, append: Boolean, withEventIdOnly: Boolean)
override fun addHttpPusher(pushkey: String,
appId: String,
profileTag: String,
lang: String,
appDisplayName: String,
deviceDisplayName: String,
url: String,
append: Boolean,
withEventIdOnly: Boolean)
: UUID {
// Do some parameter checks. It's ok to throw Exception, to inform developer of the problem
if (pushkey.length > 512) throw InvalidParameterException("pushkey should not exceed 512 chars")
if (appId.length > 64) throw InvalidParameterException("appId should not exceed 64 chars")
if ("/_matrix/push/v1/notify" !in url) throw InvalidParameterException("url should contain '/_matrix/push/v1/notify'")
val pusher = JsonPusher(
pushKey = pushkey,
kind = "http",
@ -60,7 +73,7 @@ internal class DefaultPusherService @Inject constructor(
deviceDisplayName = deviceDisplayName,
profileTag = profileTag,
lang = lang,
data = JsonPusherData(url, if (withEventIdOnly) PushersService.EVENT_ID_ONLY else null),
data = JsonPusherData(url, EVENT_ID_ONLY.takeIf { withEventIdOnly }),
append = append)
val params = AddHttpPusherWorker.Params(sessionId, pusher)
@ -74,9 +87,9 @@ internal class DefaultPusherService @Inject constructor(
return request.id
}
override fun removeHttpPusher(pushkey: String, appId: String, callback: MatrixCallback<Unit>) {
override fun removeHttpPusher(pushkey: String, appId: String, callback: MatrixCallback<Unit>): Cancelable {
val params = RemovePusherTask.Params(pushkey, appId)
removePusherTask
return removePusherTask
.configureWith(params) {
this.callback = callback
}
@ -91,7 +104,11 @@ internal class DefaultPusherService @Inject constructor(
)
}
override fun pushers(): List<Pusher> {
override fun getPushers(): List<Pusher> {
return monarchy.fetchAllCopiedSync { PusherEntity.where(it) }.map { it.asDomain() }
}
companion object {
const val EVENT_ID_ONLY = "event_id_only"
}
}

View file

@ -49,38 +49,38 @@ internal abstract class PushersModule {
}
@Binds
abstract fun bindPusherService(pusherService: DefaultPusherService): PushersService
abstract fun bindPusherService(service: DefaultPushersService): PushersService
@Binds
abstract fun bindConditionResolver(conditionResolver: DefaultConditionResolver): ConditionResolver
abstract fun bindConditionResolver(resolver: DefaultConditionResolver): ConditionResolver
@Binds
abstract fun bindGetPushersTask(getPushersTask: DefaultGetPushersTask): GetPushersTask
abstract fun bindGetPushersTask(task: DefaultGetPushersTask): GetPushersTask
@Binds
abstract fun bindGetPushRulesTask(getPushRulesTask: DefaultGetPushRulesTask): GetPushRulesTask
abstract fun bindGetPushRulesTask(task: DefaultGetPushRulesTask): GetPushRulesTask
@Binds
abstract fun bindSavePushRulesTask(savePushRulesTask: DefaultSavePushRulesTask): SavePushRulesTask
abstract fun bindSavePushRulesTask(task: DefaultSavePushRulesTask): SavePushRulesTask
@Binds
abstract fun bindRemovePusherTask(removePusherTask: DefaultRemovePusherTask): RemovePusherTask
abstract fun bindRemovePusherTask(task: DefaultRemovePusherTask): RemovePusherTask
@Binds
abstract fun bindUpdatePushRuleEnableStatusTask(updatePushRuleEnableStatusTask: DefaultUpdatePushRuleEnableStatusTask): UpdatePushRuleEnableStatusTask
abstract fun bindUpdatePushRuleEnableStatusTask(task: DefaultUpdatePushRuleEnableStatusTask): UpdatePushRuleEnableStatusTask
@Binds
abstract fun bindAddPushRuleTask(addPushRuleTask: DefaultAddPushRuleTask): AddPushRuleTask
abstract fun bindAddPushRuleTask(task: DefaultAddPushRuleTask): AddPushRuleTask
@Binds
abstract fun bindRemovePushRuleTask(removePushRuleTask: DefaultRemovePushRuleTask): RemovePushRuleTask
abstract fun bindRemovePushRuleTask(task: DefaultRemovePushRuleTask): RemovePushRuleTask
@Binds
abstract fun bindSetRoomNotificationStateTask(setRoomNotificationStateTask: DefaultSetRoomNotificationStateTask): SetRoomNotificationStateTask
abstract fun bindSetRoomNotificationStateTask(task: DefaultSetRoomNotificationStateTask): SetRoomNotificationStateTask
@Binds
abstract fun bindPushRuleService(pushRuleService: DefaultPushRuleService): PushRuleService
abstract fun bindPushRuleService(service: DefaultPushRuleService): PushRuleService
@Binds
abstract fun bindProcessEventForPushTask(processEventForPushTask: DefaultProcessEventForPushTask): ProcessEventForPushTask
abstract fun bindProcessEventForPushTask(task: DefaultProcessEventForPushTask): ProcessEventForPushTask
}

View file

@ -36,5 +36,5 @@ internal abstract class SyncModule {
}
@Binds
abstract fun bindSyncTask(syncTask: DefaultSyncTask): SyncTask
abstract fun bindSyncTask(task: DefaultSyncTask): SyncTask
}

View file

@ -43,10 +43,10 @@ internal abstract class UserModule {
}
@Binds
abstract fun bindUserService(userService: DefaultUserService): UserService
abstract fun bindUserService(service: DefaultUserService): UserService
@Binds
abstract fun bindSearchUserTask(searchUserTask: DefaultSearchUserTask): SearchUserTask
abstract fun bindSearchUserTask(task: DefaultSearchUserTask): SearchUserTask
@Binds
abstract fun bindSaveIgnoredUsersTask(task: DefaultSaveIgnoredUsersTask): SaveIgnoredUsersTask
@ -55,5 +55,5 @@ internal abstract class UserModule {
abstract fun bindUpdateIgnoredUserIdsTask(task: DefaultUpdateIgnoredUserIdsTask): UpdateIgnoredUserIdsTask
@Binds
abstract fun bindUserStore(userStore: RealmUserStore): UserStore
abstract fun bindUserStore(store: RealmUserStore): UserStore
}

View file

@ -47,10 +47,10 @@ class TestTokenRegistration @Inject constructor(private val context: AppCompatAc
status = TestStatus.FAILED
return
}
val pusher = session.pushers().filter {
val pushers = session.getPushers().filter {
it.pushKey == fcmToken && it.state == PusherState.REGISTERED
}
if (pusher.isEmpty()) {
if (pushers.isEmpty()) {
description = stringProvider.getString(R.string.settings_troubleshoot_test_token_registration_failed,
stringProvider.getString(R.string.sas_error_unknown))
quickFix = object : TroubleshootQuickFix(R.string.settings_troubleshoot_test_token_registration_quick_fix) {

View file

@ -47,8 +47,8 @@ class PushersManager @Inject constructor(
appNameProvider.getAppName(),
currentSession.sessionParams.credentials.deviceId ?: "MOBILE",
stringProvider.getString(R.string.pusher_http_url),
false,
true
append = false,
withEventIdOnly = true
)
}

View file

@ -13,7 +13,9 @@
https://matrix.org/docs/spec/client_server/r0.4.0#id128
-->
<!-- Note: pusher_http_url should have path '/_matrix/push/v1/notify' -->
<string name="pusher_http_url" translatable="false">https://matrix.org/_matrix/push/v1/notify</string>
<!-- Note: pusher_app_id cannot exceed 64 chars -->
<string name="pusher_app_id" translatable="false">im.vector.app.android</string>
<string-array name="room_directory_servers" translatable="false">