From 02d54878c315e765d0264d951caedf1752d3a012 Mon Sep 17 00:00:00 2001 From: sim Date: Wed, 24 Aug 2022 22:50:08 +0200 Subject: [PATCH 02/26] Set distributor dialog always cancelable ATM, it uses the default fallback if cancelled --- .../java/im/vector/app/core/pushers/UnifiedPushHelper.kt | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/vector/src/main/java/im/vector/app/core/pushers/UnifiedPushHelper.kt b/vector/src/main/java/im/vector/app/core/pushers/UnifiedPushHelper.kt index 0993485471..de5b881029 100644 --- a/vector/src/main/java/im/vector/app/core/pushers/UnifiedPushHelper.kt +++ b/vector/src/main/java/im/vector/app/core/pushers/UnifiedPushHelper.kt @@ -104,8 +104,7 @@ class UnifiedPushHelper @Inject constructor( pushersManager = pushersManager, onDoneRunnable = onDoneRunnable, distributors = distributors, - unregisterFirst = force, - cancellable = !force + unregisterFirst = force ) } } @@ -122,7 +121,6 @@ class UnifiedPushHelper @Inject constructor( pushersManager, onDoneRunnable, distributors, unregisterFirst = true, - cancellable = true, ) } @@ -132,7 +130,6 @@ class UnifiedPushHelper @Inject constructor( onDoneRunnable: Runnable?, distributors: List, unregisterFirst: Boolean, - cancellable: Boolean, ) { val internalDistributorName = stringProvider.getString( if (fcmHelper.isFirebaseAvailable()) { @@ -176,7 +173,7 @@ class UnifiedPushHelper @Inject constructor( UnifiedPush.registerApp(context) onDoneRunnable?.run() } - .setCancelable(cancellable) + .setCancelable(true) .show() } From a4dd08ddb33f97e4e1bd92bd1eeb32a041698898 Mon Sep 17 00:00:00 2001 From: sim Date: Wed, 24 Aug 2022 23:08:19 +0200 Subject: [PATCH 03/26] Always use register to open the distributor dialog The forced unregistration always happens in register function --- .../app/core/pushers/UnifiedPushHelper.kt | 41 +++++++------------ ...rSettingsNotificationPreferenceFragment.kt | 2 +- .../TestEndpointAsTokenRegistration.kt | 2 +- 3 files changed, 16 insertions(+), 29 deletions(-) diff --git a/vector/src/main/java/im/vector/app/core/pushers/UnifiedPushHelper.kt b/vector/src/main/java/im/vector/app/core/pushers/UnifiedPushHelper.kt index de5b881029..ec646440b6 100644 --- a/vector/src/main/java/im/vector/app/core/pushers/UnifiedPushHelper.kt +++ b/vector/src/main/java/im/vector/app/core/pushers/UnifiedPushHelper.kt @@ -46,6 +46,7 @@ class UnifiedPushHelper @Inject constructor( private val vectorFeatures: VectorFeatures, private val fcmHelper: FcmHelper, ) { + fun register( activity: FragmentActivity, onDoneRunnable: Runnable? = null, @@ -56,7 +57,14 @@ class UnifiedPushHelper @Inject constructor( ) } - fun reRegister( + // If registration is forced: + // * the current distributor (if any) is removed + // * The dialog is opened + // + // The registration is forced in 2 cases : + // * in the settings + // * in the troubleshoot list (doFix) + fun forceRegister( activity: FragmentActivity, pushersManager: PushersManager, onDoneRunnable: Runnable? = null @@ -86,7 +94,8 @@ class UnifiedPushHelper @Inject constructor( // Un-register first unregister(pushersManager) } - if (UnifiedPush.getDistributor(context).isNotEmpty()) { + // the !force should not be needed + if (!force && UnifiedPush.getDistributor(context).isNotEmpty()) { UnifiedPush.registerApp(context) onDoneRunnable?.run() return@launch @@ -94,42 +103,24 @@ class UnifiedPushHelper @Inject constructor( val distributors = UnifiedPush.getDistributors(context) - if (distributors.size == 1 && !force) { + if (!force && distributors.size == 1) { UnifiedPush.saveDistributor(context, distributors.first()) UnifiedPush.registerApp(context) onDoneRunnable?.run() } else { openDistributorDialogInternal( activity = activity, - pushersManager = pushersManager, onDoneRunnable = onDoneRunnable, - distributors = distributors, - unregisterFirst = force + distributors = distributors ) } } } - fun openDistributorDialog( - activity: FragmentActivity, - pushersManager: PushersManager, - onDoneRunnable: Runnable, - ) { - val distributors = UnifiedPush.getDistributors(activity) - openDistributorDialogInternal( - activity, - pushersManager, - onDoneRunnable, distributors, - unregisterFirst = true, - ) - } - private fun openDistributorDialogInternal( activity: FragmentActivity, - pushersManager: PushersManager?, onDoneRunnable: Runnable?, - distributors: List, - unregisterFirst: Boolean, + distributors: List ) { val internalDistributorName = stringProvider.getString( if (fcmHelper.isFirebaseAvailable()) { @@ -157,10 +148,6 @@ class UnifiedPushHelper @Inject constructor( } activity.lifecycleScope.launch { - if (unregisterFirst) { - // Un-register first - unregister(pushersManager) - } UnifiedPush.saveDistributor(context, distributor) Timber.i("Saving distributor: $distributor") UnifiedPush.registerApp(context) 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 a09bb1e6a4..ab25f83a91 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 @@ -158,7 +158,7 @@ class VectorSettingsNotificationPreferenceFragment : if (vectorFeatures.allowExternalUnifiedPushDistributors()) { it.summary = unifiedPushHelper.getCurrentDistributorName() it.onPreferenceClickListener = Preference.OnPreferenceClickListener { - unifiedPushHelper.openDistributorDialog(requireActivity(), pushersManager) { + unifiedPushHelper.forceRegister(requireActivity(), pushersManager) { it.summary = unifiedPushHelper.getCurrentDistributorName() session.pushersService().refreshPushers() refreshBackgroundSyncPrefs() diff --git a/vector/src/main/java/im/vector/app/features/settings/troubleshoot/TestEndpointAsTokenRegistration.kt b/vector/src/main/java/im/vector/app/features/settings/troubleshoot/TestEndpointAsTokenRegistration.kt index 66222f759e..7875e3a21d 100644 --- a/vector/src/main/java/im/vector/app/features/settings/troubleshoot/TestEndpointAsTokenRegistration.kt +++ b/vector/src/main/java/im/vector/app/features/settings/troubleshoot/TestEndpointAsTokenRegistration.kt @@ -60,7 +60,7 @@ class TestEndpointAsTokenRegistration @Inject constructor( ) quickFix = object : TroubleshootQuickFix(R.string.settings_troubleshoot_test_endpoint_registration_quick_fix) { override fun doFix() { - unifiedPushHelper.reRegister( + unifiedPushHelper.forceRegister( context, pushersManager ) From 42c580c249a753603eed224087bdb578e4e53305 Mon Sep 17 00:00:00 2001 From: sim Date: Thu, 25 Aug 2022 08:57:27 +0200 Subject: [PATCH 04/26] Add comments --- .../main/java/im/vector/app/core/pushers/UnifiedPushHelper.kt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/vector/src/main/java/im/vector/app/core/pushers/UnifiedPushHelper.kt b/vector/src/main/java/im/vector/app/core/pushers/UnifiedPushHelper.kt index ec646440b6..c65bc0db5c 100644 --- a/vector/src/main/java/im/vector/app/core/pushers/UnifiedPushHelper.kt +++ b/vector/src/main/java/im/vector/app/core/pushers/UnifiedPushHelper.kt @@ -47,6 +47,8 @@ class UnifiedPushHelper @Inject constructor( private val fcmHelper: FcmHelper, ) { + // Called when the home activity starts + // or when notifications are enabled fun register( activity: FragmentActivity, onDoneRunnable: Runnable? = null, @@ -117,6 +119,8 @@ class UnifiedPushHelper @Inject constructor( } } + // There is no case where this function is called + // with a saved distributor and/or a pusher private fun openDistributorDialogInternal( activity: FragmentActivity, onDoneRunnable: Runnable?, From e2646c3243551e32123ffb706046678b36401f10 Mon Sep 17 00:00:00 2001 From: sim Date: Thu, 25 Aug 2022 08:58:42 +0200 Subject: [PATCH 05/26] Remove never-matched if --- .../main/java/im/vector/app/core/pushers/UnifiedPushHelper.kt | 4 ---- 1 file changed, 4 deletions(-) diff --git a/vector/src/main/java/im/vector/app/core/pushers/UnifiedPushHelper.kt b/vector/src/main/java/im/vector/app/core/pushers/UnifiedPushHelper.kt index c65bc0db5c..8d8c2d5097 100644 --- a/vector/src/main/java/im/vector/app/core/pushers/UnifiedPushHelper.kt +++ b/vector/src/main/java/im/vector/app/core/pushers/UnifiedPushHelper.kt @@ -146,10 +146,6 @@ class UnifiedPushHelper @Inject constructor( .setTitle(stringProvider.getString(R.string.unifiedpush_getdistributors_dialog_title)) .setItems(distributorsName.toTypedArray()) { _, which -> val distributor = distributors[which] - if (distributor == UnifiedPush.getDistributor(context)) { - Timber.d("Same distributor selected again, no action") - return@setItems - } activity.lifecycleScope.launch { UnifiedPush.saveDistributor(context, distributor) From f7ae377874e561cbb31dd80443b83195a74816a3 Mon Sep 17 00:00:00 2001 From: sim Date: Thu, 25 Aug 2022 09:33:26 +0200 Subject: [PATCH 06/26] Add changelog Signed-off-by: sim --- changelog.d/6936.misc | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/6936.misc diff --git a/changelog.d/6936.misc b/changelog.d/6936.misc new file mode 100644 index 0000000000..f032ad9805 --- /dev/null +++ b/changelog.d/6936.misc @@ -0,0 +1 @@ +Smaff refactor of UnifiedPushHelper From 9cf6dd7a88c4fa1c1478d37e49444e632b58d419 Mon Sep 17 00:00:00 2001 From: sim Date: Wed, 7 Sep 2022 18:02:26 +0200 Subject: [PATCH 07/26] Use firebaseReceiver with FCM --- vector-app/src/gplay/AndroidManifest.xml | 14 ++--- vector/build.gradle | 2 +- vector/src/fdroid/AndroidManifest.xml | 14 ----- .../app/push/fcm/EmbeddedFCMDistributor.kt | 27 --------- .../vector/app/push/fcm/FirebaseReceiver.kt | 59 +++++++++++++++++++ vector/src/main/AndroidManifest.xml | 14 +++++ .../core/pushers}/KeepInternalDistributor.kt | 2 +- .../core/pushers/VectorMessagingReceiver.kt | 16 +++++ 8 files changed, 95 insertions(+), 53 deletions(-) delete mode 100644 vector/src/gplay/java/im/vector/app/push/fcm/EmbeddedFCMDistributor.kt create mode 100644 vector/src/gplay/java/im/vector/app/push/fcm/FirebaseReceiver.kt rename vector/src/{fdroid/java/im/vector/app/fdroid/receiver => main/java/im/vector/app/core/pushers}/KeepInternalDistributor.kt (96%) diff --git a/vector-app/src/gplay/AndroidManifest.xml b/vector-app/src/gplay/AndroidManifest.xml index a5f0eae6be..3aa6fbcb2b 100755 --- a/vector-app/src/gplay/AndroidManifest.xml +++ b/vector-app/src/gplay/AndroidManifest.xml @@ -8,18 +8,12 @@ android:name="firebase_analytics_collection_deactivated" android:value="true" /> - - + - - + - - - + diff --git a/vector/build.gradle b/vector/build.gradle index 65adc7089c..a5538053fc 100644 --- a/vector/build.gradle +++ b/vector/build.gradle @@ -257,7 +257,7 @@ dependencies { // UnifiedPush implementation 'com.github.UnifiedPush:android-connector:2.0.1' // UnifiedPush gplay flavor only - gplayImplementation('com.github.UnifiedPush:android-embedded_fcm_distributor:2.1.3') { + gplayImplementation('com.google.firebase:firebase-messaging:23.0.8') { exclude group: 'com.google.firebase', module: 'firebase-core' exclude group: 'com.google.firebase', module: 'firebase-analytics' exclude group: 'com.google.firebase', module: 'firebase-measurement-connector' diff --git a/vector/src/fdroid/AndroidManifest.xml b/vector/src/fdroid/AndroidManifest.xml index 29dac6533e..15db89ca13 100644 --- a/vector/src/fdroid/AndroidManifest.xml +++ b/vector/src/fdroid/AndroidManifest.xml @@ -28,20 +28,6 @@ android:enabled="true" android:exported="false" /> - - - - - - - ).toString().toByteArray()) + intent.putExtra(EXTRA_TOKEN, fcmHelper.getFcmToken()) + baseContext.sendBroadcast(intent) + } +} diff --git a/vector/src/main/AndroidManifest.xml b/vector/src/main/AndroidManifest.xml index c4022576c3..29eef172ae 100644 --- a/vector/src/main/AndroidManifest.xml +++ b/vector/src/main/AndroidManifest.xml @@ -423,6 +423,20 @@ + + + + + + + diff --git a/vector/src/fdroid/java/im/vector/app/fdroid/receiver/KeepInternalDistributor.kt b/vector/src/main/java/im/vector/app/core/pushers/KeepInternalDistributor.kt similarity index 96% rename from vector/src/fdroid/java/im/vector/app/fdroid/receiver/KeepInternalDistributor.kt rename to vector/src/main/java/im/vector/app/core/pushers/KeepInternalDistributor.kt index 3feee8c63b..63725f01a3 100644 --- a/vector/src/fdroid/java/im/vector/app/fdroid/receiver/KeepInternalDistributor.kt +++ b/vector/src/main/java/im/vector/app/core/pushers/KeepInternalDistributor.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package im.vector.app.fdroid.receiver +package im.vector.app.core.pushers import android.content.BroadcastReceiver import android.content.Context diff --git a/vector/src/main/java/im/vector/app/core/pushers/VectorMessagingReceiver.kt b/vector/src/main/java/im/vector/app/core/pushers/VectorMessagingReceiver.kt index 8e88e44627..ec7cb50732 100644 --- a/vector/src/main/java/im/vector/app/core/pushers/VectorMessagingReceiver.kt +++ b/vector/src/main/java/im/vector/app/core/pushers/VectorMessagingReceiver.kt @@ -46,6 +46,8 @@ import org.matrix.android.sdk.api.logger.LoggerTag import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.getRoom import org.matrix.android.sdk.api.session.room.getTimelineEvent +import org.unifiedpush.android.connector.EXTRA_BYTES_MESSAGE +import org.unifiedpush.android.connector.EXTRA_TOKEN import org.unifiedpush.android.connector.MessagingReceiver import timber.log.Timber import javax.inject.Inject @@ -60,6 +62,7 @@ class VectorMessagingReceiver : MessagingReceiver() { @Inject lateinit var notificationDrawerManager: NotificationDrawerManager @Inject lateinit var notifiableEventResolver: NotifiableEventResolver @Inject lateinit var pushersManager: PushersManager + @Inject lateinit var fcmHelper: FcmHelper @Inject lateinit var activeSessionHolder: ActiveSessionHolder @Inject lateinit var vectorPreferences: VectorPreferences @Inject lateinit var vectorDataStore: VectorDataStore @@ -166,6 +169,19 @@ class VectorMessagingReceiver : MessagingReceiver() { } } + override fun onReceive(context: Context, intent: Intent) { + // Injections happens here + super.onReceive(context, intent) + + // if it is from FirebaseReceiver, then the token has been rejected + if (unifiedPushHelper.isEmbeddedDistributor() + && intent.getStringExtra(EXTRA_TOKEN) == fcmHelper.getFcmToken()) { + intent.getByteArrayExtra(EXTRA_BYTES_MESSAGE)?.let { + onMessage(context, it, "") + } + } + } + /** * Internal receive method. * From 5b46c803b21c75ac7782d021d1e500e666dd8f4e Mon Sep 17 00:00:00 2001 From: sim Date: Wed, 7 Sep 2022 18:19:06 +0200 Subject: [PATCH 08/26] Add changelog detail Signed-off-by: sim --- changelog.d/7068.bugfix | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/7068.bugfix diff --git a/changelog.d/7068.bugfix b/changelog.d/7068.bugfix new file mode 100644 index 0000000000..448dcdd46c --- /dev/null +++ b/changelog.d/7068.bugfix @@ -0,0 +1 @@ +Fix push with FCM From 00a04b807e6c77ba4b5d3fd20699f0165458ab68 Mon Sep 17 00:00:00 2001 From: sim Date: Wed, 7 Sep 2022 18:22:34 +0200 Subject: [PATCH 09/26] Lint --- .../im/vector/app/core/pushers/VectorMessagingReceiver.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vector/src/main/java/im/vector/app/core/pushers/VectorMessagingReceiver.kt b/vector/src/main/java/im/vector/app/core/pushers/VectorMessagingReceiver.kt index ec7cb50732..4871b9de74 100644 --- a/vector/src/main/java/im/vector/app/core/pushers/VectorMessagingReceiver.kt +++ b/vector/src/main/java/im/vector/app/core/pushers/VectorMessagingReceiver.kt @@ -174,8 +174,8 @@ class VectorMessagingReceiver : MessagingReceiver() { super.onReceive(context, intent) // if it is from FirebaseReceiver, then the token has been rejected - if (unifiedPushHelper.isEmbeddedDistributor() - && intent.getStringExtra(EXTRA_TOKEN) == fcmHelper.getFcmToken()) { + if (unifiedPushHelper.isEmbeddedDistributor() && + intent.getStringExtra(EXTRA_TOKEN) == fcmHelper.getFcmToken()) { intent.getByteArrayExtra(EXTRA_BYTES_MESSAGE)?.let { onMessage(context, it, "") } From 0b9b8251f940c892afb7bee62162980f2ed02a57 Mon Sep 17 00:00:00 2001 From: sim Date: Thu, 8 Sep 2022 10:34:56 +0200 Subject: [PATCH 10/26] Do not intent to VectorMessagingReceiver from FirebaseReceiver Use VectorMessagingHelper to directly call onMessage --- .../vector/app/push/fcm/FirebaseReceiver.kt | 13 +- .../app/core/pushers/VectorMessagingHelper.kt | 192 ++++++++++++++++++ .../core/pushers/VectorMessagingReceiver.kt | 159 +-------------- 3 files changed, 198 insertions(+), 166 deletions(-) create mode 100644 vector/src/main/java/im/vector/app/core/pushers/VectorMessagingHelper.kt diff --git a/vector/src/gplay/java/im/vector/app/push/fcm/FirebaseReceiver.kt b/vector/src/gplay/java/im/vector/app/push/fcm/FirebaseReceiver.kt index eb983fc8c5..d744634991 100644 --- a/vector/src/gplay/java/im/vector/app/push/fcm/FirebaseReceiver.kt +++ b/vector/src/gplay/java/im/vector/app/push/fcm/FirebaseReceiver.kt @@ -16,7 +16,6 @@ package im.vector.app.push.fcm -import android.content.Intent import com.google.firebase.messaging.FirebaseMessagingService import com.google.firebase.messaging.RemoteMessage import dagger.hilt.android.AndroidEntryPoint @@ -24,11 +23,9 @@ import im.vector.app.R import im.vector.app.core.di.ActiveSessionHolder import im.vector.app.core.pushers.FcmHelper import im.vector.app.core.pushers.PushersManager +import im.vector.app.core.pushers.VectorMessagingHelper import im.vector.app.features.settings.VectorPreferences import org.json.JSONObject -import org.unifiedpush.android.connector.ACTION_MESSAGE -import org.unifiedpush.android.connector.EXTRA_BYTES_MESSAGE -import org.unifiedpush.android.connector.EXTRA_TOKEN import timber.log.Timber import javax.inject.Inject @@ -38,6 +35,7 @@ class FirebaseReceiver : FirebaseMessagingService() { @Inject lateinit var vectorPreferences: VectorPreferences @Inject lateinit var activeSessionHolder: ActiveSessionHolder @Inject lateinit var pushersManager: PushersManager + @Inject lateinit var vectorMessagingHelper: VectorMessagingHelper override fun onNewToken(token: String) { Timber.d("New Firebase token") @@ -49,11 +47,6 @@ class FirebaseReceiver : FirebaseMessagingService() { override fun onMessageReceived(message: RemoteMessage) { Timber.d("New Firebase message") - val intent = Intent() - intent.action = ACTION_MESSAGE - intent.setPackage(baseContext.packageName) - intent.putExtra(EXTRA_BYTES_MESSAGE, JSONObject(message.data as Map<*, *>).toString().toByteArray()) - intent.putExtra(EXTRA_TOKEN, fcmHelper.getFcmToken()) - baseContext.sendBroadcast(intent) + vectorMessagingHelper.onMessage(JSONObject(message.data as Map<*, *>).toString()) } } diff --git a/vector/src/main/java/im/vector/app/core/pushers/VectorMessagingHelper.kt b/vector/src/main/java/im/vector/app/core/pushers/VectorMessagingHelper.kt new file mode 100644 index 0000000000..80d4e91a76 --- /dev/null +++ b/vector/src/main/java/im/vector/app/core/pushers/VectorMessagingHelper.kt @@ -0,0 +1,192 @@ +/* + * 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.core.pushers + +import android.content.Context +import android.content.Intent +import android.os.Handler +import android.os.Looper +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.ProcessLifecycleOwner +import androidx.localbroadcastmanager.content.LocalBroadcastManager +import dagger.hilt.android.AndroidEntryPoint +import im.vector.app.core.di.ActiveSessionHolder +import im.vector.app.core.network.WifiDetector +import im.vector.app.core.pushers.model.PushData +import im.vector.app.core.resources.BuildMeta +import im.vector.app.features.notifications.NotifiableEventResolver +import im.vector.app.features.notifications.NotificationActionIds +import im.vector.app.features.notifications.NotificationDrawerManager +import im.vector.app.features.settings.VectorDataStore +import im.vector.app.features.settings.VectorPreferences +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.SupervisorJob +import kotlinx.coroutines.launch +import kotlinx.coroutines.runBlocking +import org.matrix.android.sdk.api.extensions.tryOrNull +import org.matrix.android.sdk.api.logger.LoggerTag +import org.matrix.android.sdk.api.session.Session +import org.matrix.android.sdk.api.session.getRoom +import org.matrix.android.sdk.api.session.room.getTimelineEvent +import timber.log.Timber +import javax.inject.Inject + +private val loggerTag = LoggerTag("Push", LoggerTag.SYNC) + +/** + * Hilt injection happen at super.onReceive(). + */ + +class VectorMessagingHelper @Inject constructor( + private val notificationDrawerManager: NotificationDrawerManager, + private val notifiableEventResolver: NotifiableEventResolver, + private val activeSessionHolder: ActiveSessionHolder, + private val vectorPreferences: VectorPreferences, + private val vectorDataStore: VectorDataStore, + private val wifiDetector: WifiDetector, + private val unifiedPushHelper: UnifiedPushHelper, + private val pushParser: PushParser, + private val actionIds: NotificationActionIds, + private val context: Context, + private val buildMeta: BuildMeta +) { + + private val coroutineScope = CoroutineScope(SupervisorJob()) + + // UI handler + private val mUIHandler by lazy { + Handler(Looper.getMainLooper()) + } + + /** + * Called when message is received. + * + * @param context the Android context + * @param message the message + */ + fun onMessage(message: String) { + Timber.tag(loggerTag.value).d("## onMessage() received") + + if (buildMeta.lowPrivacyLoggingEnabled) { + Timber.tag(loggerTag.value).d("## onMessage() $message") + } + + runBlocking { + vectorDataStore.incrementPushCounter() + } + + val pushData = pushParser.parseData(message, unifiedPushHelper.isEmbeddedDistributor()) + ?: return Unit.also { Timber.tag(loggerTag.value).w("Invalid received data Json format") } + + // Diagnostic Push + if (pushData.eventId == PushersManager.TEST_EVENT_ID) { + val intent = Intent(actionIds.push) + LocalBroadcastManager.getInstance(context).sendBroadcast(intent) + return + } + + if (!vectorPreferences.areNotificationEnabledForDevice()) { + Timber.tag(loggerTag.value).i("Notification are disabled for this device") + return + } + + mUIHandler.post { + if (ProcessLifecycleOwner.get().lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED)) { + // we are in foreground, let the sync do the things? + Timber.tag(loggerTag.value).d("PUSH received in a foreground state, ignore") + } else { + coroutineScope.launch(Dispatchers.IO) { onMessageReceivedInternal(pushData) } + } + } + } + + /** + * Internal receive method. + * + * @param pushData Object containing message data. + */ + private suspend fun onMessageReceivedInternal(pushData: PushData) { + try { + if (buildMeta.lowPrivacyLoggingEnabled) { + Timber.tag(loggerTag.value).d("## onMessageReceivedInternal() : $pushData") + } else { + Timber.tag(loggerTag.value).d("## onMessageReceivedInternal()") + } + + val session = activeSessionHolder.getOrInitializeSession(startSync = false) + + if (session == null) { + Timber.tag(loggerTag.value).w("## Can't sync from push, no current session") + } else { + if (isEventAlreadyKnown(pushData)) { + Timber.tag(loggerTag.value).d("Ignoring push, event already known") + } else { + // Try to get the Event content faster + Timber.tag(loggerTag.value).d("Requesting event in fast lane") + getEventFastLane(session, pushData) + + Timber.tag(loggerTag.value).d("Requesting background sync") + session.syncService().requireBackgroundSync() + } + } + } catch (e: Exception) { + Timber.tag(loggerTag.value).e(e, "## onMessageReceivedInternal() failed") + } + } + + private suspend fun getEventFastLane(session: Session, pushData: PushData) { + pushData.roomId ?: return + pushData.eventId ?: return + + // If the room is currently displayed, we will not show a notification, so no need to get the Event faster + if (notificationDrawerManager.shouldIgnoreMessageEventInRoom(pushData.roomId)) { + return + } + + if (wifiDetector.isConnectedToWifi().not()) { + Timber.tag(loggerTag.value).d("No WiFi network, do not get Event") + return + } + + Timber.tag(loggerTag.value).d("Fast lane: start request") + val event = tryOrNull { session.eventService().getEvent(pushData.roomId, pushData.eventId) } ?: return + + val resolvedEvent = notifiableEventResolver.resolveInMemoryEvent(session, event, canBeReplaced = true) + + resolvedEvent + ?.also { Timber.tag(loggerTag.value).d("Fast lane: notify drawer") } + ?.let { + notificationDrawerManager.updateEvents { it.onNotifiableEventReceived(resolvedEvent) } + } + } + + // check if the event was not yet received + // a previous catchup might have already retrieved the notified event + private fun isEventAlreadyKnown(pushData: PushData): Boolean { + if (pushData.eventId != null && pushData.roomId != null) { + try { + val session = activeSessionHolder.getSafeActiveSession() ?: return false + val room = session.getRoom(pushData.roomId) ?: return false + return room.getTimelineEvent(pushData.eventId) != null + } catch (e: Exception) { + Timber.tag(loggerTag.value).e(e, "## isEventAlreadyKnown() : failed to check if the event was already defined") + } + } + return false + } +} diff --git a/vector/src/main/java/im/vector/app/core/pushers/VectorMessagingReceiver.kt b/vector/src/main/java/im/vector/app/core/pushers/VectorMessagingReceiver.kt index 4871b9de74..e99e3fdd16 100644 --- a/vector/src/main/java/im/vector/app/core/pushers/VectorMessagingReceiver.kt +++ b/vector/src/main/java/im/vector/app/core/pushers/VectorMessagingReceiver.kt @@ -17,37 +17,17 @@ package im.vector.app.core.pushers import android.content.Context -import android.content.Intent -import android.os.Handler -import android.os.Looper import android.widget.Toast -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.ProcessLifecycleOwner -import androidx.localbroadcastmanager.content.LocalBroadcastManager import dagger.hilt.android.AndroidEntryPoint import im.vector.app.core.di.ActiveSessionHolder -import im.vector.app.core.network.WifiDetector -import im.vector.app.core.pushers.model.PushData -import im.vector.app.core.resources.BuildMeta import im.vector.app.core.services.GuardServiceStarter -import im.vector.app.features.notifications.NotifiableEventResolver -import im.vector.app.features.notifications.NotificationActionIds -import im.vector.app.features.notifications.NotificationDrawerManager import im.vector.app.features.settings.BackgroundSyncMode -import im.vector.app.features.settings.VectorDataStore import im.vector.app.features.settings.VectorPreferences import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking -import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.api.logger.LoggerTag -import org.matrix.android.sdk.api.session.Session -import org.matrix.android.sdk.api.session.getRoom -import org.matrix.android.sdk.api.session.room.getTimelineEvent -import org.unifiedpush.android.connector.EXTRA_BYTES_MESSAGE -import org.unifiedpush.android.connector.EXTRA_TOKEN import org.unifiedpush.android.connector.MessagingReceiver import timber.log.Timber import javax.inject.Inject @@ -59,28 +39,16 @@ private val loggerTag = LoggerTag("Push", LoggerTag.SYNC) */ @AndroidEntryPoint class VectorMessagingReceiver : MessagingReceiver() { - @Inject lateinit var notificationDrawerManager: NotificationDrawerManager - @Inject lateinit var notifiableEventResolver: NotifiableEventResolver @Inject lateinit var pushersManager: PushersManager - @Inject lateinit var fcmHelper: FcmHelper @Inject lateinit var activeSessionHolder: ActiveSessionHolder @Inject lateinit var vectorPreferences: VectorPreferences - @Inject lateinit var vectorDataStore: VectorDataStore - @Inject lateinit var wifiDetector: WifiDetector + @Inject lateinit var vectorMessagingHelper: VectorMessagingHelper @Inject lateinit var guardServiceStarter: GuardServiceStarter - @Inject lateinit var unifiedPushHelper: UnifiedPushHelper @Inject lateinit var unifiedPushStore: UnifiedPushStore - @Inject lateinit var pushParser: PushParser - @Inject lateinit var actionIds: NotificationActionIds - @Inject lateinit var buildMeta: BuildMeta + @Inject lateinit var unifiedPushHelper: UnifiedPushHelper private val coroutineScope = CoroutineScope(SupervisorJob()) - // UI handler - private val mUIHandler by lazy { - Handler(Looper.getMainLooper()) - } - /** * Called when message is received. * @@ -89,40 +57,7 @@ class VectorMessagingReceiver : MessagingReceiver() { * @param instance connection, for multi-account */ override fun onMessage(context: Context, message: ByteArray, instance: String) { - Timber.tag(loggerTag.value).d("## onMessage() received") - - val sMessage = String(message) - if (buildMeta.lowPrivacyLoggingEnabled) { - Timber.tag(loggerTag.value).d("## onMessage() $sMessage") - } - - runBlocking { - vectorDataStore.incrementPushCounter() - } - - val pushData = pushParser.parseData(sMessage, unifiedPushHelper.isEmbeddedDistributor()) - ?: return Unit.also { Timber.tag(loggerTag.value).w("Invalid received data Json format") } - - // Diagnostic Push - if (pushData.eventId == PushersManager.TEST_EVENT_ID) { - val intent = Intent(actionIds.push) - LocalBroadcastManager.getInstance(context).sendBroadcast(intent) - return - } - - if (!vectorPreferences.areNotificationEnabledForDevice()) { - Timber.tag(loggerTag.value).i("Notification are disabled for this device") - return - } - - mUIHandler.post { - if (ProcessLifecycleOwner.get().lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED)) { - // we are in foreground, let the sync do the things? - Timber.tag(loggerTag.value).d("PUSH received in a foreground state, ignore") - } else { - coroutineScope.launch(Dispatchers.IO) { onMessageReceivedInternal(pushData) } - } - } + vectorMessagingHelper.onMessage(String(message)) } override fun onNewEndpoint(context: Context, endpoint: String, instance: String) { @@ -168,92 +103,4 @@ class VectorMessagingReceiver : MessagingReceiver() { } } } - - override fun onReceive(context: Context, intent: Intent) { - // Injections happens here - super.onReceive(context, intent) - - // if it is from FirebaseReceiver, then the token has been rejected - if (unifiedPushHelper.isEmbeddedDistributor() && - intent.getStringExtra(EXTRA_TOKEN) == fcmHelper.getFcmToken()) { - intent.getByteArrayExtra(EXTRA_BYTES_MESSAGE)?.let { - onMessage(context, it, "") - } - } - } - - /** - * Internal receive method. - * - * @param pushData Object containing message data. - */ - private suspend fun onMessageReceivedInternal(pushData: PushData) { - try { - if (buildMeta.lowPrivacyLoggingEnabled) { - Timber.tag(loggerTag.value).d("## onMessageReceivedInternal() : $pushData") - } else { - Timber.tag(loggerTag.value).d("## onMessageReceivedInternal()") - } - - val session = activeSessionHolder.getOrInitializeSession(startSync = false) - - if (session == null) { - Timber.tag(loggerTag.value).w("## Can't sync from push, no current session") - } else { - if (isEventAlreadyKnown(pushData)) { - Timber.tag(loggerTag.value).d("Ignoring push, event already known") - } else { - // Try to get the Event content faster - Timber.tag(loggerTag.value).d("Requesting event in fast lane") - getEventFastLane(session, pushData) - - Timber.tag(loggerTag.value).d("Requesting background sync") - session.syncService().requireBackgroundSync() - } - } - } catch (e: Exception) { - Timber.tag(loggerTag.value).e(e, "## onMessageReceivedInternal() failed") - } - } - - private suspend fun getEventFastLane(session: Session, pushData: PushData) { - pushData.roomId ?: return - pushData.eventId ?: return - - // If the room is currently displayed, we will not show a notification, so no need to get the Event faster - if (notificationDrawerManager.shouldIgnoreMessageEventInRoom(pushData.roomId)) { - return - } - - if (wifiDetector.isConnectedToWifi().not()) { - Timber.tag(loggerTag.value).d("No WiFi network, do not get Event") - return - } - - Timber.tag(loggerTag.value).d("Fast lane: start request") - val event = tryOrNull { session.eventService().getEvent(pushData.roomId, pushData.eventId) } ?: return - - val resolvedEvent = notifiableEventResolver.resolveInMemoryEvent(session, event, canBeReplaced = true) - - resolvedEvent - ?.also { Timber.tag(loggerTag.value).d("Fast lane: notify drawer") } - ?.let { - notificationDrawerManager.updateEvents { it.onNotifiableEventReceived(resolvedEvent) } - } - } - - // check if the event was not yet received - // a previous catchup might have already retrieved the notified event - private fun isEventAlreadyKnown(pushData: PushData): Boolean { - if (pushData.eventId != null && pushData.roomId != null) { - try { - val session = activeSessionHolder.getSafeActiveSession() ?: return false - val room = session.getRoom(pushData.roomId) ?: return false - return room.getTimelineEvent(pushData.eventId) != null - } catch (e: Exception) { - Timber.tag(loggerTag.value).e(e, "## isEventAlreadyKnown() : failed to check if the event was already defined") - } - } - return false - } } From 6ba963b5529d386b53395b2e9c5bf5fe5ea10784 Mon Sep 17 00:00:00 2001 From: sim Date: Thu, 8 Sep 2022 10:35:19 +0200 Subject: [PATCH 11/26] Fix gateway --- .../java/im/vector/app/push/fcm/FirebaseReceiver.kt | 2 +- .../im/vector/app/core/pushers/PushersManager.kt | 5 +++-- .../im/vector/app/core/pushers/UnifiedPushHelper.kt | 12 ++++++++++-- .../im/vector/app/core/pushers/UnifiedPushStore.kt | 9 ++++++--- .../app/core/pushers/VectorMessagingReceiver.kt | 6 +++--- .../troubleshoot/TestEndpointAsTokenRegistration.kt | 3 +-- 6 files changed, 24 insertions(+), 13 deletions(-) diff --git a/vector/src/gplay/java/im/vector/app/push/fcm/FirebaseReceiver.kt b/vector/src/gplay/java/im/vector/app/push/fcm/FirebaseReceiver.kt index d744634991..92473caa1e 100644 --- a/vector/src/gplay/java/im/vector/app/push/fcm/FirebaseReceiver.kt +++ b/vector/src/gplay/java/im/vector/app/push/fcm/FirebaseReceiver.kt @@ -41,7 +41,7 @@ class FirebaseReceiver : FirebaseMessagingService() { Timber.d("New Firebase token") fcmHelper.storeFcmToken(token) if (vectorPreferences.areNotificationEnabledForDevice() && activeSessionHolder.hasActiveSession()) { - pushersManager.enqueueRegisterPusher(token, getString(R.string.default_push_gateway_http_url)) + pushersManager.enqueueRegisterPusher(token, getString(R.string.pusher_http_url)) } } 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 91ab58207d..98412497fc 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 @@ -30,6 +30,7 @@ private const val DEFAULT_PUSHER_FILE_TAG = "mobile" class PushersManager @Inject constructor( private val unifiedPushStore: UnifiedPushStore, + private val unifiedPushHelper: UnifiedPushHelper, private val activeSessionHolder: ActiveSessionHolder, private val localeProvider: LocaleProvider, private val stringProvider: StringProvider, @@ -39,9 +40,9 @@ class PushersManager @Inject constructor( val currentSession = activeSessionHolder.getActiveSession() currentSession.pushersService().testPush( - unifiedPushStore.getPushGateway()!!, + unifiedPushStore.getPushGateway(), stringProvider.getString(R.string.pusher_app_id), - unifiedPushStore.getEndpointOrToken().orEmpty(), + unifiedPushHelper.getEndpointOrToken().orEmpty(), TEST_EVENT_ID ) } diff --git a/vector/src/main/java/im/vector/app/core/pushers/UnifiedPushHelper.kt b/vector/src/main/java/im/vector/app/core/pushers/UnifiedPushHelper.kt index 0993485471..a190ed7843 100644 --- a/vector/src/main/java/im/vector/app/core/pushers/UnifiedPushHelper.kt +++ b/vector/src/main/java/im/vector/app/core/pushers/UnifiedPushHelper.kt @@ -184,7 +184,10 @@ class UnifiedPushHelper @Inject constructor( val mode = BackgroundSyncMode.FDROID_BACKGROUND_SYNC_MODE_FOR_REALTIME vectorPreferences.setFdroidSyncBackgroundMode(mode) try { - pushersManager?.unregisterPusher(unifiedPushStore.getEndpointOrToken().orEmpty()) + getEndpointOrToken()?.let { + Timber.d("Removing $it") + pushersManager?.unregisterPusher(it) + } } catch (e: Exception) { Timber.d(e, "Probably unregistering a non existing pusher") } @@ -261,7 +264,7 @@ class UnifiedPushHelper @Inject constructor( } fun getPrivacyFriendlyUpEndpoint(): String? { - val endpoint = unifiedPushStore.getEndpointOrToken() + val endpoint = getEndpointOrToken() if (endpoint.isNullOrEmpty()) return null if (isEmbeddedDistributor()) { return endpoint @@ -274,4 +277,9 @@ class UnifiedPushHelper @Inject constructor( null } } + + fun getEndpointOrToken(): String? { + return if (isEmbeddedDistributor()) fcmHelper.getFcmToken() + else unifiedPushStore.getEndpoint() + } } diff --git a/vector/src/main/java/im/vector/app/core/pushers/UnifiedPushStore.kt b/vector/src/main/java/im/vector/app/core/pushers/UnifiedPushStore.kt index 07d291a723..86247cd749 100644 --- a/vector/src/main/java/im/vector/app/core/pushers/UnifiedPushStore.kt +++ b/vector/src/main/java/im/vector/app/core/pushers/UnifiedPushStore.kt @@ -18,11 +18,13 @@ package im.vector.app.core.pushers import android.content.Context import androidx.core.content.edit +import im.vector.app.R import im.vector.app.core.di.DefaultSharedPreferences import javax.inject.Inject class UnifiedPushStore @Inject constructor( - context: Context, + val context: Context, + val fcmHelper: FcmHelper ) { private val defaultPrefs = DefaultSharedPreferences.getInstance(context) @@ -31,7 +33,7 @@ class UnifiedPushStore @Inject constructor( * * @return the UnifiedPush Endpoint or null if not received */ - fun getEndpointOrToken(): String? { + fun getEndpoint(): String? { return defaultPrefs.getString(PREFS_ENDPOINT_OR_TOKEN, null) } @@ -51,8 +53,9 @@ class UnifiedPushStore @Inject constructor( * * @return the Push Gateway or null if not defined */ - fun getPushGateway(): String? { + fun getPushGateway(): String { return defaultPrefs.getString(PREFS_PUSH_GATEWAY, null) + ?: context.getString(R.string.pusher_http_url) } /** diff --git a/vector/src/main/java/im/vector/app/core/pushers/VectorMessagingReceiver.kt b/vector/src/main/java/im/vector/app/core/pushers/VectorMessagingReceiver.kt index e99e3fdd16..4ee317bce7 100644 --- a/vector/src/main/java/im/vector/app/core/pushers/VectorMessagingReceiver.kt +++ b/vector/src/main/java/im/vector/app/core/pushers/VectorMessagingReceiver.kt @@ -65,11 +65,11 @@ class VectorMessagingReceiver : MessagingReceiver() { if (vectorPreferences.areNotificationEnabledForDevice() && activeSessionHolder.hasActiveSession()) { // If the endpoint has changed // or the gateway has changed - if (unifiedPushStore.getEndpointOrToken() != endpoint) { + if (unifiedPushHelper.getEndpointOrToken() != endpoint) { unifiedPushStore.storeUpEndpoint(endpoint) coroutineScope.launch { unifiedPushHelper.storeCustomOrDefaultGateway(endpoint) { - unifiedPushStore.getPushGateway()?.let { + unifiedPushStore.getPushGateway().let { pushersManager.enqueueRegisterPusher(endpoint, it) } } @@ -97,7 +97,7 @@ class VectorMessagingReceiver : MessagingReceiver() { guardServiceStarter.start() runBlocking { try { - pushersManager.unregisterPusher(unifiedPushStore.getEndpointOrToken().orEmpty()) + pushersManager.unregisterPusher(unifiedPushHelper.getEndpointOrToken().orEmpty()) } catch (e: Exception) { Timber.tag(loggerTag.value).d("Probably unregistering a non existing pusher") } diff --git a/vector/src/main/java/im/vector/app/features/settings/troubleshoot/TestEndpointAsTokenRegistration.kt b/vector/src/main/java/im/vector/app/features/settings/troubleshoot/TestEndpointAsTokenRegistration.kt index 66222f759e..dbabe8a691 100644 --- a/vector/src/main/java/im/vector/app/features/settings/troubleshoot/TestEndpointAsTokenRegistration.kt +++ b/vector/src/main/java/im/vector/app/features/settings/troubleshoot/TestEndpointAsTokenRegistration.kt @@ -37,12 +37,11 @@ class TestEndpointAsTokenRegistration @Inject constructor( private val pushersManager: PushersManager, private val activeSessionHolder: ActiveSessionHolder, private val unifiedPushHelper: UnifiedPushHelper, - private val unifiedPushStore: UnifiedPushStore, ) : TroubleshootTest(R.string.settings_troubleshoot_test_endpoint_registration_title) { override fun perform(activityResultLauncher: ActivityResultLauncher) { // Check if we have a registered pusher for this token - val endpoint = unifiedPushStore.getEndpointOrToken() ?: run { + val endpoint = unifiedPushHelper.getEndpointOrToken() ?: run { status = TestStatus.FAILED return } From 94e2a0a3e31b885aa43732094c84ed7889e7f6c5 Mon Sep 17 00:00:00 2001 From: sim Date: Thu, 8 Sep 2022 10:58:08 +0200 Subject: [PATCH 12/26] Ensure FCM token is always retrieved --- .../im/vector/app/features/home/HomeActivity.kt | 4 ++-- ...ctorSettingsNotificationPreferenceFragment.kt | 16 ++++++++++++++++ .../TestEndpointAsTokenRegistration.kt | 1 - 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt b/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt index 78b4364f38..52a02eba6b 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt @@ -128,7 +128,7 @@ class HomeActivity : @Inject lateinit var activeSessionHolder: ActiveSessionHolder @Inject lateinit var vectorUncaughtExceptionHandler: VectorUncaughtExceptionHandler - @Inject lateinit var pushManager: PushersManager + @Inject lateinit var pushersManager: PushersManager @Inject lateinit var notificationDrawerManager: NotificationDrawerManager @Inject lateinit var vectorPreferences: VectorPreferences @Inject lateinit var popupAlertManager: PopupAlertManager @@ -208,7 +208,7 @@ class HomeActivity : if (unifiedPushHelper.isEmbeddedDistributor()) { fcmHelper.ensureFcmTokenIsRetrieved( this, - pushManager, + pushersManager, vectorPreferences.areNotificationEnabledForDevice() ) } 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 ab25f83a91..37d09d02c9 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 @@ -38,6 +38,7 @@ import im.vector.app.core.preference.VectorEditTextPreference import im.vector.app.core.preference.VectorPreference import im.vector.app.core.preference.VectorPreferenceCategory import im.vector.app.core.preference.VectorSwitchPreference +import im.vector.app.core.pushers.FcmHelper import im.vector.app.core.pushers.PushersManager import im.vector.app.core.pushers.UnifiedPushHelper import im.vector.app.core.services.GuardServiceStarter @@ -70,6 +71,7 @@ class VectorSettingsNotificationPreferenceFragment : @Inject lateinit var unifiedPushHelper: UnifiedPushHelper @Inject lateinit var pushersManager: PushersManager + @Inject lateinit var fcmHelper: FcmHelper @Inject lateinit var activeSessionHolder: ActiveSessionHolder @Inject lateinit var vectorPreferences: VectorPreferences @Inject lateinit var guardServiceStarter: GuardServiceStarter @@ -106,6 +108,13 @@ class VectorSettingsNotificationPreferenceFragment : if (isChecked) { unifiedPushHelper.register(requireActivity()) { // Update the summary + if (unifiedPushHelper.isEmbeddedDistributor()) { + fcmHelper.ensureFcmTokenIsRetrieved( + requireActivity(), + pushersManager, + vectorPreferences.areNotificationEnabledForDevice() + ) + } findPreference(VectorPreferences.SETTINGS_NOTIFICATION_METHOD_KEY) ?.summary = unifiedPushHelper.getCurrentDistributorName() } @@ -159,6 +168,13 @@ class VectorSettingsNotificationPreferenceFragment : it.summary = unifiedPushHelper.getCurrentDistributorName() it.onPreferenceClickListener = Preference.OnPreferenceClickListener { unifiedPushHelper.forceRegister(requireActivity(), pushersManager) { + if (unifiedPushHelper.isEmbeddedDistributor()) { + fcmHelper.ensureFcmTokenIsRetrieved( + requireActivity(), + pushersManager, + vectorPreferences.areNotificationEnabledForDevice() + ) + } it.summary = unifiedPushHelper.getCurrentDistributorName() session.pushersService().refreshPushers() refreshBackgroundSyncPrefs() diff --git a/vector/src/main/java/im/vector/app/features/settings/troubleshoot/TestEndpointAsTokenRegistration.kt b/vector/src/main/java/im/vector/app/features/settings/troubleshoot/TestEndpointAsTokenRegistration.kt index d09a125b81..78eb372fef 100644 --- a/vector/src/main/java/im/vector/app/features/settings/troubleshoot/TestEndpointAsTokenRegistration.kt +++ b/vector/src/main/java/im/vector/app/features/settings/troubleshoot/TestEndpointAsTokenRegistration.kt @@ -26,7 +26,6 @@ import im.vector.app.R import im.vector.app.core.di.ActiveSessionHolder import im.vector.app.core.pushers.PushersManager import im.vector.app.core.pushers.UnifiedPushHelper -import im.vector.app.core.pushers.UnifiedPushStore import im.vector.app.core.resources.StringProvider import org.matrix.android.sdk.api.session.pushers.PusherState import javax.inject.Inject From 3267cbbf78053ebbf5f1bf657e7fff3689d3bcf9 Mon Sep 17 00:00:00 2001 From: sim Date: Thu, 8 Sep 2022 11:15:41 +0200 Subject: [PATCH 13/26] Lint --- .../java/im/vector/app/core/pushers/VectorMessagingHelper.kt | 2 -- 1 file changed, 2 deletions(-) diff --git a/vector/src/main/java/im/vector/app/core/pushers/VectorMessagingHelper.kt b/vector/src/main/java/im/vector/app/core/pushers/VectorMessagingHelper.kt index 80d4e91a76..a2fa1162f1 100644 --- a/vector/src/main/java/im/vector/app/core/pushers/VectorMessagingHelper.kt +++ b/vector/src/main/java/im/vector/app/core/pushers/VectorMessagingHelper.kt @@ -23,7 +23,6 @@ import android.os.Looper import androidx.lifecycle.Lifecycle import androidx.lifecycle.ProcessLifecycleOwner import androidx.localbroadcastmanager.content.LocalBroadcastManager -import dagger.hilt.android.AndroidEntryPoint import im.vector.app.core.di.ActiveSessionHolder import im.vector.app.core.network.WifiDetector import im.vector.app.core.pushers.model.PushData @@ -76,7 +75,6 @@ class VectorMessagingHelper @Inject constructor( /** * Called when message is received. * - * @param context the Android context * @param message the message */ fun onMessage(message: String) { From 48498020a0c8b602058cf9028a957914c97ee828 Mon Sep 17 00:00:00 2001 From: sim Date: Thu, 8 Sep 2022 11:23:15 +0200 Subject: [PATCH 14/26] Ensure FCM always have the good gateway --- .../main/java/im/vector/app/core/pushers/PushersManager.kt | 3 +-- .../java/im/vector/app/core/pushers/UnifiedPushHelper.kt | 5 +++++ .../java/im/vector/app/core/pushers/UnifiedPushStore.kt | 4 +--- .../im/vector/app/core/pushers/VectorMessagingReceiver.kt | 2 +- .../settings/troubleshoot/TestUnifiedPushGateway.kt | 6 +++--- 5 files changed, 11 insertions(+), 9 deletions(-) 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 98412497fc..c77f454ab0 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 @@ -29,7 +29,6 @@ import kotlin.math.abs private const val DEFAULT_PUSHER_FILE_TAG = "mobile" class PushersManager @Inject constructor( - private val unifiedPushStore: UnifiedPushStore, private val unifiedPushHelper: UnifiedPushHelper, private val activeSessionHolder: ActiveSessionHolder, private val localeProvider: LocaleProvider, @@ -40,7 +39,7 @@ class PushersManager @Inject constructor( val currentSession = activeSessionHolder.getActiveSession() currentSession.pushersService().testPush( - unifiedPushStore.getPushGateway(), + unifiedPushHelper.getPushGateway() ?: return, stringProvider.getString(R.string.pusher_app_id), unifiedPushHelper.getEndpointOrToken().orEmpty(), TEST_EVENT_ID diff --git a/vector/src/main/java/im/vector/app/core/pushers/UnifiedPushHelper.kt b/vector/src/main/java/im/vector/app/core/pushers/UnifiedPushHelper.kt index bc8dc70668..99987ddb6c 100644 --- a/vector/src/main/java/im/vector/app/core/pushers/UnifiedPushHelper.kt +++ b/vector/src/main/java/im/vector/app/core/pushers/UnifiedPushHelper.kt @@ -266,4 +266,9 @@ class UnifiedPushHelper @Inject constructor( return if (isEmbeddedDistributor()) fcmHelper.getFcmToken() else unifiedPushStore.getEndpoint() } + + fun getPushGateway(): String? { + return if (isEmbeddedDistributor()) context.getString(R.string.pusher_http_url) + else unifiedPushStore.getPushGateway() + } } diff --git a/vector/src/main/java/im/vector/app/core/pushers/UnifiedPushStore.kt b/vector/src/main/java/im/vector/app/core/pushers/UnifiedPushStore.kt index 86247cd749..d9c6bf3159 100644 --- a/vector/src/main/java/im/vector/app/core/pushers/UnifiedPushStore.kt +++ b/vector/src/main/java/im/vector/app/core/pushers/UnifiedPushStore.kt @@ -18,7 +18,6 @@ package im.vector.app.core.pushers import android.content.Context import androidx.core.content.edit -import im.vector.app.R import im.vector.app.core.di.DefaultSharedPreferences import javax.inject.Inject @@ -53,9 +52,8 @@ class UnifiedPushStore @Inject constructor( * * @return the Push Gateway or null if not defined */ - fun getPushGateway(): String { + fun getPushGateway(): String? { return defaultPrefs.getString(PREFS_PUSH_GATEWAY, null) - ?: context.getString(R.string.pusher_http_url) } /** diff --git a/vector/src/main/java/im/vector/app/core/pushers/VectorMessagingReceiver.kt b/vector/src/main/java/im/vector/app/core/pushers/VectorMessagingReceiver.kt index 4ee317bce7..1aa9c3e891 100644 --- a/vector/src/main/java/im/vector/app/core/pushers/VectorMessagingReceiver.kt +++ b/vector/src/main/java/im/vector/app/core/pushers/VectorMessagingReceiver.kt @@ -69,7 +69,7 @@ class VectorMessagingReceiver : MessagingReceiver() { unifiedPushStore.storeUpEndpoint(endpoint) coroutineScope.launch { unifiedPushHelper.storeCustomOrDefaultGateway(endpoint) { - unifiedPushStore.getPushGateway().let { + unifiedPushHelper.getPushGateway()?.let { pushersManager.enqueueRegisterPusher(endpoint, it) } } diff --git a/vector/src/main/java/im/vector/app/features/settings/troubleshoot/TestUnifiedPushGateway.kt b/vector/src/main/java/im/vector/app/features/settings/troubleshoot/TestUnifiedPushGateway.kt index 38f14951b4..19a4fd188f 100644 --- a/vector/src/main/java/im/vector/app/features/settings/troubleshoot/TestUnifiedPushGateway.kt +++ b/vector/src/main/java/im/vector/app/features/settings/troubleshoot/TestUnifiedPushGateway.kt @@ -19,19 +19,19 @@ package im.vector.app.features.settings.troubleshoot import android.content.Intent import androidx.activity.result.ActivityResultLauncher import im.vector.app.R -import im.vector.app.core.pushers.UnifiedPushStore +import im.vector.app.core.pushers.UnifiedPushHelper import im.vector.app.core.resources.StringProvider import javax.inject.Inject class TestUnifiedPushGateway @Inject constructor( - private val unifiedPushStore: UnifiedPushStore, + private val unifiedPushHelper: UnifiedPushHelper, private val stringProvider: StringProvider ) : TroubleshootTest(R.string.settings_troubleshoot_test_current_gateway_title) { override fun perform(activityResultLauncher: ActivityResultLauncher) { description = stringProvider.getString( R.string.settings_troubleshoot_test_current_gateway, - unifiedPushStore.getPushGateway() + unifiedPushHelper.getPushGateway() ) status = TestStatus.SUCCESS } From f65074b3c572d45fdeb6a3723672f9d7099bbf11 Mon Sep 17 00:00:00 2001 From: sim Date: Thu, 8 Sep 2022 11:46:34 +0200 Subject: [PATCH 15/26] Update pusher with FCM new token only if using FCM --- .../java/im/vector/app/push/fcm/FirebaseReceiver.kt | 8 +++++++- .../im/vector/app/core/pushers/UnifiedPushHelper.kt | 10 ++++++++-- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/vector/src/gplay/java/im/vector/app/push/fcm/FirebaseReceiver.kt b/vector/src/gplay/java/im/vector/app/push/fcm/FirebaseReceiver.kt index 92473caa1e..0b4d1f1f43 100644 --- a/vector/src/gplay/java/im/vector/app/push/fcm/FirebaseReceiver.kt +++ b/vector/src/gplay/java/im/vector/app/push/fcm/FirebaseReceiver.kt @@ -23,6 +23,7 @@ import im.vector.app.R import im.vector.app.core.di.ActiveSessionHolder import im.vector.app.core.pushers.FcmHelper import im.vector.app.core.pushers.PushersManager +import im.vector.app.core.pushers.UnifiedPushHelper import im.vector.app.core.pushers.VectorMessagingHelper import im.vector.app.features.settings.VectorPreferences import org.json.JSONObject @@ -36,11 +37,16 @@ class FirebaseReceiver : FirebaseMessagingService() { @Inject lateinit var activeSessionHolder: ActiveSessionHolder @Inject lateinit var pushersManager: PushersManager @Inject lateinit var vectorMessagingHelper: VectorMessagingHelper + @Inject lateinit var unifiedPushHelper: UnifiedPushHelper override fun onNewToken(token: String) { Timber.d("New Firebase token") fcmHelper.storeFcmToken(token) - if (vectorPreferences.areNotificationEnabledForDevice() && activeSessionHolder.hasActiveSession()) { + if ( + vectorPreferences.areNotificationEnabledForDevice() && + activeSessionHolder.hasActiveSession() && + unifiedPushHelper.isEmbeddedDistributor() + ) { pushersManager.enqueueRegisterPusher(token, getString(R.string.pusher_http_url)) } } diff --git a/vector/src/main/java/im/vector/app/core/pushers/UnifiedPushHelper.kt b/vector/src/main/java/im/vector/app/core/pushers/UnifiedPushHelper.kt index 99987ddb6c..b5ec8a0d15 100644 --- a/vector/src/main/java/im/vector/app/core/pushers/UnifiedPushHelper.kt +++ b/vector/src/main/java/im/vector/app/core/pushers/UnifiedPushHelper.kt @@ -240,11 +240,17 @@ class UnifiedPushHelper @Inject constructor( } fun isEmbeddedDistributor(): Boolean { - return UnifiedPush.getDistributor(context) == context.packageName && fcmHelper.isFirebaseAvailable() + return isInternalDistributor() && fcmHelper.isFirebaseAvailable() } fun isBackgroundSync(): Boolean { - return UnifiedPush.getDistributor(context) == context.packageName && !fcmHelper.isFirebaseAvailable() + return isInternalDistributor() && !fcmHelper.isFirebaseAvailable() + } + + private fun isInternalDistributor(): Boolean { + return UnifiedPush.getDistributor(context).isEmpty() || + UnifiedPush.getDistributor(context) == context.packageName + } fun getPrivacyFriendlyUpEndpoint(): String? { From 65654e7e8a99e0e059188a48be3b66bf79e8f1bf Mon Sep 17 00:00:00 2001 From: sim Date: Thu, 8 Sep 2022 12:21:11 +0200 Subject: [PATCH 16/26] Lint --- .../main/java/im/vector/app/core/pushers/UnifiedPushHelper.kt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/vector/src/main/java/im/vector/app/core/pushers/UnifiedPushHelper.kt b/vector/src/main/java/im/vector/app/core/pushers/UnifiedPushHelper.kt index b5ec8a0d15..aab94eca93 100644 --- a/vector/src/main/java/im/vector/app/core/pushers/UnifiedPushHelper.kt +++ b/vector/src/main/java/im/vector/app/core/pushers/UnifiedPushHelper.kt @@ -250,7 +250,6 @@ class UnifiedPushHelper @Inject constructor( private fun isInternalDistributor(): Boolean { return UnifiedPush.getDistributor(context).isEmpty() || UnifiedPush.getDistributor(context) == context.packageName - } fun getPrivacyFriendlyUpEndpoint(): String? { @@ -274,7 +273,7 @@ class UnifiedPushHelper @Inject constructor( } fun getPushGateway(): String? { - return if (isEmbeddedDistributor()) context.getString(R.string.pusher_http_url) + return if (isEmbeddedDistributor()) stringProvider.getString(R.string.pusher_http_url) else unifiedPushStore.getPushGateway() } } From 2527dbbeb2a411777602b483360aac0240d5cf83 Mon Sep 17 00:00:00 2001 From: sim Date: Thu, 8 Sep 2022 15:37:18 +0200 Subject: [PATCH 17/26] Rename FirebaseReceiver to VectorFirebaseMessagingService --- vector-app/src/gplay/AndroidManifest.xml | 2 +- .../{FirebaseReceiver.kt => VectorFirebaseMessagingService.kt} | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename vector/src/gplay/java/im/vector/app/push/fcm/{FirebaseReceiver.kt => VectorFirebaseMessagingService.kt} (97%) diff --git a/vector-app/src/gplay/AndroidManifest.xml b/vector-app/src/gplay/AndroidManifest.xml index 3aa6fbcb2b..e102b3ee8c 100755 --- a/vector-app/src/gplay/AndroidManifest.xml +++ b/vector-app/src/gplay/AndroidManifest.xml @@ -8,7 +8,7 @@ android:name="firebase_analytics_collection_deactivated" android:value="true" /> - diff --git a/vector/src/gplay/java/im/vector/app/push/fcm/FirebaseReceiver.kt b/vector/src/gplay/java/im/vector/app/push/fcm/VectorFirebaseMessagingService.kt similarity index 97% rename from vector/src/gplay/java/im/vector/app/push/fcm/FirebaseReceiver.kt rename to vector/src/gplay/java/im/vector/app/push/fcm/VectorFirebaseMessagingService.kt index 0b4d1f1f43..b52cfd6b11 100644 --- a/vector/src/gplay/java/im/vector/app/push/fcm/FirebaseReceiver.kt +++ b/vector/src/gplay/java/im/vector/app/push/fcm/VectorFirebaseMessagingService.kt @@ -31,7 +31,7 @@ import timber.log.Timber import javax.inject.Inject @AndroidEntryPoint -class FirebaseReceiver : FirebaseMessagingService() { +class VectorFirebaseMessagingService : FirebaseMessagingService() { @Inject lateinit var fcmHelper: FcmHelper @Inject lateinit var vectorPreferences: VectorPreferences @Inject lateinit var activeSessionHolder: ActiveSessionHolder From dbea1726ec0683cba3ea389f5ab85b1a4477170f Mon Sep 17 00:00:00 2001 From: sim Date: Thu, 8 Sep 2022 15:38:52 +0200 Subject: [PATCH 18/26] Rename VectorMessagingHelper to VectorPushHandler --- .../vector/app/push/fcm/VectorFirebaseMessagingService.kt | 6 +++--- .../im/vector/app/core/pushers/VectorMessagingReceiver.kt | 4 ++-- .../{VectorMessagingHelper.kt => VectorPushHandler.kt} | 5 +---- 3 files changed, 6 insertions(+), 9 deletions(-) rename vector/src/main/java/im/vector/app/core/pushers/{VectorMessagingHelper.kt => VectorPushHandler.kt} (98%) diff --git a/vector/src/gplay/java/im/vector/app/push/fcm/VectorFirebaseMessagingService.kt b/vector/src/gplay/java/im/vector/app/push/fcm/VectorFirebaseMessagingService.kt index b52cfd6b11..5646df1857 100644 --- a/vector/src/gplay/java/im/vector/app/push/fcm/VectorFirebaseMessagingService.kt +++ b/vector/src/gplay/java/im/vector/app/push/fcm/VectorFirebaseMessagingService.kt @@ -24,7 +24,7 @@ import im.vector.app.core.di.ActiveSessionHolder import im.vector.app.core.pushers.FcmHelper import im.vector.app.core.pushers.PushersManager import im.vector.app.core.pushers.UnifiedPushHelper -import im.vector.app.core.pushers.VectorMessagingHelper +import im.vector.app.core.pushers.VectorPushHandler import im.vector.app.features.settings.VectorPreferences import org.json.JSONObject import timber.log.Timber @@ -36,7 +36,7 @@ class VectorFirebaseMessagingService : FirebaseMessagingService() { @Inject lateinit var vectorPreferences: VectorPreferences @Inject lateinit var activeSessionHolder: ActiveSessionHolder @Inject lateinit var pushersManager: PushersManager - @Inject lateinit var vectorMessagingHelper: VectorMessagingHelper + @Inject lateinit var vectorPushHandler: VectorPushHandler @Inject lateinit var unifiedPushHelper: UnifiedPushHelper override fun onNewToken(token: String) { @@ -53,6 +53,6 @@ class VectorFirebaseMessagingService : FirebaseMessagingService() { override fun onMessageReceived(message: RemoteMessage) { Timber.d("New Firebase message") - vectorMessagingHelper.onMessage(JSONObject(message.data as Map<*, *>).toString()) + vectorPushHandler.onMessage(JSONObject(message.data as Map<*, *>).toString()) } } diff --git a/vector/src/main/java/im/vector/app/core/pushers/VectorMessagingReceiver.kt b/vector/src/main/java/im/vector/app/core/pushers/VectorMessagingReceiver.kt index 1aa9c3e891..a2375350aa 100644 --- a/vector/src/main/java/im/vector/app/core/pushers/VectorMessagingReceiver.kt +++ b/vector/src/main/java/im/vector/app/core/pushers/VectorMessagingReceiver.kt @@ -42,7 +42,7 @@ class VectorMessagingReceiver : MessagingReceiver() { @Inject lateinit var pushersManager: PushersManager @Inject lateinit var activeSessionHolder: ActiveSessionHolder @Inject lateinit var vectorPreferences: VectorPreferences - @Inject lateinit var vectorMessagingHelper: VectorMessagingHelper + @Inject lateinit var vectorPushHandler: VectorPushHandler @Inject lateinit var guardServiceStarter: GuardServiceStarter @Inject lateinit var unifiedPushStore: UnifiedPushStore @Inject lateinit var unifiedPushHelper: UnifiedPushHelper @@ -57,7 +57,7 @@ class VectorMessagingReceiver : MessagingReceiver() { * @param instance connection, for multi-account */ override fun onMessage(context: Context, message: ByteArray, instance: String) { - vectorMessagingHelper.onMessage(String(message)) + vectorPushHandler.onMessage(String(message)) } override fun onNewEndpoint(context: Context, endpoint: String, instance: String) { diff --git a/vector/src/main/java/im/vector/app/core/pushers/VectorMessagingHelper.kt b/vector/src/main/java/im/vector/app/core/pushers/VectorPushHandler.kt similarity index 98% rename from vector/src/main/java/im/vector/app/core/pushers/VectorMessagingHelper.kt rename to vector/src/main/java/im/vector/app/core/pushers/VectorPushHandler.kt index a2fa1162f1..3c9109a24d 100644 --- a/vector/src/main/java/im/vector/app/core/pushers/VectorMessagingHelper.kt +++ b/vector/src/main/java/im/vector/app/core/pushers/VectorPushHandler.kt @@ -47,11 +47,8 @@ import javax.inject.Inject private val loggerTag = LoggerTag("Push", LoggerTag.SYNC) -/** - * Hilt injection happen at super.onReceive(). - */ -class VectorMessagingHelper @Inject constructor( +class VectorPushHandler @Inject constructor( private val notificationDrawerManager: NotificationDrawerManager, private val notifiableEventResolver: NotifiableEventResolver, private val activeSessionHolder: ActiveSessionHolder, From bc5309b5d73ef28af7b8958eceb921264f6d39e1 Mon Sep 17 00:00:00 2001 From: sim Date: Thu, 8 Sep 2022 15:40:06 +0200 Subject: [PATCH 19/26] Rename VectorMessagingReceiver to VectorUnifiedPushMessagingReceiver --- vector/src/main/AndroidManifest.xml | 2 +- ...ssagingReceiver.kt => VectorUnifiedPushMessagingReceiver.kt} | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename vector/src/main/java/im/vector/app/core/pushers/{VectorMessagingReceiver.kt => VectorUnifiedPushMessagingReceiver.kt} (98%) diff --git a/vector/src/main/AndroidManifest.xml b/vector/src/main/AndroidManifest.xml index 29eef172ae..7b98a1982d 100644 --- a/vector/src/main/AndroidManifest.xml +++ b/vector/src/main/AndroidManifest.xml @@ -412,7 +412,7 @@ diff --git a/vector/src/main/java/im/vector/app/core/pushers/VectorMessagingReceiver.kt b/vector/src/main/java/im/vector/app/core/pushers/VectorUnifiedPushMessagingReceiver.kt similarity index 98% rename from vector/src/main/java/im/vector/app/core/pushers/VectorMessagingReceiver.kt rename to vector/src/main/java/im/vector/app/core/pushers/VectorUnifiedPushMessagingReceiver.kt index a2375350aa..4e68e39b37 100644 --- a/vector/src/main/java/im/vector/app/core/pushers/VectorMessagingReceiver.kt +++ b/vector/src/main/java/im/vector/app/core/pushers/VectorUnifiedPushMessagingReceiver.kt @@ -38,7 +38,7 @@ private val loggerTag = LoggerTag("Push", LoggerTag.SYNC) * Hilt injection happen at super.onReceive(). */ @AndroidEntryPoint -class VectorMessagingReceiver : MessagingReceiver() { +class VectorUnifiedPushMessagingReceiver : MessagingReceiver() { @Inject lateinit var pushersManager: PushersManager @Inject lateinit var activeSessionHolder: ActiveSessionHolder @Inject lateinit var vectorPreferences: VectorPreferences From 3e12907b26113bf8fc86a9a226fb6df4758d82dd Mon Sep 17 00:00:00 2001 From: sim Date: Thu, 8 Sep 2022 16:25:48 +0200 Subject: [PATCH 20/26] Parse pushData in the push receiver --- .../fcm/VectorFirebaseMessagingService.kt | 7 +++++-- .../im/vector/app/core/pushers/PushParser.kt | 16 ++++++++------ .../app/core/pushers/VectorPushHandler.kt | 21 +++++++------------ .../VectorUnifiedPushMessagingReceiver.kt | 6 +++++- 4 files changed, 28 insertions(+), 22 deletions(-) diff --git a/vector/src/gplay/java/im/vector/app/push/fcm/VectorFirebaseMessagingService.kt b/vector/src/gplay/java/im/vector/app/push/fcm/VectorFirebaseMessagingService.kt index 5646df1857..9182b855f3 100644 --- a/vector/src/gplay/java/im/vector/app/push/fcm/VectorFirebaseMessagingService.kt +++ b/vector/src/gplay/java/im/vector/app/push/fcm/VectorFirebaseMessagingService.kt @@ -22,11 +22,11 @@ import dagger.hilt.android.AndroidEntryPoint import im.vector.app.R import im.vector.app.core.di.ActiveSessionHolder import im.vector.app.core.pushers.FcmHelper +import im.vector.app.core.pushers.PushParser import im.vector.app.core.pushers.PushersManager import im.vector.app.core.pushers.UnifiedPushHelper import im.vector.app.core.pushers.VectorPushHandler import im.vector.app.features.settings.VectorPreferences -import org.json.JSONObject import timber.log.Timber import javax.inject.Inject @@ -36,6 +36,7 @@ class VectorFirebaseMessagingService : FirebaseMessagingService() { @Inject lateinit var vectorPreferences: VectorPreferences @Inject lateinit var activeSessionHolder: ActiveSessionHolder @Inject lateinit var pushersManager: PushersManager + @Inject lateinit var pushParser: PushParser @Inject lateinit var vectorPushHandler: VectorPushHandler @Inject lateinit var unifiedPushHelper: UnifiedPushHelper @@ -53,6 +54,8 @@ class VectorFirebaseMessagingService : FirebaseMessagingService() { override fun onMessageReceived(message: RemoteMessage) { Timber.d("New Firebase message") - vectorPushHandler.onMessage(JSONObject(message.data as Map<*, *>).toString()) + pushParser.parsePushDataFcm(message.data)?.let { + vectorPushHandler.handle(it) + } } } diff --git a/vector/src/main/java/im/vector/app/core/pushers/PushParser.kt b/vector/src/main/java/im/vector/app/core/pushers/PushParser.kt index 6f141e3736..b25b97be95 100644 --- a/vector/src/main/java/im/vector/app/core/pushers/PushParser.kt +++ b/vector/src/main/java/im/vector/app/core/pushers/PushParser.kt @@ -20,6 +20,7 @@ import im.vector.app.core.pushers.model.PushData import im.vector.app.core.pushers.model.PushDataFcm import im.vector.app.core.pushers.model.PushDataUnifiedPush import im.vector.app.core.pushers.model.toPushData +import org.json.JSONObject import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.api.util.MatrixJsonParser import javax.inject.Inject @@ -40,12 +41,15 @@ class PushParser @Inject constructor() { * [3] https://spec.matrix.org/latest/push-gateway-api/ * [4] https://github.com/p1gp1g/sygnal/blob/unifiedpush/sygnal/upfcmpushkin.py (Not tested for a while) */ - fun parseData(message: String, firebaseFormat: Boolean): PushData? { - val moshi = MatrixJsonParser.getMoshi() - return if (firebaseFormat) { - tryOrNull { moshi.adapter(PushDataFcm::class.java).fromJson(message) }?.toPushData() - } else { - tryOrNull { moshi.adapter(PushDataUnifiedPush::class.java).fromJson(message) }?.toPushData() + fun parsePushDataUnifiedPush(message: ByteArray): PushData? { + return MatrixJsonParser.getMoshi().let { + tryOrNull { it.adapter(PushDataUnifiedPush::class.java).fromJson(String(message)) }?.toPushData() + } + } + + fun parsePushDataFcm(message: Map<*, *>): PushData? { + return MatrixJsonParser.getMoshi().let { + tryOrNull { it.adapter(PushDataFcm::class.java).fromJson(JSONObject(message).toString()) }?.toPushData() } } } diff --git a/vector/src/main/java/im/vector/app/core/pushers/VectorPushHandler.kt b/vector/src/main/java/im/vector/app/core/pushers/VectorPushHandler.kt index 3c9109a24d..aec1d38c95 100644 --- a/vector/src/main/java/im/vector/app/core/pushers/VectorPushHandler.kt +++ b/vector/src/main/java/im/vector/app/core/pushers/VectorPushHandler.kt @@ -55,8 +55,6 @@ class VectorPushHandler @Inject constructor( private val vectorPreferences: VectorPreferences, private val vectorDataStore: VectorDataStore, private val wifiDetector: WifiDetector, - private val unifiedPushHelper: UnifiedPushHelper, - private val pushParser: PushParser, private val actionIds: NotificationActionIds, private val context: Context, private val buildMeta: BuildMeta @@ -74,20 +72,17 @@ class VectorPushHandler @Inject constructor( * * @param message the message */ - fun onMessage(message: String) { - Timber.tag(loggerTag.value).d("## onMessage() received") + fun handle(pushData: PushData) { + Timber.tag(loggerTag.value).d("## handling pushData") if (buildMeta.lowPrivacyLoggingEnabled) { - Timber.tag(loggerTag.value).d("## onMessage() $message") + Timber.tag(loggerTag.value).d("## pushData: $pushData") } runBlocking { vectorDataStore.incrementPushCounter() } - val pushData = pushParser.parseData(message, unifiedPushHelper.isEmbeddedDistributor()) - ?: return Unit.also { Timber.tag(loggerTag.value).w("Invalid received data Json format") } - // Diagnostic Push if (pushData.eventId == PushersManager.TEST_EVENT_ID) { val intent = Intent(actionIds.push) @@ -105,7 +100,7 @@ class VectorPushHandler @Inject constructor( // we are in foreground, let the sync do the things? Timber.tag(loggerTag.value).d("PUSH received in a foreground state, ignore") } else { - coroutineScope.launch(Dispatchers.IO) { onMessageReceivedInternal(pushData) } + coroutineScope.launch(Dispatchers.IO) { handleInternal(pushData) } } } } @@ -115,12 +110,12 @@ class VectorPushHandler @Inject constructor( * * @param pushData Object containing message data. */ - private suspend fun onMessageReceivedInternal(pushData: PushData) { + private suspend fun handleInternal(pushData: PushData) { try { if (buildMeta.lowPrivacyLoggingEnabled) { - Timber.tag(loggerTag.value).d("## onMessageReceivedInternal() : $pushData") + Timber.tag(loggerTag.value).d("## handleInternal() : $pushData") } else { - Timber.tag(loggerTag.value).d("## onMessageReceivedInternal()") + Timber.tag(loggerTag.value).d("## handleInternal()") } val session = activeSessionHolder.getOrInitializeSession(startSync = false) @@ -140,7 +135,7 @@ class VectorPushHandler @Inject constructor( } } } catch (e: Exception) { - Timber.tag(loggerTag.value).e(e, "## onMessageReceivedInternal() failed") + Timber.tag(loggerTag.value).e(e, "## handleInternal() failed") } } diff --git a/vector/src/main/java/im/vector/app/core/pushers/VectorUnifiedPushMessagingReceiver.kt b/vector/src/main/java/im/vector/app/core/pushers/VectorUnifiedPushMessagingReceiver.kt index 4e68e39b37..01d85caa83 100644 --- a/vector/src/main/java/im/vector/app/core/pushers/VectorUnifiedPushMessagingReceiver.kt +++ b/vector/src/main/java/im/vector/app/core/pushers/VectorUnifiedPushMessagingReceiver.kt @@ -40,6 +40,7 @@ private val loggerTag = LoggerTag("Push", LoggerTag.SYNC) @AndroidEntryPoint class VectorUnifiedPushMessagingReceiver : MessagingReceiver() { @Inject lateinit var pushersManager: PushersManager + @Inject lateinit var pushParser: PushParser @Inject lateinit var activeSessionHolder: ActiveSessionHolder @Inject lateinit var vectorPreferences: VectorPreferences @Inject lateinit var vectorPushHandler: VectorPushHandler @@ -57,7 +58,10 @@ class VectorUnifiedPushMessagingReceiver : MessagingReceiver() { * @param instance connection, for multi-account */ override fun onMessage(context: Context, message: ByteArray, instance: String) { - vectorPushHandler.onMessage(String(message)) + Timber.tag(loggerTag.value).d("New message") + pushParser.parsePushDataUnifiedPush(message)?.let { + vectorPushHandler.handle(it) + } } override fun onNewEndpoint(context: Context, endpoint: String, instance: String) { From a17a4fe4b1f43e86d234190185ea458f00e08770 Mon Sep 17 00:00:00 2001 From: sim Date: Thu, 8 Sep 2022 17:16:55 +0200 Subject: [PATCH 21/26] Add logs for invalid push data --- .../app/push/fcm/VectorFirebaseMessagingService.kt | 9 +++++++-- .../core/pushers/VectorUnifiedPushMessagingReceiver.kt | 2 ++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/vector/src/gplay/java/im/vector/app/push/fcm/VectorFirebaseMessagingService.kt b/vector/src/gplay/java/im/vector/app/push/fcm/VectorFirebaseMessagingService.kt index 9182b855f3..ddbe8b1292 100644 --- a/vector/src/gplay/java/im/vector/app/push/fcm/VectorFirebaseMessagingService.kt +++ b/vector/src/gplay/java/im/vector/app/push/fcm/VectorFirebaseMessagingService.kt @@ -27,9 +27,12 @@ import im.vector.app.core.pushers.PushersManager import im.vector.app.core.pushers.UnifiedPushHelper import im.vector.app.core.pushers.VectorPushHandler import im.vector.app.features.settings.VectorPreferences +import org.matrix.android.sdk.api.logger.LoggerTag import timber.log.Timber import javax.inject.Inject +private val loggerTag = LoggerTag("Push", LoggerTag.SYNC) + @AndroidEntryPoint class VectorFirebaseMessagingService : FirebaseMessagingService() { @Inject lateinit var fcmHelper: FcmHelper @@ -41,7 +44,7 @@ class VectorFirebaseMessagingService : FirebaseMessagingService() { @Inject lateinit var unifiedPushHelper: UnifiedPushHelper override fun onNewToken(token: String) { - Timber.d("New Firebase token") + Timber.tag(loggerTag.value).d("New Firebase token") fcmHelper.storeFcmToken(token) if ( vectorPreferences.areNotificationEnabledForDevice() && @@ -53,9 +56,11 @@ class VectorFirebaseMessagingService : FirebaseMessagingService() { } override fun onMessageReceived(message: RemoteMessage) { - Timber.d("New Firebase message") + Timber.tag(loggerTag.value).d("New Firebase message") pushParser.parsePushDataFcm(message.data)?.let { vectorPushHandler.handle(it) + } ?: run { + Timber.tag(loggerTag.value).w("Invalid received data Json format") } } } diff --git a/vector/src/main/java/im/vector/app/core/pushers/VectorUnifiedPushMessagingReceiver.kt b/vector/src/main/java/im/vector/app/core/pushers/VectorUnifiedPushMessagingReceiver.kt index 01d85caa83..838cbd5935 100644 --- a/vector/src/main/java/im/vector/app/core/pushers/VectorUnifiedPushMessagingReceiver.kt +++ b/vector/src/main/java/im/vector/app/core/pushers/VectorUnifiedPushMessagingReceiver.kt @@ -61,6 +61,8 @@ class VectorUnifiedPushMessagingReceiver : MessagingReceiver() { Timber.tag(loggerTag.value).d("New message") pushParser.parsePushDataUnifiedPush(message)?.let { vectorPushHandler.handle(it) + } ?: run { + Timber.tag(loggerTag.value).w("Invalid received data Json format") } } From 7c4527fba645cc8b0ccc93ea962655da148ca6f9 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 9 Sep 2022 15:58:16 +0200 Subject: [PATCH 22/26] Fix test - no need to use Moshi to parse FCM Push data. --- .../im/vector/app/core/pushers/PushParser.kt | 43 ++++++----- .../app/core/pushers/model/PushDataFcm.kt | 9 +-- .../vector/app/core/pushers/PushParserTest.kt | 74 +++++++++++-------- 3 files changed, 73 insertions(+), 53 deletions(-) diff --git a/vector/src/main/java/im/vector/app/core/pushers/PushParser.kt b/vector/src/main/java/im/vector/app/core/pushers/PushParser.kt index b25b97be95..6de8935315 100644 --- a/vector/src/main/java/im/vector/app/core/pushers/PushParser.kt +++ b/vector/src/main/java/im/vector/app/core/pushers/PushParser.kt @@ -20,27 +20,26 @@ import im.vector.app.core.pushers.model.PushData import im.vector.app.core.pushers.model.PushDataFcm import im.vector.app.core.pushers.model.PushDataUnifiedPush import im.vector.app.core.pushers.model.toPushData -import org.json.JSONObject import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.api.util.MatrixJsonParser import javax.inject.Inject +/** + * Parse the received data from Push. Json format are different depending on the source. + * + * Notifications received by FCM are formatted by the matrix gateway [1]. The data send to FCM is the content + * of the "notification" attribute of the json sent to the gateway [2][3]. + * On the other side, with UnifiedPush, the content of the message received is the content posted to the push + * gateway endpoint [3]. + * + * *Note*: If we want to get the same content with FCM and unifiedpush, we can do a new sygnal pusher [4]. + * + * [1] https://github.com/matrix-org/sygnal/blob/main/sygnal/gcmpushkin.py + * [2] https://github.com/matrix-org/sygnal/blob/main/sygnal/gcmpushkin.py#L366 + * [3] https://spec.matrix.org/latest/push-gateway-api/ + * [4] https://github.com/p1gp1g/sygnal/blob/unifiedpush/sygnal/upfcmpushkin.py (Not tested for a while) + */ class PushParser @Inject constructor() { - /** - * Parse the received data from Push. Json format are different depending on the source. - * - * Notifications received by FCM are formatted by the matrix gateway [1]. The data send to FCM is the content - * of the "notification" attribute of the json sent to the gateway [2][3]. - * On the other side, with UnifiedPush, the content of the message received is the content posted to the push - * gateway endpoint [3]. - * - * *Note*: If we want to get the same content with FCM and unifiedpush, we can do a new sygnal pusher [4]. - * - * [1] https://github.com/matrix-org/sygnal/blob/main/sygnal/gcmpushkin.py - * [2] https://github.com/matrix-org/sygnal/blob/main/sygnal/gcmpushkin.py#L366 - * [3] https://spec.matrix.org/latest/push-gateway-api/ - * [4] https://github.com/p1gp1g/sygnal/blob/unifiedpush/sygnal/upfcmpushkin.py (Not tested for a while) - */ fun parsePushDataUnifiedPush(message: ByteArray): PushData? { return MatrixJsonParser.getMoshi().let { tryOrNull { it.adapter(PushDataUnifiedPush::class.java).fromJson(String(message)) }?.toPushData() @@ -48,8 +47,16 @@ class PushParser @Inject constructor() { } fun parsePushDataFcm(message: Map<*, *>): PushData? { - return MatrixJsonParser.getMoshi().let { - tryOrNull { it.adapter(PushDataFcm::class.java).fromJson(JSONObject(message).toString()) }?.toPushData() + if ((message.containsKey("event_id") && message["event_id"] !is String) || + message.containsKey("room_id") && message["room_id"] !is String || + message.containsKey("unread") && message["unread"] !is Int) { + return null } + val pushDataFcm = PushDataFcm( + eventId = message["event_id"] as String?, + roomId = message["room_id"] as String?, + unread = message["unread"] as Int?, + ) + return pushDataFcm.toPushData() } } diff --git a/vector/src/main/java/im/vector/app/core/pushers/model/PushDataFcm.kt b/vector/src/main/java/im/vector/app/core/pushers/model/PushDataFcm.kt index 1b9c37ae0a..e78cdf5ff8 100644 --- a/vector/src/main/java/im/vector/app/core/pushers/model/PushDataFcm.kt +++ b/vector/src/main/java/im/vector/app/core/pushers/model/PushDataFcm.kt @@ -16,8 +16,6 @@ package im.vector.app.core.pushers.model -import com.squareup.moshi.Json -import com.squareup.moshi.JsonClass import org.matrix.android.sdk.api.MatrixPatterns /** @@ -32,11 +30,10 @@ import org.matrix.android.sdk.api.MatrixPatterns * * . */ -@JsonClass(generateAdapter = true) data class PushDataFcm( - @Json(name = "event_id") val eventId: String?, - @Json(name = "room_id") val roomId: String?, - @Json(name = "unread") var unread: Int?, + val eventId: String?, + val roomId: String?, + var unread: Int?, ) fun PushDataFcm.toPushData() = PushData( diff --git a/vector/src/test/java/im/vector/app/core/pushers/PushParserTest.kt b/vector/src/test/java/im/vector/app/core/pushers/PushParserTest.kt index 03577a4400..9dcaa992f8 100644 --- a/vector/src/test/java/im/vector/app/core/pushers/PushParserTest.kt +++ b/vector/src/test/java/im/vector/app/core/pushers/PushParserTest.kt @@ -35,73 +35,89 @@ class PushParserTest { ) @Test - fun `test edge cases`() { - doAllEdgeTests(true) - doAllEdgeTests(false) + fun `test edge cases Firebase`() { + val pushParser = PushParser() + // Empty Json + pushParser.parsePushDataFcm(emptyMap()) shouldBeEqualTo emptyData + // Bad Json + pushParser.parsePushDataFcm(FIREBASE_PUSH_DATA.mutate("room_id", 5)) shouldBe null + pushParser.parsePushDataFcm(FIREBASE_PUSH_DATA.mutate("event_id", 5)) shouldBe null + pushParser.parsePushDataFcm(FIREBASE_PUSH_DATA.mutate("unread", "str")) shouldBe null + // Extra data + pushParser.parsePushDataFcm(FIREBASE_PUSH_DATA.mutate("extra", 5)) shouldBeEqualTo validData } - private fun doAllEdgeTests(firebaseFormat: Boolean) { + @Test + fun `test edge cases UnifiedPush`() { val pushParser = PushParser() // Empty string - pushParser.parseData("", firebaseFormat) shouldBe null + pushParser.parsePushDataUnifiedPush("".toByteArray()) shouldBe null // Empty Json - pushParser.parseData("{}", firebaseFormat) shouldBeEqualTo emptyData + pushParser.parsePushDataUnifiedPush("{}".toByteArray()) shouldBeEqualTo emptyData // Bad Json - pushParser.parseData("ABC", firebaseFormat) shouldBe null + pushParser.parsePushDataUnifiedPush("ABC".toByteArray()) shouldBe null } @Test - fun `test unified push format`() { + fun `test UnifiedPush format`() { val pushParser = PushParser() - - pushParser.parseData(UNIFIED_PUSH_DATA, false) shouldBeEqualTo validData - pushParser.parseData(UNIFIED_PUSH_DATA, true) shouldBeEqualTo emptyData + pushParser.parsePushDataUnifiedPush(UNIFIED_PUSH_DATA.toByteArray()) shouldBeEqualTo validData } @Test - fun `test firebase push format`() { + fun `test Firebase format`() { val pushParser = PushParser() - - pushParser.parseData(FIREBASE_PUSH_DATA, true) shouldBeEqualTo validData - pushParser.parseData(FIREBASE_PUSH_DATA, false) shouldBeEqualTo emptyData + pushParser.parsePushDataFcm(FIREBASE_PUSH_DATA) shouldBeEqualTo validData } @Test fun `test empty roomId`() { val pushParser = PushParser() - - pushParser.parseData(FIREBASE_PUSH_DATA.replace("!aRoomId:domain", ""), true) shouldBeEqualTo validData.copy(roomId = null) - pushParser.parseData(UNIFIED_PUSH_DATA.replace("!aRoomId:domain", ""), false) shouldBeEqualTo validData.copy(roomId = null) + val expected = validData.copy(roomId = null) + pushParser.parsePushDataFcm(FIREBASE_PUSH_DATA.mutate("room_id", "")) shouldBeEqualTo expected + pushParser.parsePushDataUnifiedPush(UNIFIED_PUSH_DATA.replace("!aRoomId:domain", "").toByteArray()) shouldBeEqualTo expected } @Test fun `test invalid roomId`() { val pushParser = PushParser() - - pushParser.parseData(FIREBASE_PUSH_DATA.replace("!aRoomId:domain", "aRoomId:domain"), true) shouldBeEqualTo validData.copy(roomId = null) - pushParser.parseData(UNIFIED_PUSH_DATA.replace("!aRoomId:domain", "aRoomId:domain"), false) shouldBeEqualTo validData.copy(roomId = null) + val expected = validData.copy(roomId = null) + pushParser.parsePushDataFcm(FIREBASE_PUSH_DATA.mutate("room_id", "aRoomId:domain")) shouldBeEqualTo expected + pushParser.parsePushDataUnifiedPush(UNIFIED_PUSH_DATA.mutate("!aRoomId:domain", "aRoomId:domain")) shouldBeEqualTo expected } @Test fun `test empty eventId`() { val pushParser = PushParser() - - pushParser.parseData(FIREBASE_PUSH_DATA.replace("\$anEventId", ""), true) shouldBeEqualTo validData.copy(eventId = null) - pushParser.parseData(UNIFIED_PUSH_DATA.replace("\$anEventId", ""), false) shouldBeEqualTo validData.copy(eventId = null) + val expected = validData.copy(eventId = null) + pushParser.parsePushDataFcm(FIREBASE_PUSH_DATA.mutate("event_id", "")) shouldBeEqualTo expected + pushParser.parsePushDataUnifiedPush(UNIFIED_PUSH_DATA.mutate("\$anEventId", "")) shouldBeEqualTo expected } @Test fun `test invalid eventId`() { val pushParser = PushParser() - - pushParser.parseData(FIREBASE_PUSH_DATA.replace("\$anEventId", "anEventId"), true) shouldBeEqualTo validData.copy(eventId = null) - pushParser.parseData(UNIFIED_PUSH_DATA.replace("\$anEventId", "anEventId"), false) shouldBeEqualTo validData.copy(eventId = null) + val expected = validData.copy(eventId = null) + pushParser.parsePushDataFcm(FIREBASE_PUSH_DATA.mutate("event_id", "anEventId")) shouldBeEqualTo expected + pushParser.parsePushDataUnifiedPush(UNIFIED_PUSH_DATA.mutate("\$anEventId", "anEventId")) shouldBeEqualTo expected } companion object { private const val UNIFIED_PUSH_DATA = "{\"notification\":{\"event_id\":\"\$anEventId\",\"room_id\":\"!aRoomId:domain\",\"counts\":{\"unread\":1},\"prio\":\"high\"}}" - private const val FIREBASE_PUSH_DATA = - "{\"event_id\":\"\$anEventId\",\"room_id\":\"!aRoomId:domain\",\"unread\":\"1\",\"prio\":\"high\"}" + private val FIREBASE_PUSH_DATA = mapOf( + "event_id" to "\$anEventId", + "room_id" to "!aRoomId:domain", + "unread" to 1, + "prio" to "high", + ) } } + +private fun Map.mutate(key: K, value: V?): Map { + return toMutableMap().apply { put(key, value) } +} + +private fun String.mutate(oldValue: String, newValue: String): ByteArray { + return replace(oldValue, newValue).toByteArray() +} From d9ad9859ec0903c14d260cd6329ffa65557feb76 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 9 Sep 2022 14:22:51 +0200 Subject: [PATCH 23/26] Format --- .../main/java/im/vector/app/core/pushers/VectorPushHandler.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/vector/src/main/java/im/vector/app/core/pushers/VectorPushHandler.kt b/vector/src/main/java/im/vector/app/core/pushers/VectorPushHandler.kt index aec1d38c95..2919539f78 100644 --- a/vector/src/main/java/im/vector/app/core/pushers/VectorPushHandler.kt +++ b/vector/src/main/java/im/vector/app/core/pushers/VectorPushHandler.kt @@ -47,7 +47,6 @@ import javax.inject.Inject private val loggerTag = LoggerTag("Push", LoggerTag.SYNC) - class VectorPushHandler @Inject constructor( private val notificationDrawerManager: NotificationDrawerManager, private val notifiableEventResolver: NotifiableEventResolver, From bdff23a74db1273dba9edf04423e307ac74489f0 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 9 Sep 2022 14:24:07 +0200 Subject: [PATCH 24/26] update doc --- .../main/java/im/vector/app/core/pushers/VectorPushHandler.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/src/main/java/im/vector/app/core/pushers/VectorPushHandler.kt b/vector/src/main/java/im/vector/app/core/pushers/VectorPushHandler.kt index 2919539f78..b74028d579 100644 --- a/vector/src/main/java/im/vector/app/core/pushers/VectorPushHandler.kt +++ b/vector/src/main/java/im/vector/app/core/pushers/VectorPushHandler.kt @@ -69,7 +69,7 @@ class VectorPushHandler @Inject constructor( /** * Called when message is received. * - * @param message the message + * @param pushData the data received in the push. */ fun handle(pushData: PushData) { Timber.tag(loggerTag.value).d("## handling pushData") From e19647f6cabdb45daa6ea7ffee294cba52e2f15e Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 9 Sep 2022 16:26:52 +0200 Subject: [PATCH 25/26] Firebase provides Map --- .../app/push/fcm/VectorFirebaseMessagingService.kt | 4 +--- .../java/im/vector/app/core/pushers/PushParser.kt | 13 ++++--------- .../im/vector/app/core/pushers/PushParserTest.kt | 14 +++++++------- 3 files changed, 12 insertions(+), 19 deletions(-) diff --git a/vector/src/gplay/java/im/vector/app/push/fcm/VectorFirebaseMessagingService.kt b/vector/src/gplay/java/im/vector/app/push/fcm/VectorFirebaseMessagingService.kt index ddbe8b1292..7fd55bd165 100644 --- a/vector/src/gplay/java/im/vector/app/push/fcm/VectorFirebaseMessagingService.kt +++ b/vector/src/gplay/java/im/vector/app/push/fcm/VectorFirebaseMessagingService.kt @@ -57,10 +57,8 @@ class VectorFirebaseMessagingService : FirebaseMessagingService() { override fun onMessageReceived(message: RemoteMessage) { Timber.tag(loggerTag.value).d("New Firebase message") - pushParser.parsePushDataFcm(message.data)?.let { + pushParser.parsePushDataFcm(message.data).let { vectorPushHandler.handle(it) - } ?: run { - Timber.tag(loggerTag.value).w("Invalid received data Json format") } } } diff --git a/vector/src/main/java/im/vector/app/core/pushers/PushParser.kt b/vector/src/main/java/im/vector/app/core/pushers/PushParser.kt index 6de8935315..8c18295c45 100644 --- a/vector/src/main/java/im/vector/app/core/pushers/PushParser.kt +++ b/vector/src/main/java/im/vector/app/core/pushers/PushParser.kt @@ -46,16 +46,11 @@ class PushParser @Inject constructor() { } } - fun parsePushDataFcm(message: Map<*, *>): PushData? { - if ((message.containsKey("event_id") && message["event_id"] !is String) || - message.containsKey("room_id") && message["room_id"] !is String || - message.containsKey("unread") && message["unread"] !is Int) { - return null - } + fun parsePushDataFcm(message: Map): PushData { val pushDataFcm = PushDataFcm( - eventId = message["event_id"] as String?, - roomId = message["room_id"] as String?, - unread = message["unread"] as Int?, + eventId = message["event_id"], + roomId = message["room_id"], + unread = message["unread"]?.let { tryOrNull { Integer.parseInt(it) } }, ) return pushDataFcm.toPushData() } diff --git a/vector/src/test/java/im/vector/app/core/pushers/PushParserTest.kt b/vector/src/test/java/im/vector/app/core/pushers/PushParserTest.kt index 9dcaa992f8..c0f6c33da8 100644 --- a/vector/src/test/java/im/vector/app/core/pushers/PushParserTest.kt +++ b/vector/src/test/java/im/vector/app/core/pushers/PushParserTest.kt @@ -38,13 +38,11 @@ class PushParserTest { fun `test edge cases Firebase`() { val pushParser = PushParser() // Empty Json - pushParser.parsePushDataFcm(emptyMap()) shouldBeEqualTo emptyData + pushParser.parsePushDataFcm(emptyMap()) shouldBeEqualTo emptyData // Bad Json - pushParser.parsePushDataFcm(FIREBASE_PUSH_DATA.mutate("room_id", 5)) shouldBe null - pushParser.parsePushDataFcm(FIREBASE_PUSH_DATA.mutate("event_id", 5)) shouldBe null - pushParser.parsePushDataFcm(FIREBASE_PUSH_DATA.mutate("unread", "str")) shouldBe null + pushParser.parsePushDataFcm(FIREBASE_PUSH_DATA.mutate("unread", "str")) shouldBeEqualTo validData.copy(unread = null) // Extra data - pushParser.parsePushDataFcm(FIREBASE_PUSH_DATA.mutate("extra", 5)) shouldBeEqualTo validData + pushParser.parsePushDataFcm(FIREBASE_PUSH_DATA.mutate("extra", "5")) shouldBeEqualTo validData } @Test @@ -74,6 +72,7 @@ class PushParserTest { fun `test empty roomId`() { val pushParser = PushParser() val expected = validData.copy(roomId = null) + pushParser.parsePushDataFcm(FIREBASE_PUSH_DATA.mutate("room_id", null)) shouldBeEqualTo expected pushParser.parsePushDataFcm(FIREBASE_PUSH_DATA.mutate("room_id", "")) shouldBeEqualTo expected pushParser.parsePushDataUnifiedPush(UNIFIED_PUSH_DATA.replace("!aRoomId:domain", "").toByteArray()) shouldBeEqualTo expected } @@ -90,6 +89,7 @@ class PushParserTest { fun `test empty eventId`() { val pushParser = PushParser() val expected = validData.copy(eventId = null) + pushParser.parsePushDataFcm(FIREBASE_PUSH_DATA.mutate("event_id", null)) shouldBeEqualTo expected pushParser.parsePushDataFcm(FIREBASE_PUSH_DATA.mutate("event_id", "")) shouldBeEqualTo expected pushParser.parsePushDataUnifiedPush(UNIFIED_PUSH_DATA.mutate("\$anEventId", "")) shouldBeEqualTo expected } @@ -108,13 +108,13 @@ class PushParserTest { private val FIREBASE_PUSH_DATA = mapOf( "event_id" to "\$anEventId", "room_id" to "!aRoomId:domain", - "unread" to 1, + "unread" to "1", "prio" to "high", ) } } -private fun Map.mutate(key: K, value: V?): Map { +private fun Map.mutate(key: String, value: String?): Map { return toMutableMap().apply { put(key, value) } } From 8c884f45fb8b7e474ee17851e5ff6c1d0fdc4458 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 9 Sep 2022 16:50:55 +0200 Subject: [PATCH 26/26] Ignore `Instantiatable` class warning --- vector-app/src/gplay/AndroidManifest.xml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/vector-app/src/gplay/AndroidManifest.xml b/vector-app/src/gplay/AndroidManifest.xml index e102b3ee8c..0ac14f9cd3 100755 --- a/vector-app/src/gplay/AndroidManifest.xml +++ b/vector-app/src/gplay/AndroidManifest.xml @@ -1,5 +1,6 @@ - + @@ -8,8 +9,10 @@ android:name="firebase_analytics_collection_deactivated" android:value="true" /> + + android:exported="false" + tools:ignore="Instantiatable">