diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/pushers/PushersService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/pushers/PushersService.kt index 03391ff8ba..757b55a3fa 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/pushers/PushersService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/pushers/PushersService.kt @@ -29,38 +29,9 @@ interface PushersService { * Add a new HTTP pusher. * Ref: https://matrix.org/docs/spec/client_server/latest#post-matrix-client-r0-pushers-set * - * @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. - * @param appId the application id - * 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 status = workManager.getWorkInfoByIdLiveData()) * @throws [InvalidParameterException] if a parameter is not correct */ - suspend fun addHttpPusher(pushkey: String, - appId: String, - profileTag: String, - lang: String, - appDisplayName: String, - deviceDisplayName: String, - url: String, - append: Boolean, - withEventIdOnly: Boolean) + suspend fun addHttpPusher(httpPusher: HttpPusher) /** * Enqueues a new HTTP pusher via the WorkManager API. @@ -70,15 +41,7 @@ interface PushersService { * (LiveData status = workManager.getWorkInfoByIdLiveData()) * @throws [InvalidParameterException] if a parameter is not correct */ - fun enqueueAddHttpPusher(pushkey: String, - appId: String, - profileTag: String, - lang: String, - appDisplayName: String, - deviceDisplayName: String, - url: String, - append: Boolean, - withEventIdOnly: Boolean): UUID + fun enqueueAddHttpPusher(httpPusher: HttpPusher): UUID /** * Add a new Email pusher. @@ -144,4 +107,62 @@ interface PushersService { * Get the current pushers */ fun getPushers(): List + + data class HttpPusher( + + /** + * 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. + */ + val pushkey: String, + + /** + * The application id + * 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. + */ + val appId: String, + + /** + * This string determines which set of device specific rules this pusher executes. + */ + val profileTag: String, + + /** + * The preferred language for receiving notifications (e.g. "en" or "en-US"). + */ + val lang: String, + + /** + * A human readable string that will allow the user to identify what application owns this pusher. + */ + val appDisplayName: String, + + /** + * A human readable string that will allow the user to identify what device owns this pusher. + */ + val deviceDisplayName: String, + + /** + * The URL to use to send notifications to. MUST be an HTTPS URL with a path of /_matrix/push/v1/notify. + */ + val url: String, + + /** + * 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. + */ + val append: Boolean, + + /** + * 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 + */ + val withEventIdOnly: Boolean, + ) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/DefaultPushersService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/DefaultPushersService.kt index 8a510969e7..e87c27e601 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/DefaultPushersService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/DefaultPushersService.kt @@ -58,57 +58,26 @@ internal class DefaultPushersService @Inject constructor( .executeBy(taskExecutor) } - override fun enqueueAddHttpPusher(pushkey: String, - appId: String, - profileTag: String, - lang: String, - appDisplayName: String, - deviceDisplayName: String, - url: String, - append: Boolean, - withEventIdOnly: Boolean - ): UUID { - return enqueueAddPusher( - JsonPusher( - pushKey = pushkey, - kind = "http", - appId = appId, - profileTag = profileTag, - lang = lang, - appDisplayName = appDisplayName, - deviceDisplayName = deviceDisplayName, - data = JsonPusherData(url, EVENT_ID_ONLY.takeIf { withEventIdOnly }), - append = append - ) - ) + override fun enqueueAddHttpPusher(httpPusher: PushersService.HttpPusher): UUID { + return enqueueAddPusher(httpPusher.toJsonPusher()) } - override suspend fun addHttpPusher(pushkey: String, - appId: String, - profileTag: String, - lang: String, - appDisplayName: String, - deviceDisplayName: String, - url: String, - append: Boolean, - withEventIdOnly: Boolean) { - addPusherTask.execute( - AddPusherTask.Params( - JsonPusher( - pushKey = pushkey, - kind = "http", - appId = appId, - profileTag = profileTag, - lang = lang, - appDisplayName = appDisplayName, - deviceDisplayName = deviceDisplayName, - data = JsonPusherData(url, EVENT_ID_ONLY.takeIf { withEventIdOnly }), - append = append - ) - ) - ) + override suspend fun addHttpPusher(httpPusher: PushersService.HttpPusher) { + addPusherTask.execute(AddPusherTask.Params(httpPusher.toJsonPusher())) } + private fun PushersService.HttpPusher.toJsonPusher() = JsonPusher( + pushKey = pushkey, + kind = "http", + appId = appId, + profileTag = profileTag, + lang = lang, + appDisplayName = appDisplayName, + deviceDisplayName = deviceDisplayName, + data = JsonPusherData(url, EVENT_ID_ONLY.takeIf { withEventIdOnly }), + append = append + ) + override suspend fun addEmailPusher(email: String, lang: String, emailBranding: String, diff --git a/vector/src/gplay/java/im/vector/app/gplay/features/settings/troubleshoot/TestTokenRegistration.kt b/vector/src/gplay/java/im/vector/app/gplay/features/settings/troubleshoot/TestTokenRegistration.kt index 966d79c59b..94d4ec8a56 100644 --- a/vector/src/gplay/java/im/vector/app/gplay/features/settings/troubleshoot/TestTokenRegistration.kt +++ b/vector/src/gplay/java/im/vector/app/gplay/features/settings/troubleshoot/TestTokenRegistration.kt @@ -57,7 +57,7 @@ class TestTokenRegistration @Inject constructor(private val context: AppCompatAc stringProvider.getString(R.string.sas_error_unknown)) quickFix = object : TroubleshootQuickFix(R.string.settings_troubleshoot_test_token_registration_quick_fix) { override fun doFix() { - val workId = pushersManager.registerPusherWithFcmKey(fcmToken) + val workId = pushersManager.enqueueRegisterPusherWithFcmKey(fcmToken) WorkManager.getInstance(context).getWorkInfoByIdLiveData(workId).observe(context, Observer { workInfo -> if (workInfo != null) { if (workInfo.state == WorkInfo.State.SUCCEEDED) { diff --git a/vector/src/gplay/java/im/vector/app/gplay/push/fcm/VectorFirebaseMessagingService.kt b/vector/src/gplay/java/im/vector/app/gplay/push/fcm/VectorFirebaseMessagingService.kt index ddedfb93e3..2ce51ba4c7 100755 --- a/vector/src/gplay/java/im/vector/app/gplay/push/fcm/VectorFirebaseMessagingService.kt +++ b/vector/src/gplay/java/im/vector/app/gplay/push/fcm/VectorFirebaseMessagingService.kt @@ -135,7 +135,7 @@ class VectorFirebaseMessagingService : FirebaseMessagingService() { Timber.tag(loggerTag.value).i("onNewToken: FCM Token has been updated") FcmHelper.storeFcmToken(this, refreshedToken) if (vectorPreferences.areNotificationEnabledForDevice() && activeSessionHolder.hasActiveSession()) { - pusherManager.registerPusherWithFcmKey(refreshedToken) + pusherManager.enqueueRegisterPusherWithFcmKey(refreshedToken) } } diff --git a/vector/src/gplay/java/im/vector/app/push/fcm/FcmHelper.kt b/vector/src/gplay/java/im/vector/app/push/fcm/FcmHelper.kt index f3bdcafb1c..fe091ffda3 100755 --- a/vector/src/gplay/java/im/vector/app/push/fcm/FcmHelper.kt +++ b/vector/src/gplay/java/im/vector/app/push/fcm/FcmHelper.kt @@ -75,7 +75,7 @@ object FcmHelper { .addOnSuccessListener { token -> storeFcmToken(activity, token) if (registerPusher) { - pushersManager.registerPusherWithFcmKey(token) + pushersManager.enqueueRegisterPusherWithFcmKey(token) } } .addOnFailureListener { e -> diff --git a/vector/src/main/java/im/vector/app/core/pushers/PushersManager.kt b/vector/src/main/java/im/vector/app/core/pushers/PushersManager.kt index 0ed7c91540..0f780d4504 100644 --- a/vector/src/main/java/im/vector/app/core/pushers/PushersManager.kt +++ b/vector/src/main/java/im/vector/app/core/pushers/PushersManager.kt @@ -21,6 +21,7 @@ import im.vector.app.core.di.ActiveSessionHolder import im.vector.app.core.resources.AppNameProvider import im.vector.app.core.resources.LocaleProvider import im.vector.app.core.resources.StringProvider +import org.matrix.android.sdk.api.session.pushers.PushersService import java.util.UUID import javax.inject.Inject import kotlin.math.abs @@ -44,23 +45,28 @@ class PushersManager @Inject constructor( ) } - fun registerPusherWithFcmKey(pushKey: String): UUID { + fun enqueueRegisterPusherWithFcmKey(pushKey: String): UUID { val currentSession = activeSessionHolder.getActiveSession() - val profileTag = DEFAULT_PUSHER_FILE_TAG + "_" + abs(currentSession.myUserId.hashCode()) - - return currentSession.enqueueAddHttpPusher( - pushKey, - stringProvider.getString(R.string.pusher_app_id), - profileTag, - localeProvider.current().language, - appNameProvider.getAppName(), - currentSession.sessionParams.deviceId ?: "MOBILE", - stringProvider.getString(R.string.pusher_http_url), - append = false, - withEventIdOnly = true - ) + return currentSession.enqueueAddHttpPusher(httpPusher(pushKey)) } + suspend fun registerPusherWithFcmKey(pushKey: String) { + val currentSession = activeSessionHolder.getActiveSession() + currentSession.addHttpPusher(httpPusher(pushKey)) + } + + private fun httpPusher(pushKey: String) = PushersService.HttpPusher( + pushKey, + stringProvider.getString(R.string.pusher_app_id), + profileTag = DEFAULT_PUSHER_FILE_TAG + "_" + abs(activeSessionHolder.getActiveSession().myUserId.hashCode()), + localeProvider.current().language, + appNameProvider.getAppName(), + activeSessionHolder.getActiveSession().sessionParams.deviceId ?: "MOBILE", + stringProvider.getString(R.string.pusher_http_url), + append = false, + withEventIdOnly = true + ) + suspend fun registerEmailForPush(email: String) { val currentSession = activeSessionHolder.getActiveSession() val appName = appNameProvider.getAppName() diff --git a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsNotificationPreferenceFragment.kt b/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsNotificationPreferenceFragment.kt index 098d1b2caa..18ea2d6773 100644 --- a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsNotificationPreferenceFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsNotificationPreferenceFragment.kt @@ -85,6 +85,21 @@ class VectorSettingsNotificationPreferenceFragment @Inject constructor( (pref as SwitchPreference).isChecked = areNotifEnabledAtAccountLevel } + findPreference(VectorPreferences.SETTINGS_ENABLE_THIS_DEVICE_PREFERENCE_KEY)?.let { + it.setTransactionalSwitchChangeListener(lifecycleScope) { isChecked -> + if (isChecked) { + FcmHelper.getFcmToken(requireContext())?.let { + pushManager.registerPusherWithFcmKey(it) + } + } else { + FcmHelper.getFcmToken(requireContext())?.let { + pushManager.unregisterPusher(it) + session.refreshPushers() + } + } + } + } + findPreference(VectorPreferences.SETTINGS_FDROID_BACKGROUND_SYNC_MODE)?.let { it.onPreferenceClickListener = Preference.OnPreferenceClickListener { val initialMode = vectorPreferences.getFdroidSyncBackgroundMode() @@ -324,10 +339,6 @@ class VectorSettingsNotificationPreferenceFragment @Inject constructor( override fun onPreferenceTreeClick(preference: Preference?): Boolean { return when (preference?.key) { - VectorPreferences.SETTINGS_ENABLE_THIS_DEVICE_PREFERENCE_KEY -> { - updateEnabledForDevice(preference) - true - } VectorPreferences.SETTINGS_ENABLE_ALL_NOTIF_PREFERENCE_KEY -> { updateEnabledForAccount(preference) true @@ -338,32 +349,6 @@ class VectorSettingsNotificationPreferenceFragment @Inject constructor( } } - private fun updateEnabledForDevice(preference: Preference?) { - val switchPref = preference as SwitchPreference - if (switchPref.isChecked) { - FcmHelper.getFcmToken(requireContext())?.let { - pushManager.registerPusherWithFcmKey(it) - } - } else { - FcmHelper.getFcmToken(requireContext())?.let { - lifecycleScope.launch { - runCatching { pushManager.unregisterPusher(it) } - .fold( - { session.refreshPushers() }, - { - if (!isAdded) { - return@fold - } - // revert the check box - switchPref.isChecked = !switchPref.isChecked - Toast.makeText(activity, R.string.unknown_error, Toast.LENGTH_SHORT).show() - } - ) - } - } - } - } - private fun updateEnabledForAccount(preference: Preference?) { val pushRuleService = session val switchPref = preference as SwitchPreference