diff --git a/app/build.gradle.kts b/app/build.gradle.kts index ea45e51bf8..6131abf385 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -301,6 +301,7 @@ dependencies { testImplementation(libs.test.turbine) testImplementation(projects.libraries.matrix.test) testImplementation(projects.services.toolbox.test) + testImplementation(projects.tests.testutils) koverDependencies() } diff --git a/app/src/main/kotlin/io/element/android/x/intent/DefaultIntentProvider.kt b/app/src/main/kotlin/io/element/android/x/intent/DefaultIntentProvider.kt index fedcdf2919..3366c1ee50 100644 --- a/app/src/main/kotlin/io/element/android/x/intent/DefaultIntentProvider.kt +++ b/app/src/main/kotlin/io/element/android/x/intent/DefaultIntentProvider.kt @@ -11,7 +11,7 @@ import android.content.Context import android.content.Intent import androidx.core.net.toUri import com.squareup.anvil.annotations.ContributesBinding -import io.element.android.libraries.deeplink.DeepLinkCreator +import io.element.android.libraries.deeplink.api.DeepLinkCreator import io.element.android.libraries.di.AppScope import io.element.android.libraries.di.ApplicationContext import io.element.android.libraries.matrix.api.core.RoomId diff --git a/app/src/test/kotlin/io/element/android/x/intent/DefaultIntentProviderTest.kt b/app/src/test/kotlin/io/element/android/x/intent/DefaultIntentProviderTest.kt index 5e81d6b964..9d6d9d4320 100644 --- a/app/src/test/kotlin/io/element/android/x/intent/DefaultIntentProviderTest.kt +++ b/app/src/test/kotlin/io/element/android/x/intent/DefaultIntentProviderTest.kt @@ -5,15 +5,22 @@ * Please see LICENSE files in the repository root for full details. */ +@file:Suppress("SameParameterValue") + package io.element.android.x.intent import android.content.Context import android.content.Intent import com.google.common.truth.Truth.assertThat -import io.element.android.libraries.deeplink.DeepLinkCreator +import io.element.android.libraries.deeplink.api.DeepLinkCreator +import io.element.android.libraries.matrix.api.core.RoomId +import io.element.android.libraries.matrix.api.core.SessionId +import io.element.android.libraries.matrix.api.core.ThreadId import io.element.android.libraries.matrix.test.A_ROOM_ID import io.element.android.libraries.matrix.test.A_SESSION_ID import io.element.android.libraries.matrix.test.A_THREAD_ID +import io.element.android.tests.testutils.lambda.lambdaRecorder +import io.element.android.tests.testutils.lambda.value import io.element.android.x.MainActivity import org.junit.Test import org.junit.runner.RunWith @@ -23,45 +30,31 @@ import org.robolectric.RuntimeEnvironment @RunWith(RobolectricTestRunner::class) class DefaultIntentProviderTest { @Test - fun `test getViewRoomIntent with Session`() { - val sut = createDefaultIntentProvider() - val result = sut.getViewRoomIntent( - sessionId = A_SESSION_ID, - roomId = null, - threadId = null, + fun `test getViewRoomIntent with data`() { + val deepLinkCreator = lambdaRecorder { _, _, _ -> "deepLinkCreatorResult" } + val sut = createDefaultIntentProvider( + deepLinkCreator = { sessionId, roomId, threadId -> deepLinkCreator.invoke(sessionId, roomId, threadId) }, ) - result.commonAssertions() - assertThat(result.data.toString()).isEqualTo("elementx://open/@alice:server.org") - } - - @Test - fun `test getViewRoomIntent with Session and Room`() { - val sut = createDefaultIntentProvider() - val result = sut.getViewRoomIntent( - sessionId = A_SESSION_ID, - roomId = A_ROOM_ID, - threadId = null, - ) - result.commonAssertions() - assertThat(result.data.toString()).isEqualTo("elementx://open/@alice:server.org/!aRoomId:domain") - } - - @Test - fun `test getViewRoomIntent with Session, Room and Thread`() { - val sut = createDefaultIntentProvider() val result = sut.getViewRoomIntent( sessionId = A_SESSION_ID, roomId = A_ROOM_ID, threadId = A_THREAD_ID, ) result.commonAssertions() - assertThat(result.data.toString()).isEqualTo("elementx://open/@alice:server.org/!aRoomId:domain/\$aThreadId") + assertThat(result.data.toString()).isEqualTo("deepLinkCreatorResult") + deepLinkCreator.assertions().isCalledOnce().with( + value(A_SESSION_ID), + value(A_ROOM_ID), + value(A_THREAD_ID), + ) } - private fun createDefaultIntentProvider(): DefaultIntentProvider { + private fun createDefaultIntentProvider( + deepLinkCreator: DeepLinkCreator = DeepLinkCreator { _, _, _ -> "" }, + ): DefaultIntentProvider { return DefaultIntentProvider( context = RuntimeEnvironment.getApplication() as Context, - deepLinkCreator = DeepLinkCreator(), + deepLinkCreator = deepLinkCreator, ) } diff --git a/appnav/build.gradle.kts b/appnav/build.gradle.kts index bc0fa405a7..715dd79d9b 100644 --- a/appnav/build.gradle.kts +++ b/appnav/build.gradle.kts @@ -27,7 +27,7 @@ dependencies { implementation(projects.libraries.core) implementation(projects.libraries.androidutils) implementation(projects.libraries.architecture) - implementation(projects.libraries.deeplink) + implementation(projects.libraries.deeplink.api) implementation(projects.libraries.matrix.api) implementation(projects.libraries.oidc.api) implementation(projects.libraries.preferences.api) diff --git a/appnav/src/main/kotlin/io/element/android/appnav/RootFlowNode.kt b/appnav/src/main/kotlin/io/element/android/appnav/RootFlowNode.kt index 3d02739ba6..c64288839b 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/RootFlowNode.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/RootFlowNode.kt @@ -44,7 +44,7 @@ import io.element.android.libraries.architecture.BaseFlowNode import io.element.android.libraries.architecture.createNode import io.element.android.libraries.architecture.waitForChildAttached import io.element.android.libraries.core.uri.ensureProtocol -import io.element.android.libraries.deeplink.DeeplinkData +import io.element.android.libraries.deeplink.api.DeeplinkData import io.element.android.libraries.designsystem.theme.components.CircularProgressIndicator import io.element.android.libraries.di.AppScope import io.element.android.libraries.matrix.api.auth.MatrixAuthenticationService diff --git a/appnav/src/main/kotlin/io/element/android/appnav/intent/IntentResolver.kt b/appnav/src/main/kotlin/io/element/android/appnav/intent/IntentResolver.kt index 786b694c3f..0c8a7cb17f 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/intent/IntentResolver.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/intent/IntentResolver.kt @@ -10,8 +10,8 @@ package io.element.android.appnav.intent import android.content.Intent import io.element.android.features.login.api.LoginIntentResolver import io.element.android.features.login.api.LoginParams -import io.element.android.libraries.deeplink.DeeplinkData -import io.element.android.libraries.deeplink.DeeplinkParser +import io.element.android.libraries.deeplink.api.DeeplinkData +import io.element.android.libraries.deeplink.api.DeeplinkParser import io.element.android.libraries.matrix.api.permalink.PermalinkData import io.element.android.libraries.matrix.api.permalink.PermalinkParser import io.element.android.libraries.oidc.api.OidcAction diff --git a/appnav/src/test/kotlin/io/element/android/appnav/intent/IntentResolverTest.kt b/appnav/src/test/kotlin/io/element/android/appnav/intent/IntentResolverTest.kt index e95eb66cc3..05898c75f3 100644 --- a/appnav/src/test/kotlin/io/element/android/appnav/intent/IntentResolverTest.kt +++ b/appnav/src/test/kotlin/io/element/android/appnav/intent/IntentResolverTest.kt @@ -14,9 +14,7 @@ import androidx.core.net.toUri import com.google.common.truth.Truth.assertThat import io.element.android.features.login.api.LoginParams import io.element.android.features.login.test.FakeLoginIntentResolver -import io.element.android.libraries.deeplink.DeepLinkCreator -import io.element.android.libraries.deeplink.DeeplinkData -import io.element.android.libraries.deeplink.DeeplinkParser +import io.element.android.libraries.deeplink.api.DeeplinkData import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.permalink.PermalinkData import io.element.android.libraries.matrix.test.A_ROOM_ID @@ -46,15 +44,11 @@ class IntentResolverTest { @Test fun `test resolve navigation intent root`() { - val sut = createIntentResolver() + val sut = createIntentResolver( + deeplinkParserResult = DeeplinkData.Root(A_SESSION_ID) + ) val intent = Intent(RuntimeEnvironment.getApplication(), Activity::class.java).apply { action = Intent.ACTION_VIEW - data = DeepLinkCreator().room( - sessionId = A_SESSION_ID, - roomId = null, - threadId = null, - ) - .toUri() } val result = sut.resolve(intent) assertThat(result).isEqualTo( @@ -68,15 +62,15 @@ class IntentResolverTest { @Test fun `test resolve navigation intent room`() { - val sut = createIntentResolver() - val intent = Intent(RuntimeEnvironment.getApplication(), Activity::class.java).apply { - action = Intent.ACTION_VIEW - data = DeepLinkCreator().room( + val sut = createIntentResolver( + deeplinkParserResult = DeeplinkData.Room( sessionId = A_SESSION_ID, roomId = A_ROOM_ID, threadId = null, ) - .toUri() + ) + val intent = Intent(RuntimeEnvironment.getApplication(), Activity::class.java).apply { + action = Intent.ACTION_VIEW } val result = sut.resolve(intent) assertThat(result).isEqualTo( @@ -92,15 +86,15 @@ class IntentResolverTest { @Test fun `test resolve navigation intent thread`() { - val sut = createIntentResolver() - val intent = Intent(RuntimeEnvironment.getApplication(), Activity::class.java).apply { - action = Intent.ACTION_VIEW - data = DeepLinkCreator().room( + val sut = createIntentResolver( + deeplinkParserResult = DeeplinkData.Room( sessionId = A_SESSION_ID, roomId = A_ROOM_ID, threadId = A_THREAD_ID, ) - .toUri() + ) + val intent = Intent(RuntimeEnvironment.getApplication(), Activity::class.java).apply { + action = Intent.ACTION_VIEW } val result = sut.resolve(intent) assertThat(result).isEqualTo( @@ -240,12 +234,13 @@ class IntentResolverTest { } private fun createIntentResolver( + deeplinkParserResult: DeeplinkData? = null, permalinkParserResult: (String) -> PermalinkData = { lambdaError() }, loginIntentResolverResult: (String) -> LoginParams? = { lambdaError() }, oidcIntentResolverResult: (Intent) -> OidcAction? = { lambdaError() }, ): IntentResolver { return IntentResolver( - deeplinkParser = DeeplinkParser(), + deeplinkParser = { deeplinkParserResult }, loginIntentResolver = FakeLoginIntentResolver( parseResult = loginIntentResolverResult, ), diff --git a/features/createroom/impl/build.gradle.kts b/features/createroom/impl/build.gradle.kts index 99e8fc653f..d2306837d0 100644 --- a/features/createroom/impl/build.gradle.kts +++ b/features/createroom/impl/build.gradle.kts @@ -32,7 +32,7 @@ dependencies { implementation(projects.libraries.designsystem) implementation(projects.libraries.uiStrings) implementation(projects.libraries.androidutils) - implementation(projects.libraries.deeplink) + implementation(projects.libraries.deeplink.api) implementation(projects.libraries.mediapickers.api) implementation(projects.libraries.mediaupload.api) implementation(projects.libraries.permissions.api) diff --git a/features/home/impl/build.gradle.kts b/features/home/impl/build.gradle.kts index 972c0817e2..e3c8321cd5 100644 --- a/features/home/impl/build.gradle.kts +++ b/features/home/impl/build.gradle.kts @@ -38,7 +38,7 @@ dependencies { implementation(projects.libraries.dateformatter.api) implementation(projects.libraries.eventformatter.api) implementation(projects.libraries.indicator.api) - implementation(projects.libraries.deeplink) + implementation(projects.libraries.deeplink.api) implementation(projects.libraries.fullscreenintent.api) implementation(projects.libraries.permissions.api) implementation(projects.libraries.permissions.noop) diff --git a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/HomeFlowNode.kt b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/HomeFlowNode.kt index d08abb6891..4265114e24 100644 --- a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/HomeFlowNode.kt +++ b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/HomeFlowNode.kt @@ -44,7 +44,7 @@ import io.element.android.features.reportroom.api.ReportRoomEntryPoint import io.element.android.libraries.architecture.BackstackView import io.element.android.libraries.architecture.BaseFlowNode import io.element.android.libraries.architecture.appyx.launchMolecule -import io.element.android.libraries.deeplink.usecase.InviteFriendsUseCase +import io.element.android.libraries.deeplink.api.usecase.InviteFriendsUseCase import io.element.android.libraries.di.SessionScope import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.core.RoomId diff --git a/features/startchat/impl/build.gradle.kts b/features/startchat/impl/build.gradle.kts index 270c329a02..ddc8a271ef 100644 --- a/features/startchat/impl/build.gradle.kts +++ b/features/startchat/impl/build.gradle.kts @@ -33,7 +33,7 @@ dependencies { implementation(projects.libraries.designsystem) implementation(projects.libraries.uiStrings) implementation(projects.libraries.androidutils) - implementation(projects.libraries.deeplink) + implementation(projects.libraries.deeplink.api) implementation(projects.libraries.mediapickers.api) implementation(projects.libraries.mediaupload.api) implementation(projects.libraries.permissions.api) diff --git a/features/startchat/impl/src/main/kotlin/io/element/android/features/startchat/impl/root/StartChatNode.kt b/features/startchat/impl/src/main/kotlin/io/element/android/features/startchat/impl/root/StartChatNode.kt index f42b7da7cc..9b9a1ec0dc 100644 --- a/features/startchat/impl/src/main/kotlin/io/element/android/features/startchat/impl/root/StartChatNode.kt +++ b/features/startchat/impl/src/main/kotlin/io/element/android/features/startchat/impl/root/StartChatNode.kt @@ -21,7 +21,7 @@ import dagger.assisted.AssistedInject import im.vector.app.features.analytics.plan.MobileScreen import io.element.android.anvilannotations.ContributesNode import io.element.android.features.startchat.StartChatNavigator -import io.element.android.libraries.deeplink.usecase.InviteFriendsUseCase +import io.element.android.libraries.deeplink.api.usecase.InviteFriendsUseCase import io.element.android.libraries.di.SessionScope import io.element.android.libraries.matrix.api.core.toRoomIdOrAlias import io.element.android.services.analytics.api.AnalyticsService diff --git a/libraries/deeplink/api/build.gradle.kts b/libraries/deeplink/api/build.gradle.kts new file mode 100644 index 0000000000..01d568df52 --- /dev/null +++ b/libraries/deeplink/api/build.gradle.kts @@ -0,0 +1,17 @@ +/* + * Copyright 2022-2024 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial + * Please see LICENSE files in the repository root for full details. + */ +plugins { + id("io.element.android-library") +} + +android { + namespace = "io.element.android.libraries.deeplink.api" +} + +dependencies { + implementation(projects.libraries.matrix.api) +} diff --git a/libraries/deeplink/api/src/main/kotlin/io/element/android/libraries/deeplink/api/DeepLinkCreator.kt b/libraries/deeplink/api/src/main/kotlin/io/element/android/libraries/deeplink/api/DeepLinkCreator.kt new file mode 100644 index 0000000000..09c8c563ad --- /dev/null +++ b/libraries/deeplink/api/src/main/kotlin/io/element/android/libraries/deeplink/api/DeepLinkCreator.kt @@ -0,0 +1,16 @@ +/* + * Copyright 2023, 2024 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial + * Please see LICENSE files in the repository root for full details. + */ + +package io.element.android.libraries.deeplink.api + +import io.element.android.libraries.matrix.api.core.RoomId +import io.element.android.libraries.matrix.api.core.SessionId +import io.element.android.libraries.matrix.api.core.ThreadId + +fun interface DeepLinkCreator { + fun room(sessionId: SessionId, roomId: RoomId?, threadId: ThreadId?): String +} diff --git a/libraries/deeplink/src/main/kotlin/io/element/android/libraries/deeplink/DeeplinkData.kt b/libraries/deeplink/api/src/main/kotlin/io/element/android/libraries/deeplink/api/DeeplinkData.kt similarity index 94% rename from libraries/deeplink/src/main/kotlin/io/element/android/libraries/deeplink/DeeplinkData.kt rename to libraries/deeplink/api/src/main/kotlin/io/element/android/libraries/deeplink/api/DeeplinkData.kt index 9dc8a90509..d15652b3ee 100644 --- a/libraries/deeplink/src/main/kotlin/io/element/android/libraries/deeplink/DeeplinkData.kt +++ b/libraries/deeplink/api/src/main/kotlin/io/element/android/libraries/deeplink/api/DeeplinkData.kt @@ -5,7 +5,7 @@ * Please see LICENSE files in the repository root for full details. */ -package io.element.android.libraries.deeplink +package io.element.android.libraries.deeplink.api import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.core.SessionId diff --git a/libraries/deeplink/api/src/main/kotlin/io/element/android/libraries/deeplink/api/DeeplinkParser.kt b/libraries/deeplink/api/src/main/kotlin/io/element/android/libraries/deeplink/api/DeeplinkParser.kt new file mode 100644 index 0000000000..d101bbc2ec --- /dev/null +++ b/libraries/deeplink/api/src/main/kotlin/io/element/android/libraries/deeplink/api/DeeplinkParser.kt @@ -0,0 +1,14 @@ +/* + * Copyright 2023, 2024 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial + * Please see LICENSE files in the repository root for full details. + */ + +package io.element.android.libraries.deeplink.api + +import android.content.Intent + +fun interface DeeplinkParser { + fun getFromIntent(intent: Intent): DeeplinkData? +} diff --git a/libraries/deeplink/api/src/main/kotlin/io/element/android/libraries/deeplink/api/usecase/InviteFriendsUseCase.kt b/libraries/deeplink/api/src/main/kotlin/io/element/android/libraries/deeplink/api/usecase/InviteFriendsUseCase.kt new file mode 100644 index 0000000000..5c5bcf5043 --- /dev/null +++ b/libraries/deeplink/api/src/main/kotlin/io/element/android/libraries/deeplink/api/usecase/InviteFriendsUseCase.kt @@ -0,0 +1,14 @@ +/* + * Copyright 2023, 2024 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial + * Please see LICENSE files in the repository root for full details. + */ + +package io.element.android.libraries.deeplink.api.usecase + +import android.app.Activity + +interface InviteFriendsUseCase { + fun execute(activity: Activity) +} diff --git a/libraries/deeplink/build.gradle.kts b/libraries/deeplink/impl/build.gradle.kts similarity index 90% rename from libraries/deeplink/build.gradle.kts rename to libraries/deeplink/impl/build.gradle.kts index 5e1a06bee0..412c162299 100644 --- a/libraries/deeplink/build.gradle.kts +++ b/libraries/deeplink/impl/build.gradle.kts @@ -6,17 +6,19 @@ import extension.setupAnvil * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial * Please see LICENSE files in the repository root for full details. */ + plugins { id("io.element.android-library") } android { - namespace = "io.element.android.libraries.deeplink" + namespace = "io.element.android.libraries.deeplink.impl" } setupAnvil() dependencies { + api(projects.libraries.deeplink.api) implementation(projects.libraries.di) implementation(libs.dagger) implementation(libs.androidx.corektx) diff --git a/libraries/deeplink/src/main/kotlin/io/element/android/libraries/deeplink/Constants.kt b/libraries/deeplink/impl/src/main/kotlin/io/element/android/libraries/deeplink/impl/Constants.kt similarity index 84% rename from libraries/deeplink/src/main/kotlin/io/element/android/libraries/deeplink/Constants.kt rename to libraries/deeplink/impl/src/main/kotlin/io/element/android/libraries/deeplink/impl/Constants.kt index b39a1c97d8..1cd98a70d3 100644 --- a/libraries/deeplink/src/main/kotlin/io/element/android/libraries/deeplink/Constants.kt +++ b/libraries/deeplink/impl/src/main/kotlin/io/element/android/libraries/deeplink/impl/Constants.kt @@ -5,7 +5,7 @@ * Please see LICENSE files in the repository root for full details. */ -package io.element.android.libraries.deeplink +package io.element.android.libraries.deeplink.impl internal const val SCHEME = "elementx" internal const val HOST = "open" diff --git a/libraries/deeplink/src/main/kotlin/io/element/android/libraries/deeplink/DeepLinkCreator.kt b/libraries/deeplink/impl/src/main/kotlin/io/element/android/libraries/deeplink/impl/DefaultDeepLinkCreator.kt similarity index 61% rename from libraries/deeplink/src/main/kotlin/io/element/android/libraries/deeplink/DeepLinkCreator.kt rename to libraries/deeplink/impl/src/main/kotlin/io/element/android/libraries/deeplink/impl/DefaultDeepLinkCreator.kt index 25058e1812..0331d828d2 100644 --- a/libraries/deeplink/src/main/kotlin/io/element/android/libraries/deeplink/DeepLinkCreator.kt +++ b/libraries/deeplink/impl/src/main/kotlin/io/element/android/libraries/deeplink/impl/DefaultDeepLinkCreator.kt @@ -1,19 +1,23 @@ /* - * Copyright 2023, 2024 New Vector Ltd. + * Copyright 2025 New Vector Ltd. * * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial * Please see LICENSE files in the repository root for full details. */ -package io.element.android.libraries.deeplink +package io.element.android.libraries.deeplink.impl +import com.squareup.anvil.annotations.ContributesBinding +import io.element.android.libraries.deeplink.api.DeepLinkCreator +import io.element.android.libraries.di.AppScope import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.core.SessionId import io.element.android.libraries.matrix.api.core.ThreadId import javax.inject.Inject -class DeepLinkCreator @Inject constructor() { - fun room(sessionId: SessionId, roomId: RoomId?, threadId: ThreadId?): String { +@ContributesBinding(AppScope::class) +class DefaultDeepLinkCreator @Inject constructor() : DeepLinkCreator { + override fun room(sessionId: SessionId, roomId: RoomId?, threadId: ThreadId?): String { return buildString { append("$SCHEME://$HOST/") append(sessionId.value) diff --git a/libraries/deeplink/src/main/kotlin/io/element/android/libraries/deeplink/DeeplinkParser.kt b/libraries/deeplink/impl/src/main/kotlin/io/element/android/libraries/deeplink/impl/DefaultDeeplinkParser.kt similarity index 71% rename from libraries/deeplink/src/main/kotlin/io/element/android/libraries/deeplink/DeeplinkParser.kt rename to libraries/deeplink/impl/src/main/kotlin/io/element/android/libraries/deeplink/impl/DefaultDeeplinkParser.kt index cdb249b7b9..84b17fc9aa 100644 --- a/libraries/deeplink/src/main/kotlin/io/element/android/libraries/deeplink/DeeplinkParser.kt +++ b/libraries/deeplink/impl/src/main/kotlin/io/element/android/libraries/deeplink/impl/DefaultDeeplinkParser.kt @@ -1,21 +1,26 @@ /* - * Copyright 2023, 2024 New Vector Ltd. + * Copyright 2025 New Vector Ltd. * * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial * Please see LICENSE files in the repository root for full details. */ -package io.element.android.libraries.deeplink +package io.element.android.libraries.deeplink.impl import android.content.Intent import android.net.Uri +import com.squareup.anvil.annotations.ContributesBinding +import io.element.android.libraries.deeplink.api.DeeplinkData +import io.element.android.libraries.deeplink.api.DeeplinkParser +import io.element.android.libraries.di.AppScope import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.core.SessionId import io.element.android.libraries.matrix.api.core.ThreadId import javax.inject.Inject -class DeeplinkParser @Inject constructor() { - fun getFromIntent(intent: Intent): DeeplinkData? { +@ContributesBinding(AppScope::class) +class DefaultDeeplinkParser @Inject constructor() : DeeplinkParser { + override fun getFromIntent(intent: Intent): DeeplinkData? { return intent .takeIf { it.action == Intent.ACTION_VIEW } ?.data diff --git a/libraries/deeplink/src/main/kotlin/io/element/android/libraries/deeplink/usecase/InviteFriendsUseCase.kt b/libraries/deeplink/impl/src/main/kotlin/io/element/android/libraries/deeplink/impl/usecase/DefaultInviteFriendsUseCase.kt similarity index 79% rename from libraries/deeplink/src/main/kotlin/io/element/android/libraries/deeplink/usecase/InviteFriendsUseCase.kt rename to libraries/deeplink/impl/src/main/kotlin/io/element/android/libraries/deeplink/impl/usecase/DefaultInviteFriendsUseCase.kt index dc072fc9bc..8c24234cd8 100644 --- a/libraries/deeplink/src/main/kotlin/io/element/android/libraries/deeplink/usecase/InviteFriendsUseCase.kt +++ b/libraries/deeplink/impl/src/main/kotlin/io/element/android/libraries/deeplink/impl/usecase/DefaultInviteFriendsUseCase.kt @@ -1,15 +1,18 @@ /* - * Copyright 2023, 2024 New Vector Ltd. + * Copyright 2025 New Vector Ltd. * * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial * Please see LICENSE files in the repository root for full details. */ -package io.element.android.libraries.deeplink.usecase +package io.element.android.libraries.deeplink.impl.usecase import android.app.Activity +import com.squareup.anvil.annotations.ContributesBinding import io.element.android.libraries.androidutils.system.startSharePlainTextIntent import io.element.android.libraries.core.meta.BuildMeta +import io.element.android.libraries.deeplink.api.usecase.InviteFriendsUseCase +import io.element.android.libraries.di.SessionScope import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.permalink.PermalinkBuilder import io.element.android.libraries.ui.strings.CommonStrings @@ -18,13 +21,14 @@ import timber.log.Timber import javax.inject.Inject import io.element.android.libraries.androidutils.R as AndroidUtilsR -class InviteFriendsUseCase @Inject constructor( +@ContributesBinding(SessionScope::class) +class DefaultInviteFriendsUseCase @Inject constructor( private val stringProvider: StringProvider, private val matrixClient: MatrixClient, private val buildMeta: BuildMeta, private val permalinkBuilder: PermalinkBuilder, -) { - fun execute(activity: Activity) { +) : InviteFriendsUseCase { + override fun execute(activity: Activity) { val permalinkResult = permalinkBuilder.permalinkForUser(matrixClient.sessionId) permalinkResult.fold( onSuccess = { permalink -> diff --git a/libraries/deeplink/src/test/kotlin/io/element/android/libraries/deeplink/DeepLinkCreatorTest.kt b/libraries/deeplink/impl/src/test/kotlin/io/element/android/libraries/deeplink/impl/DefaultDeepLinkCreatorTest.kt similarity index 87% rename from libraries/deeplink/src/test/kotlin/io/element/android/libraries/deeplink/DeepLinkCreatorTest.kt rename to libraries/deeplink/impl/src/test/kotlin/io/element/android/libraries/deeplink/impl/DefaultDeepLinkCreatorTest.kt index f6114fabb2..db6afe65f9 100644 --- a/libraries/deeplink/src/test/kotlin/io/element/android/libraries/deeplink/DeepLinkCreatorTest.kt +++ b/libraries/deeplink/impl/src/test/kotlin/io/element/android/libraries/deeplink/impl/DefaultDeepLinkCreatorTest.kt @@ -5,7 +5,7 @@ * Please see LICENSE files in the repository root for full details. */ -package io.element.android.libraries.deeplink +package io.element.android.libraries.deeplink.impl import com.google.common.truth.Truth.assertThat import io.element.android.libraries.matrix.test.A_ROOM_ID @@ -13,10 +13,10 @@ import io.element.android.libraries.matrix.test.A_SESSION_ID import io.element.android.libraries.matrix.test.A_THREAD_ID import org.junit.Test -class DeepLinkCreatorTest { +class DefaultDeepLinkCreatorTest { @Test fun room() { - val sut = DeepLinkCreator() + val sut = DefaultDeepLinkCreator() assertThat(sut.room(A_SESSION_ID, null, null)) .isEqualTo("elementx://open/@alice:server.org") assertThat(sut.room(A_SESSION_ID, A_ROOM_ID, null)) diff --git a/libraries/deeplink/src/test/kotlin/io/element/android/libraries/deeplink/DeeplinkParserTest.kt b/libraries/deeplink/impl/src/test/kotlin/io/element/android/libraries/deeplink/impl/DefaultDeeplinkParserTest.kt similarity index 90% rename from libraries/deeplink/src/test/kotlin/io/element/android/libraries/deeplink/DeeplinkParserTest.kt rename to libraries/deeplink/impl/src/test/kotlin/io/element/android/libraries/deeplink/impl/DefaultDeeplinkParserTest.kt index 48e3bab9db..787c721092 100644 --- a/libraries/deeplink/src/test/kotlin/io/element/android/libraries/deeplink/DeeplinkParserTest.kt +++ b/libraries/deeplink/impl/src/test/kotlin/io/element/android/libraries/deeplink/impl/DefaultDeeplinkParserTest.kt @@ -5,11 +5,12 @@ * Please see LICENSE files in the repository root for full details. */ -package io.element.android.libraries.deeplink +package io.element.android.libraries.deeplink.impl import android.content.Intent import androidx.core.net.toUri import com.google.common.truth.Truth.assertThat +import io.element.android.libraries.deeplink.api.DeeplinkData import io.element.android.libraries.matrix.test.A_ROOM_ID import io.element.android.libraries.matrix.test.A_SESSION_ID import io.element.android.libraries.matrix.test.A_THREAD_ID @@ -19,7 +20,7 @@ import org.junit.runner.RunWith import org.robolectric.RobolectricTestRunner @RunWith(RobolectricTestRunner::class) -class DeeplinkParserTest { +class DefaultDeeplinkParserTest { companion object { const val A_URI = "elementx://open/@alice:server.org" @@ -29,10 +30,9 @@ class DeeplinkParserTest { "elementx://open/@alice:server.org/!aRoomId:domain/\$aThreadId" } - private val sut = DeeplinkParser() - @Test fun `nominal cases`() { + val sut = DefaultDeeplinkParser() assertThat(sut.getFromIntent(createIntent(A_URI))) .isEqualTo(DeeplinkData.Root(A_SESSION_ID)) assertThat(sut.getFromIntent(createIntent(A_URI_WITH_ROOM))) @@ -43,7 +43,7 @@ class DeeplinkParserTest { @Test fun `error cases`() { - val sut = DeeplinkParser() + val sut = DefaultDeeplinkParser() // Bad scheme assertThat(sut.getFromIntent(createIntent("x://open/@alice:server.org"))).isNull() // Bad host diff --git a/plugins/src/main/kotlin/extension/DependencyHandleScope.kt b/plugins/src/main/kotlin/extension/DependencyHandleScope.kt index 0f5afb9690..440f9d338b 100644 --- a/plugins/src/main/kotlin/extension/DependencyHandleScope.kt +++ b/plugins/src/main/kotlin/extension/DependencyHandleScope.kt @@ -59,7 +59,7 @@ fun DependencyHandlerScope.composeDependencies(libs: LibrariesForLibs) { fun DependencyHandlerScope.allLibrariesImpl() { implementation(project(":libraries:androidutils")) - implementation(project(":libraries:deeplink")) + implementation(project(":libraries:deeplink:impl")) implementation(project(":libraries:designsystem")) implementation(project(":libraries:matrix:impl")) implementation(project(":libraries:matrixui"))