From a151f42495536759b76b48d8e7cec7618c7060f8 Mon Sep 17 00:00:00 2001 From: Onuray Sahin Date: Wed, 2 Sep 2020 18:26:08 +0300 Subject: [PATCH 1/8] Handle room, user, group links by converting them to permalinks. --- vector/src/main/AndroidManifest.xml | 3 +- .../app/features/link/LinkHandlerActivity.kt | 51 +++++++++++++++++-- 2 files changed, 49 insertions(+), 5 deletions(-) diff --git a/vector/src/main/AndroidManifest.xml b/vector/src/main/AndroidManifest.xml index f07d992726..539a672e97 100644 --- a/vector/src/main/AndroidManifest.xml +++ b/vector/src/main/AndroidManifest.xml @@ -144,8 +144,7 @@ - - + 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..c9c07a9419 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,15 @@ 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 org.matrix.android.sdk.api.session.permalinks.PermalinkService import timber.log.Timber +import java.util.concurrent.TimeUnit import javax.inject.Inject /** @@ -37,6 +42,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) @@ -62,9 +68,45 @@ class LinkHandlerActivity : VectorBaseActivity() { 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 (!sessionHolder.hasActiveSession()) { + startLoginActivity(uri) + finish() + } else { + convertUrlToPermalink(uri.toString())?.let { permalink -> + startPermalinkHandler(permalink) + } ?: run { + // Other link are not yet handled, but should not comes here (manifest configuration error?) + Timber.w("Unable to handle this uir: $uri") + finish() + } + } + } + } + + 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.permalink_malformed) + } + finish() + } + .disposeOnDestroy() + } + + /** + * Converts domain urls to matrix.to urls + * @param url full url like https://app.element.io/#/room/#dummy_room:matrix.org + * @return matrix.to url like https://matrix.to/#/#dummy_room:matrix.org + */ + private fun convertUrlToPermalink(url: String): String? { + return when { + url.startsWith(ROOM_BASE_URL) -> url.replace(ROOM_BASE_URL, PermalinkService.MATRIX_TO_URL_BASE) + url.startsWith(USER_BASE_URL) -> url.replace(USER_BASE_URL, PermalinkService.MATRIX_TO_URL_BASE) + url.startsWith(GROUP_BASE_URL) -> url.replace(GROUP_BASE_URL, PermalinkService.MATRIX_TO_URL_BASE) + else -> null } } @@ -114,5 +156,8 @@ class LinkHandlerActivity : VectorBaseActivity() { companion object { private const val PATH_CONFIG = "/config/config" + private const val ROOM_BASE_URL = "https://app.element.io/#/room/" + private const val USER_BASE_URL = "https://app.element.io/#/user/" + private const val GROUP_BASE_URL = "https://app.element.io/#/group/" } } From f186a00515eb7d847ea9e586b81fbef55b855076 Mon Sep 17 00:00:00 2001 From: Onuray Sahin Date: Fri, 4 Sep 2020 14:20:03 +0300 Subject: [PATCH 2/8] Support legacy riot.im url. --- .../app/features/link/LinkHandlerActivity.kt | 69 ++++++++++--------- 1 file changed, 35 insertions(+), 34 deletions(-) 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 c9c07a9419..25ebf85b1c 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 @@ -30,7 +30,6 @@ 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 org.matrix.android.sdk.api.session.permalinks.PermalinkService import timber.log.Timber import java.util.concurrent.TimeUnit import javax.inject.Inject @@ -61,28 +60,43 @@ class LinkHandlerActivity : VectorBaseActivity() { } if (uri.path == PATH_CONFIG) { - if (sessionHolder.hasActiveSession()) { - displayAlreadyLoginPopup(uri) - } else { - // user is not yet logged in, this is the nominal case - startLoginActivity(uri) - } + handleConfigUrl(uri) + } else if (SUPPORTED_HOSTS.contains(uri.host)) { + handleSupportedHostUrl(uri) + } + } + + private fun handleConfigUrl(uri: Uri) { + if (sessionHolder.hasActiveSession()) { + displayAlreadyLoginPopup(uri) } else { - if (!sessionHolder.hasActiveSession()) { - startLoginActivity(uri) + // 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() - } else { - convertUrlToPermalink(uri.toString())?.let { permalink -> - startPermalinkHandler(permalink) - } ?: run { - // Other link are not yet handled, but should not comes here (manifest configuration error?) - Timber.w("Unable to handle this uir: $uri") - finish() - } } } } + private fun convertUriToPermalink(uri: Uri): String? { + val path = SUPPORTED_PATHS.find { it in uri.toString() } ?: return null + return uri + .toString() + .replace(uri.host + path, "$MATRIX_TO_HOST/#") + } + private fun startPermalinkHandler(permalink: String) { permalinkHandler.launch(this, permalink, buildTask = true) .delay(500, TimeUnit.MILLISECONDS) @@ -96,20 +110,6 @@ class LinkHandlerActivity : VectorBaseActivity() { .disposeOnDestroy() } - /** - * Converts domain urls to matrix.to urls - * @param url full url like https://app.element.io/#/room/#dummy_room:matrix.org - * @return matrix.to url like https://matrix.to/#/#dummy_room:matrix.org - */ - private fun convertUrlToPermalink(url: String): String? { - return when { - url.startsWith(ROOM_BASE_URL) -> url.replace(ROOM_BASE_URL, PermalinkService.MATRIX_TO_URL_BASE) - url.startsWith(USER_BASE_URL) -> url.replace(USER_BASE_URL, PermalinkService.MATRIX_TO_URL_BASE) - url.startsWith(GROUP_BASE_URL) -> url.replace(GROUP_BASE_URL, PermalinkService.MATRIX_TO_URL_BASE) - else -> null - } - } - /** * Start the login screen with identity server and home server pre-filled */ @@ -156,8 +156,9 @@ class LinkHandlerActivity : VectorBaseActivity() { companion object { private const val PATH_CONFIG = "/config/config" - private const val ROOM_BASE_URL = "https://app.element.io/#/room/" - private const val USER_BASE_URL = "https://app.element.io/#/user/" - private const val GROUP_BASE_URL = "https://app.element.io/#/group/" + + private val SUPPORTED_HOSTS = arrayOf("app.element.io", "riot.im") + private val SUPPORTED_PATHS = arrayOf("/#/room", "/#/user", "/#/group") + private const val MATRIX_TO_HOST = "matrix.to" } } From 4d7cd7319b45f6c952dfbff33ba247df4c4ad035 Mon Sep 17 00:00:00 2001 From: Onuray Sahin Date: Mon, 7 Sep 2020 12:19:34 +0300 Subject: [PATCH 3/8] Handle new mobile config url. --- tools/tests/test_configuration_link.sh | 2 +- vector/src/main/AndroidManifest.xml | 1 + .../java/im/vector/app/features/link/LinkHandlerActivity.kt | 4 ++-- .../src/main/java/im/vector/app/features/login/LoginConfig.kt | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) 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 539a672e97..2f1df686a6 100644 --- a/vector/src/main/AndroidManifest.xml +++ b/vector/src/main/AndroidManifest.xml @@ -145,6 +145,7 @@ + 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 25ebf85b1c..c8ef63c40c 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 @@ -59,7 +59,7 @@ class LinkHandlerActivity : VectorBaseActivity() { return } - if (uri.path == PATH_CONFIG) { + if (uri.getQueryParameter(CONFIG_PATH_HS_PARAMETER) != null) { handleConfigUrl(uri) } else if (SUPPORTED_HOSTS.contains(uri.host)) { handleSupportedHostUrl(uri) @@ -155,7 +155,7 @@ 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") private val SUPPORTED_PATHS = arrayOf("/#/room", "/#/user", "/#/group") 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. */ From fc51097ed8bec803a3e843b756280ced16e583a4 Mon Sep 17 00:00:00 2001 From: Onuray Sahin Date: Mon, 7 Sep 2020 17:17:58 +0300 Subject: [PATCH 4/8] develop and staging subdomains are added. --- vector/src/main/AndroidManifest.xml | 2 ++ .../java/im/vector/app/features/link/LinkHandlerActivity.kt | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/vector/src/main/AndroidManifest.xml b/vector/src/main/AndroidManifest.xml index 2f1df686a6..6865da3470 100644 --- a/vector/src/main/AndroidManifest.xml +++ b/vector/src/main/AndroidManifest.xml @@ -146,6 +146,8 @@ + + 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 c8ef63c40c..02e72fd332 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 @@ -157,7 +157,7 @@ class LinkHandlerActivity : VectorBaseActivity() { companion object { private const val CONFIG_PATH_HS_PARAMETER = "hs_url" - private val SUPPORTED_HOSTS = arrayOf("app.element.io", "riot.im") + 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" } From cf3fecd4250fc688e8834bc3be8078ecc6a62746 Mon Sep 17 00:00:00 2001 From: Onuray Sahin Date: Mon, 7 Sep 2020 17:48:12 +0300 Subject: [PATCH 5/8] Changelog added. Fixes #1795 --- CHANGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.md b/CHANGES.md index 1ffb6bcad0..ae9e428795 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -17,6 +17,7 @@ Bugfix 🐛: - Change user or room avatar: when selecting Gallery, I'm not proposed to crop the selected image (#1590) - 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) Translations 🗣: - From 3367ed676564a33aad86eb8d4323a1fd879beaac Mon Sep 17 00:00:00 2001 From: Onuray Sahin Date: Mon, 7 Sep 2020 20:02:06 +0300 Subject: [PATCH 6/8] Fix support of riot.im/develop urls. --- .../java/im/vector/app/features/link/LinkHandlerActivity.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) 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 02e72fd332..d97ca3ebc1 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 @@ -92,9 +92,11 @@ class LinkHandlerActivity : VectorBaseActivity() { 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 uri .toString() - .replace(uri.host + path, "$MATRIX_TO_HOST/#") + .replace(uri.toString().substring(0, uri.toString().indexOf(path) + path.length), "https://$MATRIX_TO_HOST/#") } private fun startPermalinkHandler(permalink: String) { From c41c91b0e71c16906f3f517b61401ef89404f289 Mon Sep 17 00:00:00 2001 From: Onuray Sahin Date: Mon, 7 Sep 2020 20:53:11 +0300 Subject: [PATCH 7/8] Update changelog. --- CHANGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.md b/CHANGES.md index acf41b40e6..8aa6e40756 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -23,6 +23,7 @@ Bugfix 🐛: - 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 From e65558958d37e68c4a163bbe426e864a778dbd9b Mon Sep 17 00:00:00 2001 From: Onuray Sahin Date: Tue, 8 Sep 2020 10:45:00 +0300 Subject: [PATCH 8/8] Code review refactoring. --- .../java/im/vector/app/features/link/LinkHandlerActivity.kt | 6 ++---- vector/src/main/res/values/strings.xml | 3 +++ 2 files changed, 5 insertions(+), 4 deletions(-) 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 d97ca3ebc1..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 @@ -94,9 +94,7 @@ class LinkHandlerActivity : VectorBaseActivity() { 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 uri - .toString() - .replace(uri.toString().substring(0, uri.toString().indexOf(path) + path.length), "https://$MATRIX_TO_HOST/#") + return "https://$MATRIX_TO_HOST/#" + uri.toString().substringAfter(path) } private fun startPermalinkHandler(permalink: String) { @@ -105,7 +103,7 @@ class LinkHandlerActivity : VectorBaseActivity() { .observeOn(AndroidSchedulers.mainThread()) .subscribe { isHandled -> if (!isHandled) { - toast(R.string.permalink_malformed) + toast(R.string.universal_link_malformed) } finish() } diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml index 06e9530ad5..d02a28bb19 100644 --- a/vector/src/main/res/values/strings.xml +++ b/vector/src/main/res/values/strings.xml @@ -2560,4 +2560,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