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 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 diff --git a/vector-app/src/gplay/AndroidManifest.xml b/vector-app/src/gplay/AndroidManifest.xml index a5f0eae6be..e102b3ee8c 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" /> - - - - - - - @@ -424,6 +424,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/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/PushersManager.kt b/vector/src/main/java/im/vector/app/core/pushers/PushersManager.kt index 91ab58207d..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,7 @@ 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, private val stringProvider: StringProvider, @@ -39,9 +39,9 @@ class PushersManager @Inject constructor( val currentSession = activeSessionHolder.getActiveSession() currentSession.pushersService().testPush( - unifiedPushStore.getPushGateway()!!, + unifiedPushHelper.getPushGateway() ?: return, 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..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 @@ -46,6 +46,9 @@ class UnifiedPushHelper @Inject constructor( private val vectorFeatures: VectorFeatures, private val fcmHelper: FcmHelper, ) { + + // Called when the home activity starts + // or when notifications are enabled fun register( activity: FragmentActivity, onDoneRunnable: Runnable? = null, @@ -56,7 +59,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 +96,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,45 +105,26 @@ 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, - cancellable = !force + distributors = distributors ) } } } - fun openDistributorDialog( - activity: FragmentActivity, - pushersManager: PushersManager, - onDoneRunnable: Runnable, - ) { - val distributors = UnifiedPush.getDistributors(activity) - openDistributorDialogInternal( - activity, - pushersManager, - onDoneRunnable, distributors, - unregisterFirst = true, - cancellable = true, - ) - } - + // There is no case where this function is called + // with a saved distributor and/or a pusher private fun openDistributorDialogInternal( activity: FragmentActivity, - pushersManager: PushersManager?, onDoneRunnable: Runnable?, - distributors: List, - unregisterFirst: Boolean, - cancellable: Boolean, + distributors: List ) { val internalDistributorName = stringProvider.getString( if (fcmHelper.isFirebaseAvailable()) { @@ -154,16 +146,8 @@ 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 { - if (unregisterFirst) { - // Un-register first - unregister(pushersManager) - } UnifiedPush.saveDistributor(context, distributor) Timber.i("Saving distributor: $distributor") UnifiedPush.registerApp(context) @@ -176,7 +160,7 @@ class UnifiedPushHelper @Inject constructor( UnifiedPush.registerApp(context) onDoneRunnable?.run() } - .setCancelable(cancellable) + .setCancelable(true) .show() } @@ -184,7 +168,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") } @@ -253,15 +240,20 @@ 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? { - val endpoint = unifiedPushStore.getEndpointOrToken() + val endpoint = getEndpointOrToken() if (endpoint.isNullOrEmpty()) return null if (isEmbeddedDistributor()) { return endpoint @@ -274,4 +266,14 @@ class UnifiedPushHelper @Inject constructor( null } } + + fun getEndpointOrToken(): String? { + return if (isEmbeddedDistributor()) fcmHelper.getFcmToken() + else unifiedPushStore.getEndpoint() + } + + fun getPushGateway(): String? { + return if (isEmbeddedDistributor()) stringProvider.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 07d291a723..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 @@ -22,7 +22,8 @@ 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 +32,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) } diff --git a/vector/src/main/java/im/vector/app/core/pushers/VectorMessagingReceiver.kt b/vector/src/main/java/im/vector/app/core/pushers/VectorPushHandler.kt similarity index 58% rename from vector/src/main/java/im/vector/app/core/pushers/VectorMessagingReceiver.kt rename to vector/src/main/java/im/vector/app/core/pushers/VectorPushHandler.kt index 8e88e44627..aec1d38c95 100644 --- a/vector/src/main/java/im/vector/app/core/pushers/VectorMessagingReceiver.kt +++ b/vector/src/main/java/im/vector/app/core/pushers/VectorPushHandler.kt @@ -20,20 +20,16 @@ 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 @@ -46,30 +42,23 @@ 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.MessagingReceiver import timber.log.Timber import javax.inject.Inject private val loggerTag = LoggerTag("Push", LoggerTag.SYNC) -/** - * Hilt injection happen at super.onReceive(). - */ -@AndroidEntryPoint -class VectorMessagingReceiver : MessagingReceiver() { - @Inject lateinit var notificationDrawerManager: NotificationDrawerManager - @Inject lateinit var notifiableEventResolver: NotifiableEventResolver - @Inject lateinit var pushersManager: PushersManager - @Inject lateinit var activeSessionHolder: ActiveSessionHolder - @Inject lateinit var vectorPreferences: VectorPreferences - @Inject lateinit var vectorDataStore: VectorDataStore - @Inject lateinit var wifiDetector: WifiDetector - @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 + +class VectorPushHandler @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 actionIds: NotificationActionIds, + private val context: Context, + private val buildMeta: BuildMeta +) { private val coroutineScope = CoroutineScope(SupervisorJob()) @@ -81,25 +70,19 @@ class VectorMessagingReceiver : MessagingReceiver() { /** * Called when message is received. * - * @param context the Android context * @param message the message - * @param instance connection, for multi-account */ - override fun onMessage(context: Context, message: ByteArray, instance: String) { - Timber.tag(loggerTag.value).d("## onMessage() received") + fun handle(pushData: PushData) { + Timber.tag(loggerTag.value).d("## handling pushData") - val sMessage = String(message) if (buildMeta.lowPrivacyLoggingEnabled) { - Timber.tag(loggerTag.value).d("## onMessage() $sMessage") + Timber.tag(loggerTag.value).d("## pushData: $pushData") } 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) @@ -117,51 +100,7 @@ class VectorMessagingReceiver : MessagingReceiver() { // 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) } - } - } - } - - override fun onNewEndpoint(context: Context, endpoint: String, instance: String) { - Timber.tag(loggerTag.value).i("onNewEndpoint: adding $endpoint") - if (vectorPreferences.areNotificationEnabledForDevice() && activeSessionHolder.hasActiveSession()) { - // If the endpoint has changed - // or the gateway has changed - if (unifiedPushStore.getEndpointOrToken() != endpoint) { - unifiedPushStore.storeUpEndpoint(endpoint) - coroutineScope.launch { - unifiedPushHelper.storeCustomOrDefaultGateway(endpoint) { - unifiedPushStore.getPushGateway()?.let { - pushersManager.enqueueRegisterPusher(endpoint, it) - } - } - } - } else { - Timber.tag(loggerTag.value).i("onNewEndpoint: skipped") - } - } - val mode = BackgroundSyncMode.FDROID_BACKGROUND_SYNC_MODE_DISABLED - vectorPreferences.setFdroidSyncBackgroundMode(mode) - guardServiceStarter.stop() - } - - override fun onRegistrationFailed(context: Context, instance: String) { - Toast.makeText(context, "Push service registration failed", Toast.LENGTH_SHORT).show() - val mode = BackgroundSyncMode.FDROID_BACKGROUND_SYNC_MODE_FOR_REALTIME - vectorPreferences.setFdroidSyncBackgroundMode(mode) - guardServiceStarter.start() - } - - override fun onUnregistered(context: Context, instance: String) { - Timber.tag(loggerTag.value).d("Unifiedpush: Unregistered") - val mode = BackgroundSyncMode.FDROID_BACKGROUND_SYNC_MODE_FOR_REALTIME - vectorPreferences.setFdroidSyncBackgroundMode(mode) - guardServiceStarter.start() - runBlocking { - try { - pushersManager.unregisterPusher(unifiedPushStore.getEndpointOrToken().orEmpty()) - } catch (e: Exception) { - Timber.tag(loggerTag.value).d("Probably unregistering a non existing pusher") + coroutineScope.launch(Dispatchers.IO) { handleInternal(pushData) } } } } @@ -171,12 +110,12 @@ class VectorMessagingReceiver : MessagingReceiver() { * * @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) @@ -196,7 +135,7 @@ class VectorMessagingReceiver : MessagingReceiver() { } } } 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 new file mode 100644 index 0000000000..838cbd5935 --- /dev/null +++ b/vector/src/main/java/im/vector/app/core/pushers/VectorUnifiedPushMessagingReceiver.kt @@ -0,0 +1,112 @@ +/* + * 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.widget.Toast +import dagger.hilt.android.AndroidEntryPoint +import im.vector.app.core.di.ActiveSessionHolder +import im.vector.app.core.services.GuardServiceStarter +import im.vector.app.features.settings.BackgroundSyncMode +import im.vector.app.features.settings.VectorPreferences +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.SupervisorJob +import kotlinx.coroutines.launch +import kotlinx.coroutines.runBlocking +import org.matrix.android.sdk.api.logger.LoggerTag +import org.unifiedpush.android.connector.MessagingReceiver +import timber.log.Timber +import javax.inject.Inject + +private val loggerTag = LoggerTag("Push", LoggerTag.SYNC) + +/** + * Hilt injection happen at super.onReceive(). + */ +@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 + @Inject lateinit var guardServiceStarter: GuardServiceStarter + @Inject lateinit var unifiedPushStore: UnifiedPushStore + @Inject lateinit var unifiedPushHelper: UnifiedPushHelper + + private val coroutineScope = CoroutineScope(SupervisorJob()) + + /** + * Called when message is received. + * + * @param context the Android context + * @param message the message + * @param instance connection, for multi-account + */ + override fun onMessage(context: Context, message: ByteArray, instance: String) { + 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") + } + } + + override fun onNewEndpoint(context: Context, endpoint: String, instance: String) { + Timber.tag(loggerTag.value).i("onNewEndpoint: adding $endpoint") + if (vectorPreferences.areNotificationEnabledForDevice() && activeSessionHolder.hasActiveSession()) { + // If the endpoint has changed + // or the gateway has changed + if (unifiedPushHelper.getEndpointOrToken() != endpoint) { + unifiedPushStore.storeUpEndpoint(endpoint) + coroutineScope.launch { + unifiedPushHelper.storeCustomOrDefaultGateway(endpoint) { + unifiedPushHelper.getPushGateway()?.let { + pushersManager.enqueueRegisterPusher(endpoint, it) + } + } + } + } else { + Timber.tag(loggerTag.value).i("onNewEndpoint: skipped") + } + } + val mode = BackgroundSyncMode.FDROID_BACKGROUND_SYNC_MODE_DISABLED + vectorPreferences.setFdroidSyncBackgroundMode(mode) + guardServiceStarter.stop() + } + + override fun onRegistrationFailed(context: Context, instance: String) { + Toast.makeText(context, "Push service registration failed", Toast.LENGTH_SHORT).show() + val mode = BackgroundSyncMode.FDROID_BACKGROUND_SYNC_MODE_FOR_REALTIME + vectorPreferences.setFdroidSyncBackgroundMode(mode) + guardServiceStarter.start() + } + + override fun onUnregistered(context: Context, instance: String) { + Timber.tag(loggerTag.value).d("Unifiedpush: Unregistered") + val mode = BackgroundSyncMode.FDROID_BACKGROUND_SYNC_MODE_FOR_REALTIME + vectorPreferences.setFdroidSyncBackgroundMode(mode) + guardServiceStarter.start() + runBlocking { + try { + 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/home/HomeActivity.kt b/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt index 1d4cbd8427..46b7efbb97 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 a09bb1e6a4..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() } @@ -158,7 +167,14 @@ class VectorSettingsNotificationPreferenceFragment : if (vectorFeatures.allowExternalUnifiedPushDistributors()) { it.summary = unifiedPushHelper.getCurrentDistributorName() it.onPreferenceClickListener = Preference.OnPreferenceClickListener { - unifiedPushHelper.openDistributorDialog(requireActivity(), pushersManager) { + 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 66222f759e..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 @@ -37,12 +36,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 } @@ -60,7 +58,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 ) 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 }