From 57e1aee984b4560942e4db82d843816a190ce75b Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 17 Jan 2024 16:07:26 +0100 Subject: [PATCH 1/2] Ensure that a PushProvider is available on a device before using it. It help to fallback to UnifiedPush (if available) if the PlayServices are not installed on the device. --- .../android/libraries/push/api/PushService.kt | 4 ++++ .../libraries/push/impl/DefaultPushService.kt | 4 +++- .../pushproviders/api/PushProvider.kt | 5 +++++ .../firebase/FirebasePushProvider.kt | 18 ++++++++++++++++++ .../unifiedpush/UnifiedPushProvider.kt | 15 +++++++++++++++ 5 files changed, 45 insertions(+), 1 deletion(-) diff --git a/libraries/push/api/src/main/kotlin/io/element/android/libraries/push/api/PushService.kt b/libraries/push/api/src/main/kotlin/io/element/android/libraries/push/api/PushService.kt index 1a0eb7a93c..5f4736e5ab 100644 --- a/libraries/push/api/src/main/kotlin/io/element/android/libraries/push/api/PushService.kt +++ b/libraries/push/api/src/main/kotlin/io/element/android/libraries/push/api/PushService.kt @@ -24,6 +24,10 @@ interface PushService { // TODO Move away fun notificationStyleChanged() + /** + * Return the list of push providers, available at compile time, and + * available at runtime, sorted by index. + */ fun getAvailablePushProviders(): List /** diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/DefaultPushService.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/DefaultPushService.kt index b16908269d..e60cd8b014 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/DefaultPushService.kt +++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/DefaultPushService.kt @@ -38,7 +38,9 @@ class DefaultPushService @Inject constructor( } override fun getAvailablePushProviders(): List { - return pushProviders.sortedBy { it.index } + return pushProviders + .filter { it.isAvailable() } + .sortedBy { it.index } } /** diff --git a/libraries/pushproviders/api/src/main/kotlin/io/element/android/libraries/pushproviders/api/PushProvider.kt b/libraries/pushproviders/api/src/main/kotlin/io/element/android/libraries/pushproviders/api/PushProvider.kt index d71cd9ec3f..3d8349a117 100644 --- a/libraries/pushproviders/api/src/main/kotlin/io/element/android/libraries/pushproviders/api/PushProvider.kt +++ b/libraries/pushproviders/api/src/main/kotlin/io/element/android/libraries/pushproviders/api/PushProvider.kt @@ -32,6 +32,11 @@ interface PushProvider { */ val name: String + /** + * Return true if the push provider is available on this device. + */ + fun isAvailable(): Boolean + fun getDistributors(): List /** diff --git a/libraries/pushproviders/firebase/src/main/kotlin/io/element/android/libraries/pushproviders/firebase/FirebasePushProvider.kt b/libraries/pushproviders/firebase/src/main/kotlin/io/element/android/libraries/pushproviders/firebase/FirebasePushProvider.kt index 1fad74e1be..4c3d6d3a20 100644 --- a/libraries/pushproviders/firebase/src/main/kotlin/io/element/android/libraries/pushproviders/firebase/FirebasePushProvider.kt +++ b/libraries/pushproviders/firebase/src/main/kotlin/io/element/android/libraries/pushproviders/firebase/FirebasePushProvider.kt @@ -16,9 +16,13 @@ package io.element.android.libraries.pushproviders.firebase +import android.content.Context +import com.google.android.gms.common.ConnectionResult +import com.google.android.gms.common.GoogleApiAvailability import com.squareup.anvil.annotations.ContributesMultibinding import io.element.android.libraries.core.log.logger.LoggerTag import io.element.android.libraries.di.AppScope +import io.element.android.libraries.di.ApplicationContext import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.pushproviders.api.Distributor import io.element.android.libraries.pushproviders.api.PushProvider @@ -30,6 +34,7 @@ private val loggerTag = LoggerTag("FirebasePushProvider", LoggerTag.PushLoggerTa @ContributesMultibinding(AppScope::class) class FirebasePushProvider @Inject constructor( + @ApplicationContext private val context: Context, private val firebaseStore: FirebaseStore, private val firebaseTroubleshooter: FirebaseTroubleshooter, private val pusherSubscriber: PusherSubscriber, @@ -37,6 +42,19 @@ class FirebasePushProvider @Inject constructor( override val index = FirebaseConfig.INDEX override val name = FirebaseConfig.NAME + override fun isAvailable(): Boolean { + // The PlayServices has to be available + val apiAvailability = GoogleApiAvailability.getInstance() + val resultCode = apiAvailability.isGooglePlayServicesAvailable(context) + return if (resultCode == ConnectionResult.SUCCESS) { + Timber.tag(loggerTag.value).d("Google Play Services is available") + true + } else { + Timber.tag(loggerTag.value).w("Google Play Services is not available") + false + } + } + override fun getDistributors(): List { return listOf(Distributor("Firebase", "Firebase")) } diff --git a/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/UnifiedPushProvider.kt b/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/UnifiedPushProvider.kt index bca4fd3ed3..5d0a0da7a1 100644 --- a/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/UnifiedPushProvider.kt +++ b/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/UnifiedPushProvider.kt @@ -19,6 +19,7 @@ package io.element.android.libraries.pushproviders.unifiedpush import android.content.Context import com.squareup.anvil.annotations.ContributesMultibinding import io.element.android.libraries.androidutils.system.getApplicationLabel +import io.element.android.libraries.core.log.logger.LoggerTag import io.element.android.libraries.di.AppScope import io.element.android.libraries.di.ApplicationContext import io.element.android.libraries.matrix.api.MatrixClient @@ -26,8 +27,11 @@ import io.element.android.libraries.pushproviders.api.Distributor import io.element.android.libraries.pushproviders.api.PushProvider import io.element.android.libraries.pushstore.api.clientsecret.PushClientSecret import org.unifiedpush.android.connector.UnifiedPush +import timber.log.Timber import javax.inject.Inject +private val loggerTag = LoggerTag("UnifiedPushProvider", LoggerTag.PushLoggerTag) + @ContributesMultibinding(AppScope::class) class UnifiedPushProvider @Inject constructor( @ApplicationContext private val context: Context, @@ -38,6 +42,17 @@ class UnifiedPushProvider @Inject constructor( override val index = UnifiedPushConfig.INDEX override val name = UnifiedPushConfig.NAME + override fun isAvailable(): Boolean { + val isAvailable = getDistributors().isNotEmpty() + return if (isAvailable) { + Timber.tag(loggerTag.value).d("UnifiedPush is available") + true + } else { + Timber.tag(loggerTag.value).w("UnifiedPush is not available") + false + } + } + override fun getDistributors(): List { val distributors = UnifiedPush.getDistributors(context) return distributors.mapNotNull { From 39f4d8ccedc4f7bc34f6ff206c6d2a13882c4a66 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 17 Jan 2024 16:56:26 +0100 Subject: [PATCH 2/2] changelog --- changelog.d/2248.misc | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/2248.misc diff --git a/changelog.d/2248.misc b/changelog.d/2248.misc new file mode 100644 index 0000000000..eed13375a0 --- /dev/null +++ b/changelog.d/2248.misc @@ -0,0 +1 @@ +Fallback to UnifiedPush (if available) if the PlayServices are not installed on the device.