diff --git a/appnav/build.gradle.kts b/appnav/build.gradle.kts index 8ece3e5841..17efdc15fc 100644 --- a/appnav/build.gradle.kts +++ b/appnav/build.gradle.kts @@ -45,6 +45,7 @@ dependencies { implementation(projects.libraries.architecture) implementation(projects.libraries.matrix.api) implementation(projects.libraries.push.api) + implementation(projects.libraries.pushproviders.api) implementation(projects.libraries.designsystem) implementation(projects.libraries.matrixui) implementation(projects.libraries.uiStrings) diff --git a/appnav/src/main/kotlin/io/element/android/appnav/loggedin/LoggedInPresenter.kt b/appnav/src/main/kotlin/io/element/android/appnav/loggedin/LoggedInPresenter.kt index b628f19bd1..552420abf8 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/loggedin/LoggedInPresenter.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/loggedin/LoggedInPresenter.kt @@ -46,7 +46,9 @@ class LoggedInPresenter @Inject constructor( override fun present(): LoggedInState { LaunchedEffect(Unit) { // Ensure pusher is registered - pushService.registerFirebasePusher(matrixClient) + // TODO Register with Firebase for now + val pushProvider = pushService.getAvailablePushProviders().firstOrNull() ?: return@LaunchedEffect + pushService.registerWith(matrixClient, pushProvider, pushProvider.getDistributorNames().first()) } val permissionsState = postNotificationPermissionsPresenter.present() diff --git a/appnav/src/test/kotlin/io/element/android/appnav/loggedin/LoggedInPresenterTest.kt b/appnav/src/test/kotlin/io/element/android/appnav/loggedin/LoggedInPresenterTest.kt index 64767eaafc..595f4850b2 100644 --- a/appnav/src/test/kotlin/io/element/android/appnav/loggedin/LoggedInPresenterTest.kt +++ b/appnav/src/test/kotlin/io/element/android/appnav/loggedin/LoggedInPresenterTest.kt @@ -27,6 +27,7 @@ import io.element.android.libraries.matrix.test.FakeMatrixClient import io.element.android.libraries.permissions.api.PermissionsPresenter import io.element.android.libraries.permissions.noop.NoopPermissionsPresenter import io.element.android.libraries.push.api.PushService +import io.element.android.libraries.push.providers.api.PushProvider import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.runTest import org.junit.Test @@ -55,7 +56,11 @@ class LoggedInPresenterTest { override fun notificationStyleChanged() { } - override suspend fun registerFirebasePusher(matrixClient: MatrixClient) { + override fun getAvailablePushProviders(): List { + return emptyList() + } + + override suspend fun registerWith(matrixClient: MatrixClient, pushProvider: PushProvider, distributorName: String) { } override suspend fun testPush() { diff --git a/libraries/push/api/build.gradle.kts b/libraries/push/api/build.gradle.kts index be1bbc13ef..0c5df8fb25 100644 --- a/libraries/push/api/build.gradle.kts +++ b/libraries/push/api/build.gradle.kts @@ -26,4 +26,5 @@ dependencies { implementation(libs.androidx.corektx) implementation(libs.coroutines.core) implementation(projects.libraries.matrix.api) + implementation(projects.libraries.pushproviders.api) } 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 cf5792be35..7eeca6e0a3 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 @@ -17,12 +17,21 @@ package io.element.android.libraries.push.api import io.element.android.libraries.matrix.api.MatrixClient +import io.element.android.libraries.push.providers.api.PushProvider interface PushService { + // TODO Move away fun notificationStyleChanged() - // Ensure pusher is registered - suspend fun registerFirebasePusher(matrixClient: MatrixClient) + fun getAvailablePushProviders(): List + /** + * Will unregister any previous pusher and register a new one with the provided [PushProvider]. + * + * The method has effect only if the [PushProvider] is different than the current one. + */ + suspend fun registerWith(matrixClient: MatrixClient, pushProvider: PushProvider, distributorName: String) + + // TODO Move away suspend fun testPush() } diff --git a/libraries/push/impl/build.gradle.kts b/libraries/push/impl/build.gradle.kts index 159500a515..44fc21fb2b 100644 --- a/libraries/push/impl/build.gradle.kts +++ b/libraries/push/impl/build.gradle.kts @@ -43,6 +43,8 @@ dependencies { implementation(projects.libraries.androidutils) implementation(projects.libraries.network) implementation(projects.libraries.matrix.api) + api(projects.libraries.pushproviders.api) + api(projects.libraries.pushstore.api) api(projects.libraries.push.api) implementation(projects.services.analytics.api) @@ -53,12 +55,10 @@ dependencies { exclude(group = "com.android.support", module = "support-annotations") } + // TODO Remove implementation(platform(libs.google.firebase.bom)) implementation("com.google.firebase:firebase-messaging-ktx") - // UnifiedPush - api(libs.unifiedpush) - testImplementation(libs.test.junit) testImplementation(libs.test.mockk) testImplementation(libs.test.truth) diff --git a/libraries/push/impl/src/main/AndroidManifest.xml b/libraries/push/impl/src/main/AndroidManifest.xml index a386a89caf..6085ffe4a4 100644 --- a/libraries/push/impl/src/main/AndroidManifest.xml +++ b/libraries/push/impl/src/main/AndroidManifest.xml @@ -14,63 +14,15 @@ ~ limitations under the License. --> - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 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 7924ddf996..9bf4afa7ea 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 @@ -20,27 +20,29 @@ import com.squareup.anvil.annotations.ContributesBinding import io.element.android.libraries.di.AppScope import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.push.api.PushService -import io.element.android.libraries.push.impl.config.PushConfig -import io.element.android.libraries.push.impl.log.pushLoggerTag import io.element.android.libraries.push.impl.notifications.NotificationDrawerManager -import timber.log.Timber +import io.element.android.libraries.push.providers.api.PushProvider import javax.inject.Inject @ContributesBinding(AppScope::class) class DefaultPushService @Inject constructor( private val notificationDrawerManager: NotificationDrawerManager, private val pushersManager: PushersManager, - private val fcmHelper: FcmHelper, + private val pushProviders: Set<@JvmSuppressWildcards PushProvider>, ) : PushService { override fun notificationStyleChanged() { notificationDrawerManager.notificationStyleChanged() } - override suspend fun registerFirebasePusher(matrixClient: MatrixClient) { - val pushKey = fcmHelper.getFcmToken() ?: return Unit.also { - Timber.tag(pushLoggerTag.value).w("Unable to register pusher, Firebase token is not known.") - } - pushersManager.registerPusher(matrixClient, pushKey, PushConfig.pusher_http_url) + override fun getAvailablePushProviders(): List { + // TODO Sort by priority? + return pushProviders.toList() + } + + override suspend fun registerWith(matrixClient: MatrixClient, pushProvider: PushProvider, distributorName: String) { + // TODO Get current push provider, compare with provided one, then unregister and register if different, and store change + + pushProvider.registerWith(matrixClient, distributorName) } override suspend fun testPush() { diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/FcmHelper.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/FcmHelper.kt deleted file mode 100644 index 9b8b6c2281..0000000000 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/FcmHelper.kt +++ /dev/null @@ -1,49 +0,0 @@ -/* - * 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 io.element.android.libraries.push.impl - -interface FcmHelper { - fun isFirebaseAvailable(): Boolean - - /** - * Retrieves the FCM registration token. - * - * @return the FCM token or null if not received from FCM. - */ - fun getFcmToken(): String? - - /** - * Store FCM token to the SharedPrefs. - * - * @param token the token to store. - */ - fun storeFcmToken(token: String?) - - /** - * onNewToken may not be called on application upgrade, so ensure my shared pref is set. - * - * @param pushersManager the instance to register the pusher on. - * @param registerPusher whether the pusher should be registered. - */ - fun ensureFcmTokenIsRetrieved(pushersManager: PushersManager, registerPusher: Boolean) - - /* - fun onEnterForeground(activeSessionHolder: ActiveSessionHolder) - - fun onEnterBackground(activeSessionHolder: ActiveSessionHolder) - */ -} diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/PushersManager.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/PushersManager.kt index f1ac346909..532a904c82 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/PushersManager.kt +++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/PushersManager.kt @@ -16,7 +16,9 @@ package io.element.android.libraries.push.impl +import com.squareup.anvil.annotations.ContributesBinding import io.element.android.libraries.core.log.logger.LoggerTag +import io.element.android.libraries.di.AppScope import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.auth.MatrixAuthenticationService import io.element.android.libraries.matrix.api.core.EventId @@ -26,10 +28,9 @@ import io.element.android.libraries.push.impl.clientsecret.PushClientSecret import io.element.android.libraries.push.impl.config.PushConfig import io.element.android.libraries.push.impl.log.pushLoggerTag import io.element.android.libraries.push.impl.pushgateway.PushGatewayNotifyRequest -import io.element.android.libraries.push.impl.userpushstore.UserPushStoreFactory -import io.element.android.libraries.push.impl.userpushstore.isFirebase +import io.element.android.libraries.push.providers.api.PusherSubscriber +import io.element.android.libraries.pushstore.api.UserPushStoreFactory import io.element.android.libraries.sessionstorage.api.SessionStore -import io.element.android.libraries.sessionstorage.api.toUserList import io.element.android.services.toolbox.api.appname.AppNameProvider import timber.log.Timber import javax.inject.Inject @@ -38,8 +39,9 @@ internal const val DEFAULT_PUSHER_FILE_TAG = "mobile" private val loggerTag = LoggerTag("PushersManager", pushLoggerTag) +@ContributesBinding(AppScope::class) class PushersManager @Inject constructor( - private val unifiedPushHelper: UnifiedPushHelper, + // private val unifiedPushHelper: UnifiedPushHelper, // private val localeProvider: LocaleProvider, private val appNameProvider: AppNameProvider, // private val getDeviceInfoUseCase: GetDeviceInfoUseCase, @@ -48,14 +50,14 @@ class PushersManager @Inject constructor( private val sessionStore: SessionStore, private val matrixAuthenticationService: MatrixAuthenticationService, private val userPushStoreFactory: UserPushStoreFactory, - private val fcmHelper: FcmHelper, -) { +): PusherSubscriber { + // TODO Move this to the PushProvider API suspend fun testPush() { pushGatewayNotifyRequest.execute( PushGatewayNotifyRequest.Params( - url = unifiedPushHelper.getPushGateway() ?: return, + url = "TODO", // unifiedPushHelper.getPushGateway() ?: return, appId = PushConfig.pusher_app_id, - pushKey = unifiedPushHelper.getEndpointOrToken().orEmpty(), + pushKey = "TODO", // unifiedPushHelper.getEndpointOrToken().orEmpty(), eventId = TEST_EVENT_ID ) ) @@ -73,26 +75,10 @@ class PushersManager @Inject constructor( TODO() } - suspend fun onNewFirebaseToken(firebaseToken: String) { - fcmHelper.storeFcmToken(firebaseToken) - - // Register the pusher for all the sessions - sessionStore.getAllSessions().toUserList().forEach { userId -> - val userDataStore = userPushStoreFactory.create(userId) - if (userDataStore.isFirebase()) { - matrixAuthenticationService.restoreSession(SessionId(userId)).getOrNull()?.use { client -> - registerPusher(client, firebaseToken, PushConfig.pusher_http_url) - } - } else { - Timber.tag(loggerTag.value).d("This session is not using Firebase pusher") - } - } - } - /** * Register a pusher to the server if not done yet. */ - suspend fun registerPusher(matrixClient: MatrixClient, pushKey: String, gateway: String) { + override suspend fun registerPusher(matrixClient: MatrixClient, pushKey: String, gateway: String) { val userDataStore = userPushStoreFactory.create(matrixClient.sessionId.value) if (userDataStore.getCurrentRegisteredPushKey() == pushKey) { Timber.tag(loggerTag.value).d("Unnecessary to register again the same pusher") diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/config/PushConfig.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/config/PushConfig.kt index d2d1c96506..823dd7f693 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/config/PushConfig.kt +++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/config/PushConfig.kt @@ -17,25 +17,8 @@ package io.element.android.libraries.push.impl.config object PushConfig { - /** - * It is the push gateway for FCM embedded distributor. - * Note: pusher_http_url should have path '/_matrix/push/v1/notify' --> - */ - const val pusher_http_url: String = "https://matrix.org/_matrix/push/v1/notify" - - /** - * It is the push gateway for UnifiedPush. - * Note: default_push_gateway_http_url should have path '/_matrix/push/v1/notify' - */ - const val default_push_gateway_http_url: String = "https://matrix.gateway.unifiedpush.org/_matrix/push/v1/notify" - /** * Note: pusher_app_id cannot exceed 64 chars. */ const val pusher_app_id: String = "im.vector.app.android" - - /** - * Set to true to allow external push distributor such as Ntfy. - */ - const val allowExternalUnifiedPushDistributors: Boolean = false } diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/push/PushHandler.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/push/DefaultPushHandler.kt similarity index 93% rename from libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/push/PushHandler.kt rename to libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/push/DefaultPushHandler.kt index b4c9716b62..30ee74f3de 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/push/PushHandler.kt +++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/push/DefaultPushHandler.kt @@ -21,9 +21,11 @@ import android.content.Intent import android.os.Handler import android.os.Looper import androidx.localbroadcastmanager.content.LocalBroadcastManager +import com.squareup.anvil.annotations.ContributesBinding import io.element.android.libraries.androidutils.network.WifiDetector import io.element.android.libraries.core.log.logger.LoggerTag import io.element.android.libraries.core.meta.BuildMeta +import io.element.android.libraries.di.AppScope import io.element.android.libraries.di.ApplicationContext import io.element.android.libraries.matrix.api.auth.MatrixAuthenticationService import io.element.android.libraries.push.api.store.PushDataStore @@ -34,6 +36,8 @@ import io.element.android.libraries.push.impl.notifications.NotifiableEventResol import io.element.android.libraries.push.impl.notifications.NotificationActionIds import io.element.android.libraries.push.impl.notifications.NotificationDrawerManager import io.element.android.libraries.push.impl.store.DefaultPushDataStore +import io.element.android.libraries.push.providers.api.PushData +import io.element.android.libraries.push.providers.api.PushHandler import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.SupervisorJob @@ -43,7 +47,8 @@ import javax.inject.Inject private val loggerTag = LoggerTag("PushHandler", pushLoggerTag) -class PushHandler @Inject constructor( +@ContributesBinding(AppScope::class) +class DefaultPushHandler @Inject constructor( private val notificationDrawerManager: NotificationDrawerManager, private val notifiableEventResolver: NotifiableEventResolver, private val pushDataStore: PushDataStore, @@ -53,7 +58,7 @@ class PushHandler @Inject constructor( @ApplicationContext private val context: Context, private val buildMeta: BuildMeta, private val matrixAuthenticationService: MatrixAuthenticationService, -) { +): PushHandler { private val coroutineScope = CoroutineScope(SupervisorJob()) private val wifiDetector: WifiDetector = WifiDetector(context) @@ -68,7 +73,7 @@ class PushHandler @Inject constructor( * * @param pushData the data received in the push. */ - suspend fun handle(pushData: PushData) { + override suspend fun handle(pushData: PushData) { Timber.tag(loggerTag.value).d("## handling pushData") if (buildMeta.lowPrivacyLoggingEnabled) { diff --git a/libraries/pushproviders/api/build.gradle.kts b/libraries/pushproviders/api/build.gradle.kts new file mode 100644 index 0000000000..08d397b383 --- /dev/null +++ b/libraries/pushproviders/api/build.gradle.kts @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2023 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. + */ + +plugins { + id("io.element.android-library") +} + +android { + namespace = "io.element.android.libraries.push.providers.api" +} + +dependencies { + implementation(projects.libraries.core) + implementation(projects.libraries.matrix.api) +} diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/push/PushData.kt b/libraries/pushproviders/api/src/main/kotlin/io/element/android/libraries/push/providers/api/PushData.kt similarity index 85% rename from libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/push/PushData.kt rename to libraries/pushproviders/api/src/main/kotlin/io/element/android/libraries/push/providers/api/PushData.kt index aaf6d65c08..b304d10b34 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/push/PushData.kt +++ b/libraries/pushproviders/api/src/main/kotlin/io/element/android/libraries/push/providers/api/PushData.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package io.element.android.libraries.push.impl.push +package io.element.android.libraries.push.providers.api import io.element.android.libraries.matrix.api.core.EventId import io.element.android.libraries.matrix.api.core.RoomId @@ -28,8 +28,8 @@ import io.element.android.libraries.matrix.api.core.RoomId * @property clientSecret data used when the pusher was configured, to be able to determine the session. */ data class PushData( - val eventId: EventId, - val roomId: RoomId, - val unread: Int?, - val clientSecret: String?, + val eventId: EventId, + val roomId: RoomId, + val unread: Int?, + val clientSecret: String?, ) diff --git a/libraries/pushproviders/api/src/main/kotlin/io/element/android/libraries/push/providers/api/PushHandler.kt b/libraries/pushproviders/api/src/main/kotlin/io/element/android/libraries/push/providers/api/PushHandler.kt new file mode 100644 index 0000000000..09ca420a1f --- /dev/null +++ b/libraries/pushproviders/api/src/main/kotlin/io/element/android/libraries/push/providers/api/PushHandler.kt @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2023 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 io.element.android.libraries.push.providers.api + +interface PushHandler { + suspend fun handle(pushData: PushData) +} diff --git a/libraries/pushproviders/api/src/main/kotlin/io/element/android/libraries/push/providers/api/PushProvider.kt b/libraries/pushproviders/api/src/main/kotlin/io/element/android/libraries/push/providers/api/PushProvider.kt new file mode 100644 index 0000000000..2b90c3d5b3 --- /dev/null +++ b/libraries/pushproviders/api/src/main/kotlin/io/element/android/libraries/push/providers/api/PushProvider.kt @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2023 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 io.element.android.libraries.push.providers.api + +import io.element.android.libraries.matrix.api.MatrixClient + +/** + * This is the main API for this module + */ +interface PushProvider { + fun getDistributorNames(): List + suspend fun registerWith(matrixClient: MatrixClient, distributorName: String) +} diff --git a/libraries/pushproviders/api/src/main/kotlin/io/element/android/libraries/push/providers/api/PusherSubscriber.kt b/libraries/pushproviders/api/src/main/kotlin/io/element/android/libraries/push/providers/api/PusherSubscriber.kt new file mode 100644 index 0000000000..805244e0ed --- /dev/null +++ b/libraries/pushproviders/api/src/main/kotlin/io/element/android/libraries/push/providers/api/PusherSubscriber.kt @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2023 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 io.element.android.libraries.push.providers.api + +import io.element.android.libraries.matrix.api.MatrixClient + +interface PusherSubscriber { + suspend fun registerPusher(matrixClient: MatrixClient, pushKey: String, gateway: String) +} diff --git a/libraries/pushproviders/firebase/build.gradle.kts b/libraries/pushproviders/firebase/build.gradle.kts new file mode 100644 index 0000000000..65360d5465 --- /dev/null +++ b/libraries/pushproviders/firebase/build.gradle.kts @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2023 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. + */ + +plugins { + id("io.element.android-library") + alias(libs.plugins.anvil) + // kotlin("plugin.serialization") version "1.8.10" +} + +android { + namespace = "io.element.android.libraries.push.providers.firebase" +} + +anvil { + generateDaggerFactories.set(true) +} + +dependencies { + implementation(libs.dagger) + implementation(libs.androidx.corektx) + implementation(projects.libraries.architecture) + implementation(projects.libraries.core) + implementation(projects.libraries.di) + implementation(projects.libraries.matrix.api) + + implementation(projects.libraries.pushstore.api) + implementation(projects.libraries.pushproviders.api) + + implementation(platform(libs.google.firebase.bom)) + implementation("com.google.firebase:firebase-messaging-ktx") + + testImplementation(libs.test.junit) + testImplementation(libs.test.truth) + testImplementation(projects.libraries.matrix.test) +} diff --git a/libraries/pushproviders/firebase/src/main/AndroidManifest.xml b/libraries/pushproviders/firebase/src/main/AndroidManifest.xml new file mode 100644 index 0000000000..40dc254644 --- /dev/null +++ b/libraries/pushproviders/firebase/src/main/AndroidManifest.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/firebase/EnsureFcmTokenIsRetrievedUseCase.kt b/libraries/pushproviders/firebase/src/main/kotlin/io/element/android/libraries/push/providers/firebase/EnsureFcmTokenIsRetrievedUseCase.kt similarity index 66% rename from libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/firebase/EnsureFcmTokenIsRetrievedUseCase.kt rename to libraries/pushproviders/firebase/src/main/kotlin/io/element/android/libraries/push/providers/firebase/EnsureFcmTokenIsRetrievedUseCase.kt index 9e9b28ecb8..e859976789 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/firebase/EnsureFcmTokenIsRetrievedUseCase.kt +++ b/libraries/pushproviders/firebase/src/main/kotlin/io/element/android/libraries/push/providers/firebase/EnsureFcmTokenIsRetrievedUseCase.kt @@ -14,24 +14,22 @@ * limitations under the License. */ -package io.element.android.libraries.push.impl.firebase +package io.element.android.libraries.push.providers.firebase -import io.element.android.libraries.push.impl.FcmHelper -import io.element.android.libraries.push.impl.PushersManager -import io.element.android.libraries.push.impl.UnifiedPushHelper import javax.inject.Inject +// TODO class EnsureFcmTokenIsRetrievedUseCase @Inject constructor( - private val unifiedPushHelper: UnifiedPushHelper, - private val fcmHelper: FcmHelper, +// private val unifiedPushHelper: UnifiedPushHelper, +// private val fcmHelper: FcmHelper, // private val activeSessionHolder: ActiveSessionHolder, ) { - fun execute(pushersManager: PushersManager, registerPusher: Boolean) { - if (unifiedPushHelper.isEmbeddedDistributor()) { - fcmHelper.ensureFcmTokenIsRetrieved(pushersManager, shouldAddHttpPusher(registerPusher)) - } - } +// fun execute(pushersManager: PushersManager, registerPusher: Boolean) { +// if (unifiedPushHelper.isEmbeddedDistributor()) { +// fcmHelper.ensureFcmTokenIsRetrieved(pushersManager, shouldAddHttpPusher(registerPusher)) +// } +// } private fun shouldAddHttpPusher(registerPusher: Boolean) = if (registerPusher) { /* diff --git a/libraries/pushproviders/firebase/src/main/kotlin/io/element/android/libraries/push/providers/firebase/FirebaseConfig.kt b/libraries/pushproviders/firebase/src/main/kotlin/io/element/android/libraries/push/providers/firebase/FirebaseConfig.kt new file mode 100644 index 0000000000..27463825d6 --- /dev/null +++ b/libraries/pushproviders/firebase/src/main/kotlin/io/element/android/libraries/push/providers/firebase/FirebaseConfig.kt @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2023 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 io.element.android.libraries.push.providers.firebase + +object FirebaseConfig { + /** + * It is the push gateway for firebase. + * Note: pusher_http_url should have path '/_matrix/push/v1/notify' --> + */ + const val pusher_http_url: String = "https://matrix.org/_matrix/push/v1/notify" + + const val internalName = "NOTIFICATION_METHOD_FIREBASE" +} diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/firebase/FirebasePushParser.kt b/libraries/pushproviders/firebase/src/main/kotlin/io/element/android/libraries/push/providers/firebase/FirebasePushParser.kt similarity index 85% rename from libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/firebase/FirebasePushParser.kt rename to libraries/pushproviders/firebase/src/main/kotlin/io/element/android/libraries/push/providers/firebase/FirebasePushParser.kt index 8659c299ae..d3af7d8448 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/firebase/FirebasePushParser.kt +++ b/libraries/pushproviders/firebase/src/main/kotlin/io/element/android/libraries/push/providers/firebase/FirebasePushParser.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 New Vector Ltd + * Copyright (c) 2023 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. @@ -14,9 +14,9 @@ * limitations under the License. */ -package io.element.android.libraries.push.impl.firebase +package io.element.android.libraries.push.providers.firebase -import io.element.android.libraries.push.impl.push.PushData +import io.element.android.libraries.push.providers.api.PushData import javax.inject.Inject class FirebasePushParser @Inject constructor() { diff --git a/libraries/pushproviders/firebase/src/main/kotlin/io/element/android/libraries/push/providers/firebase/FirebasePushProvider.kt b/libraries/pushproviders/firebase/src/main/kotlin/io/element/android/libraries/push/providers/firebase/FirebasePushProvider.kt new file mode 100644 index 0000000000..855762e5ab --- /dev/null +++ b/libraries/pushproviders/firebase/src/main/kotlin/io/element/android/libraries/push/providers/firebase/FirebasePushProvider.kt @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2023 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 io.element.android.libraries.push.providers.firebase + +import io.element.android.libraries.core.log.logger.LoggerTag +import io.element.android.libraries.matrix.api.MatrixClient +import io.element.android.libraries.push.providers.api.PushProvider +import io.element.android.libraries.push.providers.api.PusherSubscriber +import timber.log.Timber +import javax.inject.Inject + +private val loggerTag = LoggerTag("FirebasePushProvider") + +class FirebasePushProvider @Inject constructor( + private val googleFcmHelper: GoogleFcmHelper, + private val pusherSubscriber: PusherSubscriber, +) : PushProvider { + + override fun getDistributorNames(): List { + // Must return an non-empty list for now + return listOf("unused") + } + + override suspend fun registerWith(matrixClient: MatrixClient, distributorName: String) { + val pushKey = googleFcmHelper.getFcmToken() ?: return Unit.also { + Timber.tag(loggerTag.value).w("Unable to register pusher, Firebase token is not known.") + } + pusherSubscriber.registerPusher(matrixClient, pushKey, FirebaseConfig.pusher_http_url) + } +} diff --git a/libraries/pushproviders/firebase/src/main/kotlin/io/element/android/libraries/push/providers/firebase/FirebaseSetPusher.kt b/libraries/pushproviders/firebase/src/main/kotlin/io/element/android/libraries/push/providers/firebase/FirebaseSetPusher.kt new file mode 100644 index 0000000000..ea6937551a --- /dev/null +++ b/libraries/pushproviders/firebase/src/main/kotlin/io/element/android/libraries/push/providers/firebase/FirebaseSetPusher.kt @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2023 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 io.element.android.libraries.push.providers.firebase + +import io.element.android.libraries.core.log.logger.LoggerTag +import io.element.android.libraries.matrix.api.auth.MatrixAuthenticationService +import io.element.android.libraries.matrix.api.core.SessionId +import io.element.android.libraries.push.providers.api.PusherSubscriber +import io.element.android.libraries.pushstore.api.UserPushStoreFactory +import io.element.android.libraries.sessionstorage.api.SessionStore +import io.element.android.libraries.sessionstorage.api.toUserList +import timber.log.Timber +import javax.inject.Inject + +private val loggerTag = LoggerTag("FirebaseSetPusher") + +// TODO Rename +class FirebaseSetPusher @Inject constructor( + private val pusherSubscriber: PusherSubscriber, + private val sessionStore: SessionStore, + private val userPushStoreFactory: UserPushStoreFactory, + private val matrixAuthenticationService: MatrixAuthenticationService, +) { + suspend fun onNewFirebaseToken(firebaseToken: String) { + // Register the pusher for all the sessions + sessionStore.getAllSessions().toUserList().forEach { userId -> + val userDataStore = userPushStoreFactory.create(userId) + if (userDataStore.getNotificationMethod() == FirebaseConfig.internalName) { + matrixAuthenticationService.restoreSession(SessionId(userId)).getOrNull()?.use { client -> + pusherSubscriber.registerPusher(client, firebaseToken, FirebaseConfig.pusher_http_url) + } + } else { + Timber.tag(loggerTag.value).d("This session is not using Firebase pusher") + } + } + } +} diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/GoogleFcmHelper.kt b/libraries/pushproviders/firebase/src/main/kotlin/io/element/android/libraries/push/providers/firebase/GoogleFcmHelper.kt old mode 100755 new mode 100644 similarity index 87% rename from libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/GoogleFcmHelper.kt rename to libraries/pushproviders/firebase/src/main/kotlin/io/element/android/libraries/push/providers/firebase/GoogleFcmHelper.kt index 6c73607196..0772ac0603 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/GoogleFcmHelper.kt +++ b/libraries/pushproviders/firebase/src/main/kotlin/io/element/android/libraries/push/providers/firebase/GoogleFcmHelper.kt @@ -14,44 +14,37 @@ * limitations under the License. */ -package io.element.android.libraries.push.impl +package io.element.android.libraries.push.providers.firebase import android.content.Context import android.content.SharedPreferences -import android.widget.Toast import androidx.core.content.edit import com.google.android.gms.common.ConnectionResult import com.google.android.gms.common.GoogleApiAvailability -import com.google.firebase.messaging.FirebaseMessaging -import com.squareup.anvil.annotations.ContributesBinding -import io.element.android.libraries.di.AppScope import io.element.android.libraries.di.ApplicationContext import io.element.android.libraries.di.DefaultPreferences -import kotlinx.coroutines.runBlocking -import timber.log.Timber import javax.inject.Inject /** * This class store the FCM token in SharedPrefs and ensure this token is retrieved. * It has an alter ego in the fdroid variant. */ -@ContributesBinding(AppScope::class) +// TODO Rename to store? class GoogleFcmHelper @Inject constructor( @ApplicationContext private val context: Context, @DefaultPreferences private val sharedPrefs: SharedPreferences, -) : FcmHelper { - override fun isFirebaseAvailable(): Boolean = true - - override fun getFcmToken(): String? { +) { + fun getFcmToken(): String? { return sharedPrefs.getString(PREFS_KEY_FCM_TOKEN, null) } - override fun storeFcmToken(token: String?) { + fun storeFcmToken(token: String?) { sharedPrefs.edit { putString(PREFS_KEY_FCM_TOKEN, token) } } + /* override fun ensureFcmTokenIsRetrieved(pushersManager: PushersManager, registerPusher: Boolean) { // 'app should always check the device for a compatible Google Play services APK before accessing Google Play services features' if (checkPlayServices(context)) { @@ -76,6 +69,7 @@ class GoogleFcmHelper @Inject constructor( Timber.e("No valid Google Play Services found. Cannot use FCM.") } } + */ /** * Check the device to make sure it has the Google Play Services APK. If diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/firebase/PushDataFirebase.kt b/libraries/pushproviders/firebase/src/main/kotlin/io/element/android/libraries/push/providers/firebase/PushDataFirebase.kt similarity index 91% rename from libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/firebase/PushDataFirebase.kt rename to libraries/pushproviders/firebase/src/main/kotlin/io/element/android/libraries/push/providers/firebase/PushDataFirebase.kt index 739c161e79..5c336e7dc6 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/firebase/PushDataFirebase.kt +++ b/libraries/pushproviders/firebase/src/main/kotlin/io/element/android/libraries/push/providers/firebase/PushDataFirebase.kt @@ -14,11 +14,11 @@ * limitations under the License. */ -package io.element.android.libraries.push.impl.firebase +package io.element.android.libraries.push.providers.firebase import io.element.android.libraries.matrix.api.core.asEventId import io.element.android.libraries.matrix.api.core.asRoomId -import io.element.android.libraries.push.impl.push.PushData +import io.element.android.libraries.push.providers.api.PushData /** * In this case, the format is: diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/firebase/VectorFirebaseMessagingService.kt b/libraries/pushproviders/firebase/src/main/kotlin/io/element/android/libraries/push/providers/firebase/VectorFirebaseMessagingService.kt similarity index 82% rename from libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/firebase/VectorFirebaseMessagingService.kt rename to libraries/pushproviders/firebase/src/main/kotlin/io/element/android/libraries/push/providers/firebase/VectorFirebaseMessagingService.kt index 2ccf6f2505..02bb84c541 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/firebase/VectorFirebaseMessagingService.kt +++ b/libraries/pushproviders/firebase/src/main/kotlin/io/element/android/libraries/push/providers/firebase/VectorFirebaseMessagingService.kt @@ -14,27 +14,26 @@ * limitations under the License. */ -package io.element.android.libraries.push.impl.firebase +package io.element.android.libraries.push.providers.firebase import com.google.firebase.messaging.FirebaseMessagingService import com.google.firebase.messaging.RemoteMessage import io.element.android.libraries.architecture.bindings import io.element.android.libraries.core.log.logger.LoggerTag -import io.element.android.libraries.push.impl.PushersManager -import io.element.android.libraries.push.impl.log.pushLoggerTag -import io.element.android.libraries.push.impl.push.PushHandler +import io.element.android.libraries.push.providers.api.PushHandler import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.launch import timber.log.Timber import javax.inject.Inject -private val loggerTag = LoggerTag("Firebase", pushLoggerTag) +private val loggerTag = LoggerTag("Firebase") class VectorFirebaseMessagingService : FirebaseMessagingService() { - @Inject lateinit var pushersManager: PushersManager + @Inject lateinit var firebaseSetPusher: FirebaseSetPusher @Inject lateinit var pushParser: FirebasePushParser @Inject lateinit var pushHandler: PushHandler + @Inject lateinit var googleFcmHelper: GoogleFcmHelper private val coroutineScope = CoroutineScope(SupervisorJob()) @@ -45,8 +44,9 @@ class VectorFirebaseMessagingService : FirebaseMessagingService() { override fun onNewToken(token: String) { Timber.tag(loggerTag.value).d("New Firebase token") + googleFcmHelper.storeFcmToken(token) coroutineScope.launch { - pushersManager.onNewFirebaseToken(token) + firebaseSetPusher.onNewFirebaseToken(token) } } diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/firebase/VectorFirebaseMessagingServiceBindings.kt b/libraries/pushproviders/firebase/src/main/kotlin/io/element/android/libraries/push/providers/firebase/VectorFirebaseMessagingServiceBindings.kt similarity index 93% rename from libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/firebase/VectorFirebaseMessagingServiceBindings.kt rename to libraries/pushproviders/firebase/src/main/kotlin/io/element/android/libraries/push/providers/firebase/VectorFirebaseMessagingServiceBindings.kt index aef87e7df3..e17cc922ee 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/firebase/VectorFirebaseMessagingServiceBindings.kt +++ b/libraries/pushproviders/firebase/src/main/kotlin/io/element/android/libraries/push/providers/firebase/VectorFirebaseMessagingServiceBindings.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package io.element.android.libraries.push.impl.firebase +package io.element.android.libraries.push.providers.firebase import com.squareup.anvil.annotations.ContributesTo import io.element.android.libraries.di.AppScope diff --git a/libraries/pushproviders/firebase/src/main/kotlin/io/element/android/libraries/push/providers/firebase/di/FirebaseModule.kt b/libraries/pushproviders/firebase/src/main/kotlin/io/element/android/libraries/push/providers/firebase/di/FirebaseModule.kt new file mode 100644 index 0000000000..9e36754101 --- /dev/null +++ b/libraries/pushproviders/firebase/src/main/kotlin/io/element/android/libraries/push/providers/firebase/di/FirebaseModule.kt @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2023 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 io.element.android.libraries.push.providers.firebase.di + +import com.squareup.anvil.annotations.ContributesTo +import dagger.Binds +import dagger.Module +import dagger.multibindings.IntoSet +import io.element.android.libraries.di.AppScope +import io.element.android.libraries.push.providers.api.PushProvider +import io.element.android.libraries.push.providers.firebase.FirebasePushProvider + +@Module +@ContributesTo(AppScope::class) +interface FirebaseModule { + @Binds + @IntoSet + fun bind(pushProvider: FirebasePushProvider): PushProvider +} diff --git a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/firebase/FirebasePushParserTest.kt b/libraries/pushproviders/firebase/src/test/kotlin/io/element/android/libraries/push/providers/firebase/FirebasePushParserTest.kt similarity index 95% rename from libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/firebase/FirebasePushParserTest.kt rename to libraries/pushproviders/firebase/src/test/kotlin/io/element/android/libraries/push/providers/firebase/FirebasePushParserTest.kt index b14e067dae..a6525657c8 100644 --- a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/firebase/FirebasePushParserTest.kt +++ b/libraries/pushproviders/firebase/src/test/kotlin/io/element/android/libraries/push/providers/firebase/FirebasePushParserTest.kt @@ -14,12 +14,12 @@ * limitations under the License. */ -package io.element.android.libraries.push.impl.firebase +package io.element.android.libraries.push.providers.firebase import com.google.common.truth.Truth.assertThat import io.element.android.libraries.matrix.test.AN_EVENT_ID import io.element.android.libraries.matrix.test.A_ROOM_ID -import io.element.android.libraries.push.impl.push.PushData +import io.element.android.libraries.push.providers.api.PushData import org.junit.Test class FirebasePushParserTest { diff --git a/libraries/pushproviders/unifiedpush/build.gradle.kts b/libraries/pushproviders/unifiedpush/build.gradle.kts new file mode 100644 index 0000000000..6817d0aad6 --- /dev/null +++ b/libraries/pushproviders/unifiedpush/build.gradle.kts @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2023 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. + */ + +plugins { + id("io.element.android-library") + alias(libs.plugins.anvil) + kotlin("plugin.serialization") version "1.8.10" +} + +android { + namespace = "io.element.android.libraries.push.providers.unifiedpush" +} + +anvil { + generateDaggerFactories.set(true) +} + +dependencies { + implementation(libs.dagger) + implementation(projects.libraries.core) + implementation(projects.libraries.matrix.api) + + implementation(projects.libraries.pushproviders.api) + implementation(projects.libraries.architecture) + implementation(projects.libraries.core) + implementation(projects.services.toolbox.api) + + implementation(libs.serialization.json) + + // UnifiedPush library + api(libs.unifiedpush) + + testImplementation(libs.test.junit) + testImplementation(libs.test.truth) + testImplementation(projects.libraries.matrix.test) +} diff --git a/libraries/pushproviders/unifiedpush/src/main/AndroidManifest.xml b/libraries/pushproviders/unifiedpush/src/main/AndroidManifest.xml new file mode 100644 index 0000000000..719733ab3e --- /dev/null +++ b/libraries/pushproviders/unifiedpush/src/main/AndroidManifest.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/unifiedpush/GuardServiceStarter.kt b/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/push/providers/unifiedpush/GuardServiceStarter.kt similarity index 93% rename from libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/unifiedpush/GuardServiceStarter.kt rename to libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/push/providers/unifiedpush/GuardServiceStarter.kt index 08bd4a8326..f92468d047 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/unifiedpush/GuardServiceStarter.kt +++ b/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/push/providers/unifiedpush/GuardServiceStarter.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package io.element.android.libraries.push.impl.unifiedpush +package io.element.android.libraries.push.providers.unifiedpush import com.squareup.anvil.annotations.ContributesBinding import io.element.android.libraries.di.AppScope diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/unifiedpush/KeepInternalDistributor.kt b/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/push/providers/unifiedpush/KeepInternalDistributor.kt similarity index 90% rename from libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/unifiedpush/KeepInternalDistributor.kt rename to libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/push/providers/unifiedpush/KeepInternalDistributor.kt index de66ed3914..d2e0713f74 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/unifiedpush/KeepInternalDistributor.kt +++ b/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/push/providers/unifiedpush/KeepInternalDistributor.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 New Vector Ltd + * Copyright (c) 2023 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package io.element.android.libraries.push.impl.unifiedpush +package io.element.android.libraries.push.providers.unifiedpush import android.content.BroadcastReceiver import android.content.Context diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/unifiedpush/PushDataUnifiedPush.kt b/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/push/providers/unifiedpush/PushDataUnifiedPush.kt similarity index 93% rename from libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/unifiedpush/PushDataUnifiedPush.kt rename to libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/push/providers/unifiedpush/PushDataUnifiedPush.kt index 73d5f0286a..6d5ecb1db3 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/unifiedpush/PushDataUnifiedPush.kt +++ b/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/push/providers/unifiedpush/PushDataUnifiedPush.kt @@ -14,11 +14,11 @@ * limitations under the License. */ -package io.element.android.libraries.push.impl.unifiedpush +package io.element.android.libraries.push.providers.unifiedpush import io.element.android.libraries.matrix.api.core.asEventId import io.element.android.libraries.matrix.api.core.asRoomId -import io.element.android.libraries.push.impl.push.PushData +import io.element.android.libraries.push.providers.api.PushData import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/unifiedpush/RegisterUnifiedPushUseCase.kt b/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/push/providers/unifiedpush/RegisterUnifiedPushUseCase.kt similarity index 86% rename from libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/unifiedpush/RegisterUnifiedPushUseCase.kt rename to libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/push/providers/unifiedpush/RegisterUnifiedPushUseCase.kt index 50ca94f30d..a80d9ba865 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/unifiedpush/RegisterUnifiedPushUseCase.kt +++ b/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/push/providers/unifiedpush/RegisterUnifiedPushUseCase.kt @@ -14,11 +14,10 @@ * limitations under the License. */ -package io.element.android.libraries.push.impl.unifiedpush +package io.element.android.libraries.push.providers.unifiedpush import android.content.Context import io.element.android.libraries.di.ApplicationContext -import io.element.android.libraries.push.impl.config.PushConfig import org.unifiedpush.android.connector.UnifiedPush import javax.inject.Inject @@ -37,11 +36,6 @@ class RegisterUnifiedPushUseCase @Inject constructor( return RegisterUnifiedPushResult.Success } - if (!PushConfig.allowExternalUnifiedPushDistributors) { - saveAndRegisterApp(context.packageName) - return RegisterUnifiedPushResult.Success - } - if (UnifiedPush.getDistributor(context).isNotEmpty()) { registerApp() return RegisterUnifiedPushResult.Success diff --git a/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/push/providers/unifiedpush/UnifiedPushConfig.kt b/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/push/providers/unifiedpush/UnifiedPushConfig.kt new file mode 100644 index 0000000000..73c31f430c --- /dev/null +++ b/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/push/providers/unifiedpush/UnifiedPushConfig.kt @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2023 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 io.element.android.libraries.push.providers.unifiedpush + +object UnifiedPushConfig { + /** + * It is the push gateway for UnifiedPush. + * Note: default_push_gateway_http_url should have path '/_matrix/push/v1/notify' + */ + const val default_push_gateway_http_url: String = "https://matrix.gateway.unifiedpush.org/_matrix/push/v1/notify" + + const val internalName = "NOTIFICATION_METHOD_UNIFIEDPUSH" +} diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/UnifiedPushHelper.kt b/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/push/providers/unifiedpush/UnifiedPushHelper.kt similarity index 90% rename from libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/UnifiedPushHelper.kt rename to libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/push/providers/unifiedpush/UnifiedPushHelper.kt index 12ed3f1993..dce17015b7 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/UnifiedPushHelper.kt +++ b/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/push/providers/unifiedpush/UnifiedPushHelper.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 New Vector Ltd + * Copyright (c) 2023 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. @@ -14,12 +14,10 @@ * limitations under the License. */ -package io.element.android.libraries.push.impl +package io.element.android.libraries.push.providers.unifiedpush import android.content.Context -import io.element.android.libraries.androidutils.system.getApplicationLabel import io.element.android.libraries.di.ApplicationContext -import io.element.android.libraries.push.impl.config.PushConfig import io.element.android.services.toolbox.api.strings.StringProvider import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @@ -31,8 +29,6 @@ import javax.inject.Inject class UnifiedPushHelper @Inject constructor( @ApplicationContext private val context: Context, private val unifiedPushStore: UnifiedPushStore, - // private val matrix: Matrix, - private val fcmHelper: FcmHelper, private val stringProvider: StringProvider, ) { @@ -95,11 +91,14 @@ class UnifiedPushHelper @Inject constructor( // if we use the embedded distributor, // register app_id type upfcm on sygnal // the pushkey if FCM key + /* if (UnifiedPush.getDistributor(context) == context.packageName) { unifiedPushStore.storePushGateway(PushConfig.pusher_http_url) onDoneRunnable?.run() return } + + */ /* TODO EAx UnifiedPush // else, unifiedpush, and pushkey is an endpoint val gateway = PushConfig.default_push_gateway_http_url @@ -132,19 +131,25 @@ class UnifiedPushHelper @Inject constructor( } fun getCurrentDistributorName(): String { + TODO() + /* return when { isEmbeddedDistributor() -> stringProvider.getString(R.string.push_distributor_firebase_android) isBackgroundSync() -> stringProvider.getString(R.string.push_distributor_background_sync_android) else -> context.getApplicationLabel(UnifiedPush.getDistributor(context)) } + + */ } fun isEmbeddedDistributor(): Boolean { - return isInternalDistributor() && fcmHelper.isFirebaseAvailable() + TODO() + //return isInternalDistributor() && fcmHelper.isFirebaseAvailable() } fun isBackgroundSync(): Boolean { - return isInternalDistributor() && !fcmHelper.isFirebaseAvailable() + TODO() + //return isInternalDistributor() && !fcmHelper.isFirebaseAvailable() } private fun isInternalDistributor(): Boolean { @@ -168,12 +173,13 @@ class UnifiedPushHelper @Inject constructor( } fun getEndpointOrToken(): String? { - return if (isEmbeddedDistributor()) fcmHelper.getFcmToken() + // TODO + return if (isEmbeddedDistributor()) "" // fcmHelper.getFcmToken() else unifiedPushStore.getEndpoint() } fun getPushGateway(): String? { - return if (isEmbeddedDistributor()) PushConfig.pusher_http_url + return if (isEmbeddedDistributor()) "" // PushConfig.pusher_http_url else unifiedPushStore.getPushGateway() } } diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/unifiedpush/UnifiedPushParser.kt b/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/push/providers/unifiedpush/UnifiedPushParser.kt similarity index 85% rename from libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/unifiedpush/UnifiedPushParser.kt rename to libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/push/providers/unifiedpush/UnifiedPushParser.kt index 05cd8425b7..881862d473 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/unifiedpush/UnifiedPushParser.kt +++ b/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/push/providers/unifiedpush/UnifiedPushParser.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 New Vector Ltd + * Copyright (c) 2023 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. @@ -14,10 +14,10 @@ * limitations under the License. */ -package io.element.android.libraries.push.impl.unifiedpush +package io.element.android.libraries.push.providers.unifiedpush import io.element.android.libraries.core.data.tryOrNull -import io.element.android.libraries.push.impl.push.PushData +import io.element.android.libraries.push.providers.api.PushData import kotlinx.serialization.decodeFromString import kotlinx.serialization.json.Json import javax.inject.Inject diff --git a/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/push/providers/unifiedpush/UnifiedPushProvider.kt b/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/push/providers/unifiedpush/UnifiedPushProvider.kt new file mode 100644 index 0000000000..a37e9da5e2 --- /dev/null +++ b/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/push/providers/unifiedpush/UnifiedPushProvider.kt @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2023 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 io.element.android.libraries.push.providers.unifiedpush + +import io.element.android.libraries.matrix.api.MatrixClient +import io.element.android.libraries.push.providers.api.PushProvider +import javax.inject.Inject + +class UnifiedPushProvider @Inject constructor(): PushProvider { + override fun getDistributorNames(): List { + TODO("Not yet implemented") + } + + override suspend fun registerWith(matrixClient: MatrixClient, distributorName: String) { + TODO("Not yet implemented") + } +} diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/UnifiedPushStore.kt b/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/push/providers/unifiedpush/UnifiedPushStore.kt similarity index 95% rename from libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/UnifiedPushStore.kt rename to libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/push/providers/unifiedpush/UnifiedPushStore.kt index 226d0c5669..31d7bbd63e 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/UnifiedPushStore.kt +++ b/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/push/providers/unifiedpush/UnifiedPushStore.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 New Vector Ltd + * Copyright (c) 2023 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package io.element.android.libraries.push.impl +package io.element.android.libraries.push.providers.unifiedpush import android.content.Context import android.content.SharedPreferences diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/unifiedpush/UnregisterUnifiedPushUseCase.kt b/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/push/providers/unifiedpush/UnregisterUnifiedPushUseCase.kt similarity index 72% rename from libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/unifiedpush/UnregisterUnifiedPushUseCase.kt rename to libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/push/providers/unifiedpush/UnregisterUnifiedPushUseCase.kt index 6cd1af1de3..b7cd592951 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/unifiedpush/UnregisterUnifiedPushUseCase.kt +++ b/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/push/providers/unifiedpush/UnregisterUnifiedPushUseCase.kt @@ -14,19 +14,9 @@ * limitations under the License. */ -package io.element.android.libraries.push.impl.unifiedpush - -import android.content.Context -import io.element.android.libraries.di.ApplicationContext -import io.element.android.libraries.push.api.model.BackgroundSyncMode -import io.element.android.libraries.push.api.store.PushDataStore -import io.element.android.libraries.push.impl.PushersManager -import io.element.android.libraries.push.impl.UnifiedPushHelper -import io.element.android.libraries.push.impl.UnifiedPushStore -import org.unifiedpush.android.connector.UnifiedPush -import timber.log.Timber -import javax.inject.Inject +package io.element.android.libraries.push.providers.unifiedpush +/* class UnregisterUnifiedPushUseCase @Inject constructor( @ApplicationContext private val context: Context, private val pushDataStore: PushDataStore, @@ -50,3 +40,4 @@ class UnregisterUnifiedPushUseCase @Inject constructor( UnifiedPush.unregisterApp(context) } } + */ diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/unifiedpush/VectorUnifiedPushMessagingReceiver.kt b/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/push/providers/unifiedpush/VectorUnifiedPushMessagingReceiver.kt similarity index 82% rename from libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/unifiedpush/VectorUnifiedPushMessagingReceiver.kt rename to libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/push/providers/unifiedpush/VectorUnifiedPushMessagingReceiver.kt index acb438cc70..d745df6e87 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/unifiedpush/VectorUnifiedPushMessagingReceiver.kt +++ b/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/push/providers/unifiedpush/VectorUnifiedPushMessagingReceiver.kt @@ -14,40 +14,29 @@ * limitations under the License. */ -package io.element.android.libraries.push.impl.unifiedpush +package io.element.android.libraries.push.providers.unifiedpush import android.content.Context import android.content.Intent -import android.widget.Toast import io.element.android.libraries.architecture.bindings import io.element.android.libraries.core.log.logger.LoggerTag -import io.element.android.libraries.push.api.model.BackgroundSyncMode -import io.element.android.libraries.push.api.store.PushDataStore -import io.element.android.libraries.push.impl.PushersManager -import io.element.android.libraries.push.impl.UnifiedPushHelper -import io.element.android.libraries.push.impl.UnifiedPushStore -import io.element.android.libraries.push.impl.log.pushLoggerTag -import io.element.android.libraries.push.impl.push.PushHandler +import io.element.android.libraries.push.providers.api.PushHandler import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.launch -import kotlinx.coroutines.runBlocking import org.unifiedpush.android.connector.MessagingReceiver import timber.log.Timber import javax.inject.Inject -private val loggerTag = LoggerTag("Unified", pushLoggerTag) +private val loggerTag = LoggerTag("VectorUnifiedPushMessagingReceiver") class VectorUnifiedPushMessagingReceiver : MessagingReceiver() { - @Inject lateinit var pushersManager: PushersManager @Inject lateinit var pushParser: UnifiedPushParser - - //@Inject lateinit var activeSessionHolder: ActiveSessionHolder - @Inject lateinit var pushDataStore: PushDataStore + // @Inject lateinit var pushDataStore: PushDataStore @Inject lateinit var pushHandler: PushHandler @Inject lateinit var guardServiceStarter: GuardServiceStarter - @Inject lateinit var unifiedPushStore: UnifiedPushStore - @Inject lateinit var unifiedPushHelper: UnifiedPushHelper +// @Inject lateinit var unifiedPushStore: UnifiedPushStore +// @Inject lateinit var unifiedPushHelper: UnifiedPushHelper private val coroutineScope = CoroutineScope(SupervisorJob()) @@ -77,6 +66,8 @@ class VectorUnifiedPushMessagingReceiver : MessagingReceiver() { } override fun onNewEndpoint(context: Context, endpoint: String, instance: String) { + TODO() + /* Timber.tag(loggerTag.value).i("onNewEndpoint: adding $endpoint") if (pushDataStore.areNotificationEnabledForDevice() /* TODO EAx && activeSessionHolder.hasActiveSession() */) { // If the endpoint has changed @@ -99,16 +90,22 @@ class VectorUnifiedPushMessagingReceiver : MessagingReceiver() { val mode = BackgroundSyncMode.FDROID_BACKGROUND_SYNC_MODE_DISABLED pushDataStore.setFdroidSyncBackgroundMode(mode) guardServiceStarter.stop() + */ } override fun onRegistrationFailed(context: Context, instance: String) { + TODO() + /* Toast.makeText(context, "Push service registration failed", Toast.LENGTH_SHORT).show() val mode = BackgroundSyncMode.FDROID_BACKGROUND_SYNC_MODE_FOR_REALTIME pushDataStore.setFdroidSyncBackgroundMode(mode) guardServiceStarter.start() + */ } override fun onUnregistered(context: Context, instance: String) { + TODO() + /* Timber.tag(loggerTag.value).d("Unifiedpush: Unregistered") val mode = BackgroundSyncMode.FDROID_BACKGROUND_SYNC_MODE_FOR_REALTIME pushDataStore.setFdroidSyncBackgroundMode(mode) @@ -120,5 +117,6 @@ class VectorUnifiedPushMessagingReceiver : MessagingReceiver() { Timber.tag(loggerTag.value).d("Probably unregistering a non existing pusher") } } + */ } } diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/unifiedpush/VectorUnifiedPushMessagingReceiverBindings.kt b/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/push/providers/unifiedpush/VectorUnifiedPushMessagingReceiverBindings.kt similarity index 93% rename from libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/unifiedpush/VectorUnifiedPushMessagingReceiverBindings.kt rename to libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/push/providers/unifiedpush/VectorUnifiedPushMessagingReceiverBindings.kt index 90857d990d..603e297c6b 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/unifiedpush/VectorUnifiedPushMessagingReceiverBindings.kt +++ b/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/push/providers/unifiedpush/VectorUnifiedPushMessagingReceiverBindings.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package io.element.android.libraries.push.impl.unifiedpush +package io.element.android.libraries.push.providers.unifiedpush import com.squareup.anvil.annotations.ContributesTo import io.element.android.libraries.di.AppScope diff --git a/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/push/providers/unifiedpush/di/UnifiedPushModule.kt b/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/push/providers/unifiedpush/di/UnifiedPushModule.kt new file mode 100644 index 0000000000..9e34b349e3 --- /dev/null +++ b/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/push/providers/unifiedpush/di/UnifiedPushModule.kt @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2023 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 io.element.android.libraries.push.providers.unifiedpush.di + +import com.squareup.anvil.annotations.ContributesTo +import dagger.Binds +import dagger.Module +import dagger.multibindings.IntoSet +import io.element.android.libraries.di.AppScope +import io.element.android.libraries.push.providers.api.PushProvider +import io.element.android.libraries.push.providers.unifiedpush.UnifiedPushProvider + +@Module +@ContributesTo(AppScope::class) +interface UnifiedPushModule { + @Binds + @IntoSet + fun bind(pushProvider: UnifiedPushProvider): PushProvider +} diff --git a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/unifiedpush/UnifiedPushParserTest.kt b/libraries/pushproviders/unifiedpush/src/test/kotlin/io/element/android/libraries/push/providers/unifiedpush/UnifiedPushParserTest.kt similarity index 95% rename from libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/unifiedpush/UnifiedPushParserTest.kt rename to libraries/pushproviders/unifiedpush/src/test/kotlin/io/element/android/libraries/push/providers/unifiedpush/UnifiedPushParserTest.kt index f9275de4b2..6b5c0db62f 100644 --- a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/unifiedpush/UnifiedPushParserTest.kt +++ b/libraries/pushproviders/unifiedpush/src/test/kotlin/io/element/android/libraries/push/providers/unifiedpush/UnifiedPushParserTest.kt @@ -14,12 +14,12 @@ * limitations under the License. */ -package io.element.android.libraries.push.impl.unifiedpush +package io.element.android.libraries.push.providers.unifiedpush import com.google.common.truth.Truth.assertThat import io.element.android.libraries.matrix.test.AN_EVENT_ID import io.element.android.libraries.matrix.test.A_ROOM_ID -import io.element.android.libraries.push.impl.push.PushData +import io.element.android.libraries.push.providers.api.PushData import org.junit.Test class UnifiedPushParserTest { diff --git a/libraries/pushstore/api/build.gradle.kts b/libraries/pushstore/api/build.gradle.kts new file mode 100644 index 0000000000..de7a852ee0 --- /dev/null +++ b/libraries/pushstore/api/build.gradle.kts @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2023 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. + */ + +plugins { + id("io.element.android-library") +} + +android { + namespace = "io.element.android.libraries.pushstore.api" +} + +dependencies { +} diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/userpushstore/UserPushStore.kt b/libraries/pushstore/api/src/main/kotlin/io/element/android/libraries/pushstore/api/UserPushStore.kt similarity index 72% rename from libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/userpushstore/UserPushStore.kt rename to libraries/pushstore/api/src/main/kotlin/io/element/android/libraries/pushstore/api/UserPushStore.kt index 82c4beaf20..35ec23f80d 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/userpushstore/UserPushStore.kt +++ b/libraries/pushstore/api/src/main/kotlin/io/element/android/libraries/pushstore/api/UserPushStore.kt @@ -14,10 +14,7 @@ * limitations under the License. */ -package io.element.android.libraries.push.impl.userpushstore - -const val NOTIFICATION_METHOD_FIREBASE = "NOTIFICATION_METHOD_FIREBASE" -const val NOTIFICATION_METHOD_UNIFIEDPUSH = "NOTIFICATION_METHOD_UNIFIEDPUSH" +package io.element.android.libraries.pushstore.api /** * Store data related to push about a user. @@ -26,7 +23,7 @@ interface UserPushStore { /** * [NOTIFICATION_METHOD_FIREBASE] or [NOTIFICATION_METHOD_UNIFIEDPUSH]. */ - suspend fun getNotificationMethod(): String + suspend fun getNotificationMethod(): String? suspend fun setNotificationMethod(value: String) @@ -36,5 +33,3 @@ interface UserPushStore { suspend fun reset() } - -suspend fun UserPushStore.isFirebase(): Boolean = getNotificationMethod() == NOTIFICATION_METHOD_FIREBASE diff --git a/libraries/pushstore/api/src/main/kotlin/io/element/android/libraries/pushstore/api/UserPushStoreFactory.kt b/libraries/pushstore/api/src/main/kotlin/io/element/android/libraries/pushstore/api/UserPushStoreFactory.kt new file mode 100644 index 0000000000..832180e850 --- /dev/null +++ b/libraries/pushstore/api/src/main/kotlin/io/element/android/libraries/pushstore/api/UserPushStoreFactory.kt @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2023 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 io.element.android.libraries.pushstore.api + +/** + * Store data related to push about a user. + */ +interface UserPushStoreFactory { + fun create(userId: String): UserPushStore +} diff --git a/libraries/pushstore/impl/build.gradle.kts b/libraries/pushstore/impl/build.gradle.kts new file mode 100644 index 0000000000..0a39730199 --- /dev/null +++ b/libraries/pushstore/impl/build.gradle.kts @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2023 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. + */ + +plugins { + id("io.element.android-library") + alias(libs.plugins.anvil) +} + +android { + namespace = "io.element.android.libraries.push.pushstore.impl" +} + +anvil { + generateDaggerFactories.set(true) +} + +dependencies { + implementation(libs.dagger) + implementation(projects.libraries.architecture) + implementation(projects.libraries.core) + implementation(projects.libraries.pushstore.api) + implementation(projects.libraries.sessionStorage.api) + implementation(libs.androidx.corektx) + implementation(libs.androidx.datastore.preferences) +} diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/userpushstore/UserPushStoreFactory.kt b/libraries/pushstore/impl/src/main/kotlin/io/element/android/libraries/pushstore/impl/DefaultUserPushStoreFactory.kt similarity index 78% rename from libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/userpushstore/UserPushStoreFactory.kt rename to libraries/pushstore/impl/src/main/kotlin/io/element/android/libraries/pushstore/impl/DefaultUserPushStoreFactory.kt index 0323713de7..159c1cb892 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/userpushstore/UserPushStoreFactory.kt +++ b/libraries/pushstore/impl/src/main/kotlin/io/element/android/libraries/pushstore/impl/DefaultUserPushStoreFactory.kt @@ -14,28 +14,32 @@ * limitations under the License. */ -package io.element.android.libraries.push.impl.userpushstore +package io.element.android.libraries.pushstore.impl import android.content.Context +import com.squareup.anvil.annotations.ContributesBinding import io.element.android.libraries.di.AppScope import io.element.android.libraries.di.ApplicationContext import io.element.android.libraries.di.SingleIn +import io.element.android.libraries.pushstore.api.UserPushStore +import io.element.android.libraries.pushstore.api.UserPushStoreFactory import io.element.android.libraries.sessionstorage.api.observer.SessionListener import io.element.android.libraries.sessionstorage.api.observer.SessionObserver import javax.inject.Inject @SingleIn(AppScope::class) -class UserPushStoreFactory @Inject constructor( +@ContributesBinding(AppScope::class, boundType = UserPushStoreFactory::class) +class DefaultUserPushStoreFactory @Inject constructor( @ApplicationContext private val context: Context, private val sessionObserver: SessionObserver, -) : SessionListener { +) : UserPushStoreFactory, SessionListener { init { observeSessions() } // We can have only one class accessing a single data store, so keep a cache of them. private val cache = mutableMapOf() - fun create(userId: String): UserPushStore { + override fun create(userId: String): UserPushStore { return cache.getOrPut(userId) { UserPushStoreDataStore( context = context, diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/userpushstore/UserPushStoreDataStore.kt b/libraries/pushstore/impl/src/main/kotlin/io/element/android/libraries/pushstore/impl/UserPushStoreDataStore.kt similarity index 91% rename from libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/userpushstore/UserPushStoreDataStore.kt rename to libraries/pushstore/impl/src/main/kotlin/io/element/android/libraries/pushstore/impl/UserPushStoreDataStore.kt index 6f25599e54..8b37056768 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/userpushstore/UserPushStoreDataStore.kt +++ b/libraries/pushstore/impl/src/main/kotlin/io/element/android/libraries/pushstore/impl/UserPushStoreDataStore.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package io.element.android.libraries.push.impl.userpushstore +package io.element.android.libraries.pushstore.impl import android.content.Context import androidx.datastore.core.DataStore @@ -22,6 +22,7 @@ import androidx.datastore.preferences.core.Preferences import androidx.datastore.preferences.core.edit import androidx.datastore.preferences.core.stringPreferencesKey import androidx.datastore.preferences.preferencesDataStore +import io.element.android.libraries.pushstore.api.UserPushStore import kotlinx.coroutines.flow.first /** @@ -35,8 +36,8 @@ class UserPushStoreDataStore( private val notificationMethod = stringPreferencesKey("notificationMethod") private val currentPushKey = stringPreferencesKey("currentPushKey") - override suspend fun getNotificationMethod(): String { - return context.dataStore.data.first()[notificationMethod] ?: NOTIFICATION_METHOD_FIREBASE + override suspend fun getNotificationMethod(): String? { + return context.dataStore.data.first()[notificationMethod] } override suspend fun setNotificationMethod(value: String) { diff --git a/plugins/src/main/kotlin/extension/DependencyHandleScope.kt b/plugins/src/main/kotlin/extension/DependencyHandleScope.kt index 9f0cf92099..368747961d 100644 --- a/plugins/src/main/kotlin/extension/DependencyHandleScope.kt +++ b/plugins/src/main/kotlin/extension/DependencyHandleScope.kt @@ -75,6 +75,12 @@ fun DependencyHandlerScope.allLibrariesImpl() { implementation(project(":libraries:core")) implementation(project(":libraries:permissions:impl")) implementation(project(":libraries:push:impl")) + implementation(project(":libraries:push:impl")) + // Comment to not include firebase in the project + implementation(project(":libraries:pushproviders:firebase")) + // Comment to not include unified push in the project + // implementation(project(":libraries:pushproviders:unifiedpush")) + implementation(project(":libraries:pushstore:impl")) implementation(project(":libraries:architecture")) implementation(project(":libraries:dateformatter:impl")) implementation(project(":libraries:di"))