diff --git a/CHANGES.md b/CHANGES.md index 4cfe3f1af2..8e939f71c4 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -22,6 +22,8 @@ Bugfix 🐛: - Loudspeaker is always used (#1685) - Fix uploads still don't work with room v6 (#1879) - Can't handle ongoing call events in background (#1992) + - Handle room, user and group links by the Element app (#1795) + - Update associated site domain (#1833) - Crash / Attachment viewer: Cannot draw a recycled Bitmap #2034 - Login with Matrix-Id | Autodiscovery fails if identity server is invalid and Homeserver ok (#2027) - Support for image compression on Android 10 diff --git a/tools/tests/test_configuration_link.sh b/tools/tests/test_configuration_link.sh index 33b1699e70..d0a5e38e6a 100755 --- a/tools/tests/test_configuration_link.sh +++ b/tools/tests/test_configuration_link.sh @@ -1,3 +1,3 @@ #!/usr/bin/env bash -adb shell am start -a android.intent.action.VIEW -d "https://riot.im/config/config?hs_url=https%3A%2F%2Fmozilla-test.modular.im" +adb shell am start -a android.intent.action.VIEW -d "https://mobile.element.io?hs_url=https%3A%2F%2Fmozilla-test.modular.im" diff --git a/vector/src/main/AndroidManifest.xml b/vector/src/main/AndroidManifest.xml index f07d992726..6865da3470 100644 --- a/vector/src/main/AndroidManifest.xml +++ b/vector/src/main/AndroidManifest.xml @@ -144,8 +144,10 @@ - - + + + + diff --git a/vector/src/main/java/im/vector/app/features/link/LinkHandlerActivity.kt b/vector/src/main/java/im/vector/app/features/link/LinkHandlerActivity.kt index 71a372f039..daedc2fe84 100644 --- a/vector/src/main/java/im/vector/app/features/link/LinkHandlerActivity.kt +++ b/vector/src/main/java/im/vector/app/features/link/LinkHandlerActivity.kt @@ -24,10 +24,14 @@ import im.vector.app.core.di.ActiveSessionHolder import im.vector.app.core.di.ScreenComponent import im.vector.app.core.error.ErrorFormatter import im.vector.app.core.platform.VectorBaseActivity +import im.vector.app.core.utils.toast import im.vector.app.features.login.LoginActivity import im.vector.app.features.login.LoginConfig +import im.vector.app.features.permalink.PermalinkHandler +import io.reactivex.android.schedulers.AndroidSchedulers import org.matrix.android.sdk.api.MatrixCallback import timber.log.Timber +import java.util.concurrent.TimeUnit import javax.inject.Inject /** @@ -37,6 +41,7 @@ class LinkHandlerActivity : VectorBaseActivity() { @Inject lateinit var sessionHolder: ActiveSessionHolder @Inject lateinit var errorFormatter: ErrorFormatter + @Inject lateinit var permalinkHandler: PermalinkHandler override fun injectWith(injector: ScreenComponent) { injector.inject(this) @@ -54,20 +59,57 @@ class LinkHandlerActivity : VectorBaseActivity() { return } - if (uri.path == PATH_CONFIG) { - if (sessionHolder.hasActiveSession()) { - displayAlreadyLoginPopup(uri) - } else { - // user is not yet logged in, this is the nominal case - startLoginActivity(uri) - } - } else { - // Other link are not yet handled, but should not comes here (manifest configuration error?) - Timber.w("Unable to handle this uir: $uri") - finish() + if (uri.getQueryParameter(CONFIG_PATH_HS_PARAMETER) != null) { + handleConfigUrl(uri) + } else if (SUPPORTED_HOSTS.contains(uri.host)) { + handleSupportedHostUrl(uri) } } + private fun handleConfigUrl(uri: Uri) { + if (sessionHolder.hasActiveSession()) { + displayAlreadyLoginPopup(uri) + } else { + // user is not yet logged in, this is the nominal case + startLoginActivity(uri) + } + } + + private fun handleSupportedHostUrl(uri: Uri) { + if (!sessionHolder.hasActiveSession()) { + startLoginActivity(uri) + finish() + } else { + convertUriToPermalink(uri)?.let { permalink -> + startPermalinkHandler(permalink) + } ?: run { + // Host is correct but we do not recognize path + Timber.w("Unable to handle this uri: $uri") + finish() + } + } + } + + private fun convertUriToPermalink(uri: Uri): String? { + val path = SUPPORTED_PATHS.find { it in uri.toString() } ?: return null + // https://riot.im/develop/#/room/#element-android:matrix.org -> https://matrix.to/#/#element-android:matrix.org + // https://app.element.io/#/room/#element-android:matrix.org -> https://matrix.to/#/#element-android:matrix.org + return "https://$MATRIX_TO_HOST/#" + uri.toString().substringAfter(path) + } + + private fun startPermalinkHandler(permalink: String) { + permalinkHandler.launch(this, permalink, buildTask = true) + .delay(500, TimeUnit.MILLISECONDS) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe { isHandled -> + if (!isHandled) { + toast(R.string.universal_link_malformed) + } + finish() + } + .disposeOnDestroy() + } + /** * Start the login screen with identity server and home server pre-filled */ @@ -113,6 +155,10 @@ class LinkHandlerActivity : VectorBaseActivity() { } companion object { - private const val PATH_CONFIG = "/config/config" + private const val CONFIG_PATH_HS_PARAMETER = "hs_url" + + private val SUPPORTED_HOSTS = arrayOf("app.element.io", "riot.im", "develop.element.io", "staging.element.io") + private val SUPPORTED_PATHS = arrayOf("/#/room", "/#/user", "/#/group") + private const val MATRIX_TO_HOST = "matrix.to" } } diff --git a/vector/src/main/java/im/vector/app/features/login/LoginConfig.kt b/vector/src/main/java/im/vector/app/features/login/LoginConfig.kt index 701335af6b..320d3e1871 100644 --- a/vector/src/main/java/im/vector/app/features/login/LoginConfig.kt +++ b/vector/src/main/java/im/vector/app/features/login/LoginConfig.kt @@ -22,7 +22,7 @@ import kotlinx.android.parcel.Parcelize /** * Parameters extracted from a configuration url - * Ex: https://riot.im/config/config?hs_url=https%3A%2F%2Fexample.modular.im&is_url=https%3A%2F%2Fcustom.identity.org + * Ex: https://mobile.element.io?hs_url=https%3A%2F%2Fexample.modular.im&is_url=https%3A%2F%2Fcustom.identity.org * * Note: On RiotX, identityServerUrl will never be used, so is declared private. Keep it for compatibility reason. */ diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml index 267079fdc6..a0abc28a4d 100644 --- a/vector/src/main/res/values/strings.xml +++ b/vector/src/main/res/values/strings.xml @@ -2564,4 +2564,7 @@ Confirm PIN to disable PIN Can\'t open a room where you are banned from. Can\'t find this room. Make sure it exists. + + + The link was malformed