diff --git a/CHANGES.md b/CHANGES.md
index 1038417058e..595baee9e11 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -1,3 +1,16 @@
+Changes in Element v1.6.50 (2026-02-04)
+=======================================
+
+Other changes
+-------------
+ - Update the default bug reporting URL. ([#9097](https://github.com/element-hq/element-android/issues/9097))
+ - Update OAuth-awareness to support the stable version of MSC3824. ([#9102](https://github.com/element-hq/element-android/issues/9102))
+ - Update realm plugin to 10.19.0 ([#9111](https://github.com/element-hq/element-android/issues/9116))
+ - Bump org.matrix.rustcomponents:crypto-android from 26.1.22 to 26.1.28 ([#9114](https://github.com/element-hq/element-android/issues/9114))
+ - Update sentry to version 8.31.0 ([#9115](https://github.com/element-hq/element-android/issues/9115))
+ - Update Maplibre dependency to version 11.6.1 ([#9116](https://github.com/element-hq/element-android/issues/9116))
+ - Remove flipper from the codebase. ([#9117](https://github.com/element-hq/element-android/issues/9117))
+
Changes in Element v1.6.48 (2025-10-15)
=======================================
diff --git a/dependencies.gradle b/dependencies.gradle
index d3e839a118d..784128722bf 100644
--- a/dependencies.gradle
+++ b/dependencies.gradle
@@ -19,14 +19,13 @@ def markwon = "4.6.2"
def moshi = "1.15.1"
def lifecycle = "2.8.3"
def flowBinding = "1.2.0"
-def flipper = "0.259.0"
def epoxy = "5.0.0"
def mavericks = "3.0.9"
def glide = "4.16.0"
def bigImageViewer = "1.8.1"
def jjwt = "0.11.5"
def vanniktechEmoji = "0.16.0"
-def sentry = "6.18.1"
+def sentry = "8.31.0"
def fragment = "1.8.6"
// Testing
def mockk = "1.13.11"
@@ -95,10 +94,6 @@ ext.libs = [
'hiltAndroidTesting' : "com.google.dagger:hilt-android-testing:$dagger",
'hiltCompiler' : "com.google.dagger:hilt-compiler:$dagger"
],
- flipper : [
- 'flipper' : "com.facebook.flipper:flipper:$flipper",
- 'flipperNetworkPlugin' : "com.facebook.flipper:flipper-network-plugin:$flipper",
- ],
element : [
'opusencoder' : "io.element.android:opusencoder:1.1.0",
'wysiwyg' : "io.element.android:wysiwyg:2.38.2"
@@ -132,8 +127,8 @@ ext.libs = [
'mavericksTesting' : "com.airbnb.android:mavericks-testing:$mavericks"
],
maplibre : [
- 'androidSdk' : "org.maplibre.gl:android-sdk:10.0.2",
- 'pluginAnnotation' : "org.maplibre.gl:android-plugin-annotation-v9:1.0.0"
+ 'androidSdk' : "org.maplibre.gl:android-sdk:11.6.1",
+ 'pluginAnnotation' : "org.maplibre.gl:android-plugin-annotation-v9:3.0.2"
],
mockk : [
'mockk' : "io.mockk:mockk:$mockk",
diff --git a/dependencies_groups.gradle b/dependencies_groups.gradle
index 282fa353e4f..59cc63896f6 100644
--- a/dependencies_groups.gradle
+++ b/dependencies_groups.gradle
@@ -69,7 +69,6 @@ ext.groups = [
'com.dropbox.core',
'com.soywiz.korlibs.korte',
'com.facebook.fbjni',
- 'com.facebook.flipper',
'com.facebook.fresco',
'com.facebook.infer.annotation',
'com.facebook.react',
@@ -114,7 +113,6 @@ ext.groups = [
'com.intellij',
'com.jakewharton.android.repackaged',
'com.jakewharton.timber',
- 'com.kgurgul.flipper',
'com.linkedin.dexmaker',
'com.mapbox.mapboxsdk',
'com.nulab-inc',
diff --git a/docs/flipper.md b/docs/flipper.md
deleted file mode 100644
index 495425ce5f4..00000000000
--- a/docs/flipper.md
+++ /dev/null
@@ -1,58 +0,0 @@
-# Flipper
-
-
-
-* [Introduction](#introduction)
-* [Setup](#setup)
- * [Troubleshoot](#troubleshoot)
- * [No device found issue](#no-device-found-issue)
- * [Diagnostic Activity](#diagnostic-activity)
- * [Other](#other)
-* [Links](#links)
-
-
-
-## Introduction
-
-[Flipper](https://fbflipper.com) is a powerful tool from Meta, which allow to inspect the running application details and states from your computer.
-
-Flipper is configured in the Element Android project to let the developers be able to:
-- inspect all the Realm databases content;
-- do layout inspection;
-- see the crash logs;
-- see the logcat;
-- see all the network requests;
-- see all the SharedPreferences;
-- take screenshots and record videos of the device;
-- and more!
-
-## Setup
-
-- Install Flipper on your computer. Follow instructions here: https://fbflipper.com/docs/getting-started/index/
-- Run the debug version of Element on an emulator or on a real device.
-
-### Troubleshoot
-
-#### No device found issue
-
-The configuration of the Flipper application has to be updated. The issue has been asked and answered here: https://stackoverflow.com/questions/71744103/android-emulator-unable-to-connect-to-flipper/72608113#72608113
-
-#### Diagnostic Activity
-
-Flipper comes with a Diagnostic Activity that you can start from command line using:
-
-```shell
-adb shell am start -n im.vector.app.debug/com.facebook.flipper.android.diagnostics.FlipperDiagnosticActivity
-```
-
-It provides some log which can help to figure out what's going on client side.
-
-#### Other
-
-https://fbflipper.com/docs/getting-started/troubleshooting/android/ may help.
-
-## Links
-
-- Official Flipper website: https://fbflipper.com
-- Realm Plugin for Flipper: https://github.com/kamgurgul/Flipper-Realm
-- Dedicated Matrix room: https://matrix.to/#/#unifiedpush:matrix.org
diff --git a/fastlane/metadata/android/en-US/changelogs/40106500.txt b/fastlane/metadata/android/en-US/changelogs/40106500.txt
new file mode 100644
index 00000000000..73cd3e2bd9c
--- /dev/null
+++ b/fastlane/metadata/android/en-US/changelogs/40106500.txt
@@ -0,0 +1,2 @@
+Main changes in this version: bug fixes and improvements.
+Full changelog: https://github.com/element-hq/element-android/releases
diff --git a/matrix-sdk-android/build.gradle b/matrix-sdk-android/build.gradle
index 0b7b2015ffd..f1e3f30e978 100644
--- a/matrix-sdk-android/build.gradle
+++ b/matrix-sdk-android/build.gradle
@@ -17,7 +17,7 @@ buildscript {
}
}
dependencies {
- classpath "io.realm:realm-gradle-plugin:10.18.0"
+ classpath "io.realm:realm-gradle-plugin:10.19.0"
}
}
@@ -62,7 +62,7 @@ android {
// that the app's state is completely cleared between tests.
testInstrumentationRunnerArguments clearPackageData: 'true'
- buildConfigField "String", "SDK_VERSION", "\"1.6.48\""
+ buildConfigField "String", "SDK_VERSION", "\"1.6.50\""
buildConfigField "String", "GIT_SDK_REVISION", "\"${gitRevision()}\""
buildConfigField "String", "GIT_SDK_REVISION_UNIX_DATE", "\"${gitRevisionUnixDate()}\""
@@ -221,7 +221,7 @@ dependencies {
implementation libs.google.phonenumber
- implementation("org.matrix.rustcomponents:crypto-android:0.11.1")
+ implementation("org.matrix.rustcomponents:crypto-android:26.1.28")
// api project(":library:rustCrypto")
testImplementation libs.tests.junit
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/SSOAction.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/SSOAction.kt
index db2dd870d52..bd5dfb662cc 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/SSOAction.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/SSOAction.kt
@@ -19,7 +19,7 @@ package org.matrix.android.sdk.api.auth
/**
* See https://github.com/matrix-org/matrix-spec-proposals/pull/3824
*/
-enum class SSOAction {
- LOGIN,
- REGISTER;
+enum class SSOAction(val value: String) {
+ LOGIN("login"),
+ REGISTER("register");
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/data/AuthMetadata.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/data/AuthMetadata.kt
new file mode 100644
index 00000000000..62a2382842a
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/data/AuthMetadata.kt
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2026 The Matrix.org Foundation C.I.C.
+ *
+ * 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 org.matrix.android.sdk.api.auth.data
+
+import com.squareup.moshi.Json
+import com.squareup.moshi.JsonClass
+
+/**
+ * This is a subset of the server metadata discovery for the OAuth 2.0 API
+ * https://spec.matrix.org/v1.16/client-server-api/#get_matrixclientv1auth_metadata
+ *
+ * Includes the values from MSC4191: https://github.com/matrix-org/matrix-spec-proposals/pull/4191
+ *
+ *
+ * {
+ * "issuer": "https://id.server.org",
+ * "account_management_uri": "https://id.server.org/my-account",
+ * "account_management_actions_supported": ["org.matrix.profile", "org.matrix.devices_list"],
+ * }
+ *
+ * .
+ */
+
+@JsonClass(generateAdapter = true)
+data class AuthMetadata(
+ @Json(name = "issuer")
+ val issuer: String,
+
+ @Json(name = "account_management_uri")
+ val accountManagementUri: String?,
+
+ @Json(name = "account_management_actions_supported")
+ val accountManagementActionsSupported: List?,
+)
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/homeserver/HomeServerCapabilities.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/homeserver/HomeServerCapabilities.kt
index 101947f9d9b..5404eecc496 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/homeserver/HomeServerCapabilities.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/homeserver/HomeServerCapabilities.kt
@@ -82,12 +82,17 @@ data class HomeServerCapabilities(
var canRedactRelatedEvents: Boolean = false,
/**
- * External account management url for use with MSC3824 delegated OIDC, provided in Wellknown.
+ * External account management url for use with OAuth API, provided by MSC4191 /auth_metadata discovery or in unstable Wellknown.
*/
val externalAccountManagementUrl: String? = null,
/**
- * Authentication issuer for use with MSC3824 delegated OIDC, provided in Wellknown.
+ * External account management supported actions for use with OAuth API, provided by MSC4191 /auth_metadata discovery.
+ */
+ val externalAccountManagementSupportedActions: List? = null,
+
+ /**
+ * Authentication issuer for use with MSC3824 delegated OIDC, provided by /auth_metadata discovery or in unstable Wellknown.
*/
val authenticationIssuer: String? = null,
@@ -162,4 +167,26 @@ data class HomeServerCapabilities(
const val ROOM_CAP_KNOCK = "knock"
const val ROOM_CAP_RESTRICTED = "restricted"
}
+
+ fun getLogoutDeviceURL(deviceId: String): String? {
+ if (externalAccountManagementUrl == null) {
+ return null
+ }
+
+ // default to the stable value:
+ var action = "org.matrix.device_delete"
+ externalAccountManagementSupportedActions?.also { actions ->
+ if (actions.contains("org.matrix.device_delete")) {
+ // server supports stable version so use it
+ } else if (actions.contains("org.matrix.session_end")) {
+ // earlier version of MSC4191:
+ action = "org.matrix.session_end"
+ } else if (actions.contains("session_end")) {
+ // previous unspecified version
+ action = "session_end"
+ }
+ }
+
+ return externalAccountManagementUrl.removeSuffix("/") + "?action=${action}&device_id=${deviceId}"
+ }
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/DefaultAuthenticationService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/DefaultAuthenticationService.kt
index e852c61185b..6b9a06a6046 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/DefaultAuthenticationService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/DefaultAuthenticationService.kt
@@ -106,7 +106,11 @@ internal class DefaultAuthenticationService @Inject constructor(
}
// unstable MSC3824 action param
- appendParamToUrl("org.matrix.msc3824.action", action.toString())
+ // This can be removed once servers have been updated to support the stable one.
+ appendParamToUrl("org.matrix.msc3824.action", action.value)
+
+ // stable param:
+ appendParamToUrl("action", action.value)
}
}
@@ -297,8 +301,8 @@ internal class DefaultAuthenticationService @Inject constructor(
authAPI.getLoginFlows()
}
- // If an m.login.sso flow is present that is flagged as being for MSC3824 OIDC compatibility then we only return that flow
- val oidcCompatibilityFlow = loginFlowResponse.flows.orEmpty().firstOrNull { it.type == "m.login.sso" && it.delegatedOidcCompatibility == true }
+ // If an m.login.sso flow is present that is flagged as being for MSC3824 OAuth compatibility then we only return that flow
+ val oidcCompatibilityFlow = loginFlowResponse.flows.orEmpty().firstOrNull { it.type == "m.login.sso" && it.delegatedOidcCompatibility }
val flows = if (oidcCompatibilityFlow != null) listOf(oidcCompatibilityFlow) else loginFlowResponse.flows
val supportsGetLoginTokenFlow = loginFlowResponse.flows.orEmpty().firstOrNull { it.type == "m.login.token" && it.getLoginToken == true } != null
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/data/LoginFlowResponse.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/data/LoginFlowResponse.kt
index 2e52740ed48..6d8d02fabb2 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/data/LoginFlowResponse.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/data/LoginFlowResponse.kt
@@ -19,6 +19,7 @@ package org.matrix.android.sdk.internal.auth.data
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import org.matrix.android.sdk.api.auth.data.SsoIdentityProvider
+import org.matrix.android.sdk.api.extensions.orFalse
@JsonClass(generateAdapter = true)
internal data class LoginFlowResponse(
@@ -46,12 +47,20 @@ internal data class LoginFlow(
val ssoIdentityProvider: List? = null,
/**
- * Whether this login flow is preferred for OIDC-aware clients.
+ * Whether this login flow is preferred for OAuth 2.0-aware clients like we are.
*
* See [MSC3824](https://github.com/matrix-org/matrix-spec-proposals/pull/3824)
*/
+ @Json(name = "oauth_aware_preferred")
+ val oauthAwarePreferred: Boolean? = null,
+
+ /**
+ * Unstable name from MSC3824.
+ *
+ */
+ @Deprecated("Use oauthAwarePreferred instead")
@Json(name = "org.matrix.msc3824.delegated_oidc_compatibility")
- val delegatedOidcCompatibility: Boolean? = null,
+ val unstableDelegatedOidcCompatibility: Boolean? = null,
/**
* Whether a login flow of type m.login.token could accept a token issued using /login/get_token.
@@ -60,4 +69,7 @@ internal data class LoginFlow(
*/
@Json(name = "get_login_token")
val getLoginToken: Boolean? = null
-)
+) {
+ @Suppress("DEPRECATION") val delegatedOidcCompatibility: Boolean
+ get() = this.oauthAwarePreferred.orFalse() || this.unstableDelegatedOidcCompatibility.orFalse()
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt
index bbc4c3bb399..2b68e228b9c 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt
@@ -287,7 +287,14 @@ internal class OlmMachine @Inject constructor(
val events = adapter.toJson(toDevice ?: ToDeviceSyncResponse())
// field pass in the list of unused fallback keys here
- val receiveSyncChanges = inner.receiveSyncChanges(events, devices, counts, deviceUnusedFallbackKeyTypes, nextBatch ?: "")
+ val receiveSyncChanges = inner.receiveSyncChanges(
+ events = events,
+ deviceChanges = devices,
+ keyCounts = counts,
+ unusedFallbackKeys = deviceUnusedFallbackKeyTypes,
+ nextBatchToken = nextBatch ?: "",
+ decryptionSettings = DecryptionSettings(TrustRequirement.UNTRUSTED),
+ )
val outAdapter = moshi.adapter(Event::class.java)
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmSessionStoreMigration.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmSessionStoreMigration.kt
index cee831f37ac..ec946cb8800 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmSessionStoreMigration.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmSessionStoreMigration.kt
@@ -73,6 +73,7 @@ import org.matrix.android.sdk.internal.database.migration.MigrateSessionTo053
import org.matrix.android.sdk.internal.database.migration.MigrateSessionTo054
import org.matrix.android.sdk.internal.database.migration.MigrateSessionTo055
import org.matrix.android.sdk.internal.database.migration.MigrateSessionTo056
+import org.matrix.android.sdk.internal.database.migration.MigrateSessionTo057
import org.matrix.android.sdk.internal.util.Normalizer
import org.matrix.android.sdk.internal.util.database.MatrixRealmMigration
import javax.inject.Inject
@@ -81,7 +82,7 @@ internal class RealmSessionStoreMigration @Inject constructor(
private val normalizer: Normalizer
) : MatrixRealmMigration(
dbName = "Session",
- schemaVersion = 56L,
+ schemaVersion = 57L,
) {
/**
* Forces all RealmSessionStoreMigration instances to be equal.
@@ -147,5 +148,6 @@ internal class RealmSessionStoreMigration @Inject constructor(
if (oldVersion < 54) MigrateSessionTo054(realm).perform()
if (oldVersion < 55) MigrateSessionTo055(realm).perform()
if (oldVersion < 56) MigrateSessionTo056(realm).perform()
+ if (oldVersion < 57) MigrateSessionTo057(realm).perform()
}
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/mapper/HomeServerCapabilitiesMapper.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/mapper/HomeServerCapabilitiesMapper.kt
index 8cdabaf1504..1c6ba850d74 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/mapper/HomeServerCapabilitiesMapper.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/mapper/HomeServerCapabilitiesMapper.kt
@@ -49,6 +49,7 @@ internal object HomeServerCapabilitiesMapper {
canRemotelyTogglePushNotificationsOfDevices = entity.canRemotelyTogglePushNotificationsOfDevices,
canRedactRelatedEvents = entity.canRedactEventWithRelations,
externalAccountManagementUrl = entity.externalAccountManagementUrl,
+ externalAccountManagementSupportedActions = entity.externalAccountManagementSupportedActions?.split(","),
authenticationIssuer = entity.authenticationIssuer,
disableNetworkConstraint = entity.disableNetworkConstraint,
canUseAuthenticatedMedia = entity.canUseAuthenticatedMedia,
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo057.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo057.kt
new file mode 100644
index 00000000000..1739b2fe711
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo057.kt
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2026 The Matrix.org Foundation C.I.C.
+ *
+ * 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 org.matrix.android.sdk.internal.database.migration
+
+import io.realm.DynamicRealm
+import org.matrix.android.sdk.internal.database.model.HomeServerCapabilitiesEntityFields
+import org.matrix.android.sdk.internal.extensions.forceRefreshOfHomeServerCapabilities
+import org.matrix.android.sdk.internal.util.database.RealmMigrator
+
+internal class MigrateSessionTo057(realm: DynamicRealm) : RealmMigrator(realm, 57) {
+ override fun doMigrate(realm: DynamicRealm) {
+ realm.schema.get("HomeServerCapabilitiesEntity")
+ ?.addField(HomeServerCapabilitiesEntityFields.EXTERNAL_ACCOUNT_MANAGEMENT_SUPPORTED_ACTIONS, String::class.java)
+ ?.forceRefreshOfHomeServerCapabilities()
+ }
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/HomeServerCapabilitiesEntity.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/HomeServerCapabilitiesEntity.kt
index 0096071d547..d77d9025953 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/HomeServerCapabilitiesEntity.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/HomeServerCapabilitiesEntity.kt
@@ -36,6 +36,7 @@ internal open class HomeServerCapabilitiesEntity(
var canRemotelyTogglePushNotificationsOfDevices: Boolean = false,
var canRedactEventWithRelations: Boolean = false,
var externalAccountManagementUrl: String? = null,
+ var externalAccountManagementSupportedActions: String? = null,
var authenticationIssuer: String? = null,
var disableNetworkConstraint: Boolean? = null,
var canUseAuthenticatedMedia: Boolean = false,
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/homeserver/AuthMetadataAPI.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/homeserver/AuthMetadataAPI.kt
new file mode 100644
index 00000000000..cf6cab289dc
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/homeserver/AuthMetadataAPI.kt
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2026 The Matrix.org Foundation C.I.C.
+ *
+ * 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 org.matrix.android.sdk.internal.session.homeserver
+
+import org.matrix.android.sdk.api.auth.data.AuthMetadata
+import org.matrix.android.sdk.internal.network.NetworkConstants
+import retrofit2.http.GET
+
+internal interface AuthMetadataAPI {
+ /**
+ * Request the homeserver OAuth 2.0 auth metadata.
+ */
+ @GET(NetworkConstants.URI_API_PREFIX_PATH_V1 + "auth_metadata")
+ suspend fun getAuthMetadata(): AuthMetadata
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/homeserver/GetHomeServerCapabilitiesTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/homeserver/GetHomeServerCapabilitiesTask.kt
index 5314237c3c2..31d71286c91 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/homeserver/GetHomeServerCapabilitiesTask.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/homeserver/GetHomeServerCapabilitiesTask.kt
@@ -18,6 +18,7 @@ package org.matrix.android.sdk.internal.session.homeserver
import com.zhuinden.monarchy.Monarchy
import org.matrix.android.sdk.api.MatrixPatterns.getServerName
+import org.matrix.android.sdk.api.auth.data.AuthMetadata
import org.matrix.android.sdk.api.auth.data.HomeServerConnectionConfig
import org.matrix.android.sdk.api.auth.wellknown.WellknownResult
import org.matrix.android.sdk.api.extensions.orFalse
@@ -66,7 +67,8 @@ internal class DefaultGetHomeServerCapabilitiesTask @Inject constructor(
private val configExtractor: IntegrationManagerConfigExtractor,
private val homeServerConnectionConfig: HomeServerConnectionConfig,
@UserId
- private val userId: String
+ private val userId: String,
+ private val authMetadataAPI: AuthMetadataAPI,
) : GetHomeServerCapabilitiesTask {
override suspend fun execute(params: GetHomeServerCapabilitiesTask.Params) {
@@ -104,6 +106,12 @@ internal class DefaultGetHomeServerCapabilitiesTask @Inject constructor(
}
}.getOrNull()
+ val authMetadata = runCatching {
+ executeRequest(globalErrorReceiver = null) {
+ authMetadataAPI.getAuthMetadata()
+ }
+ }.getOrNull()
+
// Domain may include a port (eg, matrix.org:8080)
// Per https://spec.matrix.org/latest/client-server-api/#well-known-uri we should extract the hostname from the server name
// So we take everything before the last : as the domain for the well-known task.
@@ -117,14 +125,15 @@ internal class DefaultGetHomeServerCapabilitiesTask @Inject constructor(
)
}.getOrNull()
- insertInDb(capabilities, mediaConfig, versions, wellknownResult)
+ insertInDb(capabilities, mediaConfig, versions, wellknownResult, authMetadata)
}
private suspend fun insertInDb(
getCapabilitiesResult: GetCapabilitiesResult?,
getMediaConfigResult: GetMediaConfigResult?,
getVersionResult: Versions?,
- getWellknownResult: WellknownResult?
+ getWellknownResult: WellknownResult?,
+ authMetadata: AuthMetadata?,
) {
monarchy.awaitTransaction { realm ->
val homeServerCapabilitiesEntity = HomeServerCapabilitiesEntity.getOrCreate(realm)
@@ -174,11 +183,19 @@ internal class DefaultGetHomeServerCapabilitiesTask @Inject constructor(
Timber.v("Extracted integration config : $config")
realm.insertOrUpdate(config)
}
+ // Getting the OAuth 2.0 metadata from well-known was in unstable MSC:
homeServerCapabilitiesEntity.authenticationIssuer = getWellknownResult.wellKnown.unstableDelegatedAuthConfig?.issuer
homeServerCapabilitiesEntity.externalAccountManagementUrl = getWellknownResult.wellKnown.unstableDelegatedAuthConfig?.accountManagementUrl
homeServerCapabilitiesEntity.disableNetworkConstraint = getWellknownResult.wellKnown.disableNetworkConstraint
}
+ // If the server returns OAuth 2.0 metadata then prefer that over the well-known values:
+ if (authMetadata != null) {
+ homeServerCapabilitiesEntity.authenticationIssuer = authMetadata.issuer
+ homeServerCapabilitiesEntity.externalAccountManagementUrl = authMetadata.accountManagementUri
+ homeServerCapabilitiesEntity.externalAccountManagementSupportedActions = authMetadata.accountManagementActionsSupported?.joinToString(",")
+ }
+
homeServerCapabilitiesEntity.canLoginWithQrCode = canLoginWithQrCode(getCapabilitiesResult, getVersionResult)
homeServerCapabilitiesEntity.lastUpdatedTimestamp = Date().time
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/homeserver/HomeServerCapabilitiesModule.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/homeserver/HomeServerCapabilitiesModule.kt
index 2a1573dd98f..88988addcea 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/homeserver/HomeServerCapabilitiesModule.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/homeserver/HomeServerCapabilitiesModule.kt
@@ -34,6 +34,13 @@ internal abstract class HomeServerCapabilitiesModule {
fun providesCapabilitiesAPI(retrofit: Retrofit): CapabilitiesAPI {
return retrofit.create(CapabilitiesAPI::class.java)
}
+
+ @Provides
+ @JvmStatic
+ @SessionScope
+ fun providesAuthMetadataAPI(retrofit: Retrofit): AuthMetadataAPI {
+ return retrofit.create(AuthMetadataAPI::class.java)
+ }
}
@Binds
diff --git a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/api/session/homeserver/HomeServerCapabilitiesTest.kt b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/api/session/homeserver/HomeServerCapabilitiesTest.kt
new file mode 100644
index 00000000000..75a828fccec
--- /dev/null
+++ b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/api/session/homeserver/HomeServerCapabilitiesTest.kt
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2026 The Matrix.org Foundation C.I.C.
+ *
+ * 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 org.matrix.android.sdk.api.session.homeserver
+
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertNull
+import org.junit.Test
+
+class HomeServerCapabilitiesTest {
+
+ private val deviceId = "TEST_DEVICE_ID"
+
+ @Test
+ fun `given externalAccountManagementUrl is null, when getLogoutDeviceURL, then return null`() {
+ val capabilities = HomeServerCapabilities(
+ externalAccountManagementUrl = null
+ )
+ assertNull(capabilities.getLogoutDeviceURL(deviceId))
+ }
+
+ @Test
+ fun `given supported actions is null, when getLogoutDeviceURL, then uses default stable action`() {
+ val capabilities = HomeServerCapabilities(
+ externalAccountManagementUrl = "https://example.com",
+ externalAccountManagementSupportedActions = null
+ )
+ val expectedUrl = "https://example.com?action=org.matrix.device_delete&device_id=$deviceId"
+ assertEquals(expectedUrl, capabilities.getLogoutDeviceURL(deviceId))
+ }
+
+ @Test
+ fun `given supported actions contains stable action, when getLogoutDeviceURL, then uses stable action`() {
+ val capabilities = HomeServerCapabilities(
+ externalAccountManagementUrl = "https://example.com",
+ externalAccountManagementSupportedActions = listOf("org.matrix.device_delete", "org.matrix.session_end", "session_end")
+ )
+ val expectedUrl = "https://example.com?action=org.matrix.device_delete&device_id=$deviceId"
+ assertEquals(expectedUrl, capabilities.getLogoutDeviceURL(deviceId))
+ }
+
+ @Test
+ fun `given supported actions contains unstable action, when getLogoutDeviceURL, then uses unstable action`() {
+ val capabilities = HomeServerCapabilities(
+ externalAccountManagementUrl = "https://example.com",
+ externalAccountManagementSupportedActions = listOf("org.matrix.session_end", "session_end")
+ )
+ val expectedUrl = "https://example.com?action=org.matrix.session_end&device_id=$deviceId"
+ assertEquals(expectedUrl, capabilities.getLogoutDeviceURL(deviceId))
+ }
+
+ @Test
+ fun `given supported actions contains legacy action, when getLogoutDeviceURL, then uses legacy action`() {
+ val capabilities = HomeServerCapabilities(
+ externalAccountManagementUrl = "https://example.com",
+ externalAccountManagementSupportedActions = listOf("session_end")
+ )
+ val expectedUrl = "https://example.com?action=session_end&device_id=$deviceId"
+ assertEquals(expectedUrl, capabilities.getLogoutDeviceURL(deviceId))
+ }
+
+ @Test
+ fun `given url with trailing slash, when getLogoutDeviceURL, then slash is removed`() {
+ val capabilities = HomeServerCapabilities(
+ externalAccountManagementUrl = "https://example.com/account/"
+ )
+ val expectedUrl = "https://example.com/account?action=org.matrix.device_delete&device_id=$deviceId"
+ assertEquals(expectedUrl, capabilities.getLogoutDeviceURL(deviceId))
+ }
+}
diff --git a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/homeserver/DefaultGetHomeServerCapabilitiesTaskTest.kt b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/homeserver/DefaultGetHomeServerCapabilitiesTaskTest.kt
new file mode 100644
index 00000000000..fd228578c7f
--- /dev/null
+++ b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/homeserver/DefaultGetHomeServerCapabilitiesTaskTest.kt
@@ -0,0 +1,165 @@
+/*
+ * Copyright 2026 The Matrix.org Foundation C.I.C.
+ *
+ * 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 org.matrix.android.sdk.internal.session.homeserver
+
+import io.mockk.coEvery
+import io.mockk.mockk
+import kotlinx.coroutines.test.runTest
+import org.amshove.kluent.shouldBeEqualTo
+import org.junit.Before
+import org.junit.Test
+import org.matrix.android.sdk.api.auth.data.AuthMetadata
+import org.matrix.android.sdk.api.auth.data.DelegatedAuthConfig
+import org.matrix.android.sdk.api.auth.data.HomeServerConnectionConfig
+import org.matrix.android.sdk.api.auth.data.WellKnown
+import org.matrix.android.sdk.api.auth.wellknown.WellknownResult
+import org.matrix.android.sdk.internal.database.model.HomeServerCapabilitiesEntity
+import org.matrix.android.sdk.internal.network.GlobalErrorReceiver
+import org.matrix.android.sdk.internal.session.integrationmanager.IntegrationManagerConfigExtractor
+import org.matrix.android.sdk.internal.session.media.AuthenticatedMediaAPI
+import org.matrix.android.sdk.internal.session.media.UnauthenticatedMediaAPI
+import org.matrix.android.sdk.internal.wellknown.GetWellknownTask
+import org.matrix.android.sdk.test.fakes.FakeMonarchy
+
+class DefaultGetHomeServerCapabilitiesTaskTest {
+
+ private val capabilitiesAPI: CapabilitiesAPI = mockk()
+ private val unauthenticatedMediaAPI: UnauthenticatedMediaAPI = mockk()
+ private val authenticatedMediaAPI: AuthenticatedMediaAPI = mockk()
+ private val monarchy = FakeMonarchy()
+ private val globalErrorReceiver: GlobalErrorReceiver = mockk(relaxed = true)
+ private val getWellknownTask: GetWellknownTask = mockk()
+ private val configExtractor: IntegrationManagerConfigExtractor = mockk()
+ private val homeServerConnectionConfig: HomeServerConnectionConfig = mockk()
+ private val authMetadataAPI: AuthMetadataAPI = mockk()
+
+ private val task = DefaultGetHomeServerCapabilitiesTask(
+ capabilitiesAPI,
+ unauthenticatedMediaAPI,
+ authenticatedMediaAPI,
+ monarchy.instance,
+ globalErrorReceiver,
+ getWellknownTask,
+ configExtractor,
+ homeServerConnectionConfig,
+ "userId",
+ authMetadataAPI
+ )
+
+ private val homeServerCapabilitiesEntity = HomeServerCapabilitiesEntity()
+
+ @Before
+ fun setUp() {
+ coEvery { configExtractor.extract(any()) } returns null
+ monarchy.givenWhereReturns(result = homeServerCapabilitiesEntity)
+ }
+
+ private val wellKnownWithoutDelegation = WellknownResult.Prompt(
+ homeServerUrl = "https://test",
+ identityServerUrl = null,
+ wellKnown = WellKnown(
+ homeServer = mockk(),
+ identityServer = mockk(),
+ unstableDelegatedAuthConfig = null,
+ )
+ )
+
+ private val wellKnownWithDelegationToTest1 = WellknownResult.Prompt(
+ homeServerUrl = "https://test",
+ identityServerUrl = null,
+ wellKnown = WellKnown(
+ homeServer = mockk(),
+ identityServer = mockk(),
+ unstableDelegatedAuthConfig = DelegatedAuthConfig(
+ issuer = "https://test1",
+ accountManagementUrl = "https://test1/account"
+ )
+ )
+ )
+
+ private val authMetadataForTest2 = AuthMetadata(
+ issuer = "https://test2",
+ accountManagementUri = "https://test2/account",
+ accountManagementActionsSupported = listOf("org.matrix.device_delete", "org.matrix.profile")
+ )
+
+ private val authMetadataForTest2WithoutAccountManagement = AuthMetadata(
+ issuer = "https://test2",
+ accountManagementUri = null,
+ accountManagementActionsSupported = null
+ )
+
+ @Test
+ fun `given no OAuth config, when execute, then fields are null`() = runTest {
+ // Given
+ coEvery { getWellknownTask.execute(any()) } throws Exception()
+ coEvery { authMetadataAPI.getAuthMetadata() } throws Exception()
+
+ // When
+ task.execute(GetHomeServerCapabilitiesTask.Params(forceRefresh = false))
+
+ // Then
+ homeServerCapabilitiesEntity.authenticationIssuer shouldBeEqualTo null
+ homeServerCapabilitiesEntity.externalAccountManagementUrl shouldBeEqualTo null
+ homeServerCapabilitiesEntity.externalAccountManagementSupportedActions shouldBeEqualTo null
+ }
+
+ @Test
+ fun `given well-known, when execute, populates fields`() = runTest {
+ // Given
+ coEvery { getWellknownTask.execute(any()) } returns wellKnownWithDelegationToTest1
+ coEvery { authMetadataAPI.getAuthMetadata() } throws Exception()
+
+ // When
+ task.execute(GetHomeServerCapabilitiesTask.Params(forceRefresh = false))
+
+ // Then
+ homeServerCapabilitiesEntity.authenticationIssuer shouldBeEqualTo "https://test1"
+ homeServerCapabilitiesEntity.externalAccountManagementUrl shouldBeEqualTo "https://test1/account"
+ homeServerCapabilitiesEntity.externalAccountManagementSupportedActions shouldBeEqualTo null
+ }
+
+ @Test
+ fun `given auth metadata, when execute, populates fields`() = runTest {
+ // Given
+ coEvery { getWellknownTask.execute(any()) } returns wellKnownWithoutDelegation
+ coEvery { authMetadataAPI.getAuthMetadata() } returns authMetadataForTest2
+
+ // When
+ task.execute(GetHomeServerCapabilitiesTask.Params(forceRefresh = false))
+
+ // Then
+ homeServerCapabilitiesEntity.authenticationIssuer shouldBeEqualTo "https://test2"
+ homeServerCapabilitiesEntity.externalAccountManagementUrl shouldBeEqualTo "https://test2/account"
+ homeServerCapabilitiesEntity.externalAccountManagementSupportedActions shouldBeEqualTo "org.matrix.device_delete,org.matrix.profile"
+ }
+
+ @Test
+ fun `given well-known and auth metadata, when execute, treats auth metadata as authoritative`() = runTest {
+ // Given
+ coEvery { getWellknownTask.execute(any()) } returns wellKnownWithDelegationToTest1
+ coEvery { authMetadataAPI.getAuthMetadata() } returns authMetadataForTest2WithoutAccountManagement
+
+ // When
+ task.execute(GetHomeServerCapabilitiesTask.Params(forceRefresh = false))
+
+ // Then
+ homeServerCapabilitiesEntity.authenticationIssuer shouldBeEqualTo "https://test2"
+ homeServerCapabilitiesEntity.externalAccountManagementUrl shouldBeEqualTo null
+ homeServerCapabilitiesEntity.externalAccountManagementSupportedActions shouldBeEqualTo null
+ }
+}
diff --git a/vector-app/build.gradle b/vector-app/build.gradle
index 911d5a3b94a..5f1c5f4469a 100644
--- a/vector-app/build.gradle
+++ b/vector-app/build.gradle
@@ -37,7 +37,7 @@ ext.versionMinor = 6
// Note: even values are reserved for regular release, odd values for hotfix release.
// When creating a hotfix, you should decrease the value, since the current value
// is the value for the next regular release.
-ext.versionPatch = 48
+ext.versionPatch = 50
static def getGitTimestamp() {
def cmd = 'git show -s --format=%ct'
@@ -392,16 +392,6 @@ dependencies {
implementation 'androidx.multidex:multidex:2.0.1'
implementation "androidx.sharetarget:sharetarget:1.2.0"
- // Flipper, debug builds only
- debugImplementation(libs.flipper.flipper) {
- exclude group: 'com.facebook.fbjni', module: 'fbjni'
- }
- debugImplementation(libs.flipper.flipperNetworkPlugin) {
- exclude group: 'com.facebook.fbjni', module: 'fbjni'
- }
- debugImplementation 'com.facebook.soloader:soloader:0.10.5'
- debugImplementation "com.kgurgul.flipper:flipper-realm-android:2.3.0"
-
gplayImplementation "com.google.android.gms:play-services-location:21.3.0"
// UnifiedPush gplay flavor only
gplayImplementation platform(libs.google.firebaseBom)
diff --git a/vector-app/src/debug/AndroidManifest.xml b/vector-app/src/debug/AndroidManifest.xml
index be2aadbeaf8..4f1d6817531 100644
--- a/vector-app/src/debug/AndroidManifest.xml
+++ b/vector-app/src/debug/AndroidManifest.xml
@@ -11,11 +11,6 @@
-
-
-
diff --git a/vector-app/src/debug/java/im/vector/app/features/debug/di/DebugModule.kt b/vector-app/src/debug/java/im/vector/app/features/debug/di/DebugModule.kt
index 6604545ca4c..b5af29f7e08 100644
--- a/vector-app/src/debug/java/im/vector/app/features/debug/di/DebugModule.kt
+++ b/vector-app/src/debug/java/im/vector/app/features/debug/di/DebugModule.kt
@@ -16,10 +16,8 @@ import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import im.vector.app.core.debug.DebugNavigator
import im.vector.app.core.debug.DebugReceiver
-import im.vector.app.core.debug.FlipperProxy
import im.vector.app.core.debug.LeakDetector
import im.vector.app.features.debug.DebugMenuActivity
-import im.vector.app.flipper.VectorFlipperProxy
import im.vector.app.leakcanary.LeakCanaryLeakDetector
import im.vector.app.receivers.VectorDebugReceiver
@@ -40,9 +38,6 @@ abstract class DebugModule {
@Binds
abstract fun bindsDebugReceiver(receiver: VectorDebugReceiver): DebugReceiver
- @Binds
- abstract fun bindsFlipperProxy(flipperProxy: VectorFlipperProxy): FlipperProxy
-
@Binds
abstract fun bindsLeakDetector(leakDetector: LeakCanaryLeakDetector): LeakDetector
}
diff --git a/vector-app/src/debug/java/im/vector/app/flipper/VectorFlipperProxy.kt b/vector-app/src/debug/java/im/vector/app/flipper/VectorFlipperProxy.kt
deleted file mode 100644
index fca6278d7d3..00000000000
--- a/vector-app/src/debug/java/im/vector/app/flipper/VectorFlipperProxy.kt
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * 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.
- */
-
-package im.vector.app.flipper
-
-import android.content.Context
-import android.os.Build
-import com.facebook.flipper.android.AndroidFlipperClient
-import com.facebook.flipper.android.utils.FlipperUtils
-import com.facebook.flipper.plugins.crashreporter.CrashReporterPlugin
-import com.facebook.flipper.plugins.databases.DatabasesFlipperPlugin
-import com.facebook.flipper.plugins.inspector.DescriptorMapping
-import com.facebook.flipper.plugins.inspector.InspectorFlipperPlugin
-import com.facebook.flipper.plugins.network.FlipperOkhttpInterceptor
-import com.facebook.flipper.plugins.network.NetworkFlipperPlugin
-import com.facebook.flipper.plugins.sharedpreferences.SharedPreferencesFlipperPlugin
-import com.facebook.soloader.SoLoader
-import com.kgurgul.flipper.RealmDatabaseDriver
-import com.kgurgul.flipper.RealmDatabaseProvider
-import im.vector.app.core.debug.FlipperProxy
-import io.realm.RealmConfiguration
-import okhttp3.Interceptor
-import org.matrix.android.sdk.api.Matrix
-import javax.inject.Inject
-import javax.inject.Singleton
-
-@Singleton
-class VectorFlipperProxy @Inject constructor(
- private val context: Context,
-) : FlipperProxy {
- private val networkFlipperPlugin = NetworkFlipperPlugin()
-
- private val isEnabled: Boolean
- get() {
- // https://github.com/facebook/flipper/issues/3572
- if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP_MR1) {
- return false
- }
-
- return FlipperUtils.shouldEnableFlipper(context)
- }
-
- override fun init(matrix: Matrix) {
- if (!isEnabled) return
-
- SoLoader.init(context, false)
-
- val client = AndroidFlipperClient.getInstance(context)
- client.addPlugin(CrashReporterPlugin.getInstance())
- client.addPlugin(SharedPreferencesFlipperPlugin(context))
- client.addPlugin(InspectorFlipperPlugin(context, DescriptorMapping.withDefaults()))
- client.addPlugin(networkFlipperPlugin)
- client.addPlugin(
- DatabasesFlipperPlugin(
- RealmDatabaseDriver(
- context = context,
- realmDatabaseProvider = object : RealmDatabaseProvider {
- override fun getRealmConfigurations(): List {
- return matrix.debugService().getAllRealmConfigurations()
- }
- })
- )
- )
- client.start()
- }
-
- override fun networkInterceptor(): Interceptor? {
- if (!isEnabled) return null
-
- return FlipperOkhttpInterceptor(networkFlipperPlugin)
- }
-}
diff --git a/vector-app/src/main/java/im/vector/app/VectorApplication.kt b/vector-app/src/main/java/im/vector/app/VectorApplication.kt
index 84b87b14040..f89d22c16b3 100644
--- a/vector-app/src/main/java/im/vector/app/VectorApplication.kt
+++ b/vector-app/src/main/java/im/vector/app/VectorApplication.kt
@@ -33,12 +33,10 @@ import com.airbnb.mvrx.Mavericks
import com.facebook.stetho.Stetho
import com.gabrielittner.threetenbp.LazyThreeTen
import com.github.rubensousa.gravitysnaphelper.GravitySnapHelper
-import com.mapbox.mapboxsdk.Mapbox
import com.vanniktech.emoji.EmojiManager
import com.vanniktech.emoji.google.GoogleEmojiProvider
import dagger.hilt.android.HiltAndroidApp
import im.vector.app.config.Config
-import im.vector.app.core.debug.FlipperProxy
import im.vector.app.core.debug.LeakDetector
import im.vector.app.core.di.ActiveSessionHolder
import im.vector.app.core.pushers.FcmHelper
@@ -62,6 +60,7 @@ import im.vector.app.features.themes.ThemeUtils
import im.vector.app.features.version.VersionProvider
import im.vector.application.R
import org.jitsi.meet.sdk.log.JitsiMeetDefaultLogHandler
+import org.maplibre.android.MapLibre
import org.matrix.android.sdk.api.Matrix
import org.matrix.android.sdk.api.auth.AuthenticationService
import timber.log.Timber
@@ -97,7 +96,6 @@ class VectorApplication :
@Inject lateinit var decryptionFailureTracker: DecryptionFailureTracker
@Inject lateinit var vectorFileLogger: VectorFileLogger
@Inject lateinit var vectorAnalytics: VectorAnalytics
- @Inject lateinit var flipperProxy: FlipperProxy
@Inject lateinit var matrix: Matrix
@Inject lateinit var fcmHelper: FcmHelper
@Inject lateinit var buildMeta: BuildMeta
@@ -121,7 +119,6 @@ class VectorApplication :
enableStrictModeIfNeeded()
super.onCreate()
appContext = this
- flipperProxy.init(matrix)
vectorAnalytics.init()
vectorAnalytics.updateSuperProperties(
SuperProperties(
@@ -223,7 +220,7 @@ class VectorApplication :
EmojiManager.install(GoogleEmojiProvider())
// Initialize Mapbox before inflating mapViews
- Mapbox.getInstance(this)
+ MapLibre.getInstance(this)
initMemoryLeakAnalysis()
}
diff --git a/vector-app/src/main/java/im/vector/app/core/di/SingletonModule.kt b/vector-app/src/main/java/im/vector/app/core/di/SingletonModule.kt
index 4f1180303a3..49f0fd7aae3 100644
--- a/vector-app/src/main/java/im/vector/app/core/di/SingletonModule.kt
+++ b/vector-app/src/main/java/im/vector/app/core/di/SingletonModule.kt
@@ -24,7 +24,6 @@ import im.vector.app.EmojiSpanify
import im.vector.app.SpaceStateHandler
import im.vector.app.SpaceStateHandlerImpl
import im.vector.app.config.Config
-import im.vector.app.core.debug.FlipperProxy
import im.vector.app.core.device.DefaultGetDeviceInfoUseCase
import im.vector.app.core.device.GetDeviceInfoUseCase
import im.vector.app.core.dispatchers.CoroutineDispatchers
@@ -140,7 +139,6 @@ import javax.inject.Singleton
fun providesMatrixConfiguration(
vectorPreferences: VectorPreferences,
vectorRoomDisplayNameFallbackProvider: VectorRoomDisplayNameFallbackProvider,
- flipperProxy: FlipperProxy,
vectorPlugins: VectorPlugins,
vectorCustomEventTypesProvider: VectorCustomEventTypesProvider,
mdmService: MdmService,
@@ -149,9 +147,7 @@ import javax.inject.Singleton
applicationFlavor = BuildConfig.FLAVOR_DESCRIPTION,
roomDisplayNameFallbackProvider = vectorRoomDisplayNameFallbackProvider,
threadMessagesEnabledDefault = vectorPreferences.areThreadMessagesEnabled(),
- networkInterceptors = listOfNotNull(
- flipperProxy.networkInterceptor(),
- ),
+ networkInterceptors = emptyList(),
metricPlugins = vectorPlugins.plugins(),
cryptoAnalyticsPlugin = vectorPlugins.cryptoMetricPlugin,
customEventTypesProvider = vectorCustomEventTypesProvider,
diff --git a/vector-app/src/release/java/im/vector/app/core/di/DebugModule.kt b/vector-app/src/release/java/im/vector/app/core/di/DebugModule.kt
index 89a2d184842..2819bc9c821 100644
--- a/vector-app/src/release/java/im/vector/app/core/di/DebugModule.kt
+++ b/vector-app/src/release/java/im/vector/app/core/di/DebugModule.kt
@@ -14,10 +14,7 @@ import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import im.vector.app.core.debug.DebugNavigator
import im.vector.app.core.debug.DebugReceiver
-import im.vector.app.core.debug.FlipperProxy
import im.vector.app.core.debug.LeakDetector
-import okhttp3.Interceptor
-import org.matrix.android.sdk.api.Matrix
@InstallIn(SingletonComponent::class)
@Module
@@ -41,15 +38,6 @@ object DebugModule {
}
}
- @Provides
- fun providesFlipperProxy() = object : FlipperProxy {
- override fun init(matrix: Matrix) {
- // no op
- }
-
- override fun networkInterceptor(): Interceptor? = null
- }
-
@Provides
fun providesLeakDetector() = object : LeakDetector {
override fun enable(enable: Boolean) {
diff --git a/vector/src/main/java/im/vector/app/core/debug/FlipperProxy.kt b/vector/src/main/java/im/vector/app/core/debug/FlipperProxy.kt
deleted file mode 100644
index d3dc4b346ee..00000000000
--- a/vector/src/main/java/im/vector/app/core/debug/FlipperProxy.kt
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * 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.
- */
-
-package im.vector.app.core.debug
-
-import okhttp3.Interceptor
-import org.matrix.android.sdk.api.Matrix
-
-interface FlipperProxy {
- fun init(matrix: Matrix)
- fun networkInterceptor(): Interceptor?
-}
diff --git a/vector/src/main/java/im/vector/app/features/analytics/metrics/sentry/SentrySyncDurationMetrics.kt b/vector/src/main/java/im/vector/app/features/analytics/metrics/sentry/SentrySyncDurationMetrics.kt
index 877e4c3450f..65e5fe542c4 100644
--- a/vector/src/main/java/im/vector/app/features/analytics/metrics/sentry/SentrySyncDurationMetrics.kt
+++ b/vector/src/main/java/im/vector/app/features/analytics/metrics/sentry/SentrySyncDurationMetrics.kt
@@ -11,6 +11,7 @@ import io.sentry.ISpan
import io.sentry.ITransaction
import io.sentry.Sentry
import io.sentry.SpanStatus
+import io.sentry.TransactionOptions
import org.matrix.android.sdk.api.metrics.SyncDurationMetricPlugin
import java.util.EmptyStackException
import java.util.Stack
@@ -58,7 +59,13 @@ class SentrySyncDurationMetrics @Inject constructor() : SyncDurationMetricPlugin
override fun startTransaction() {
if (Sentry.isEnabled()) {
- transaction = Sentry.startTransaction("sync_response_handler", "task", true)
+ transaction = Sentry.startTransaction(
+ "sync_response_handler",
+ "task",
+ TransactionOptions().apply {
+ isBindToScope = true
+ },
+ )
logTransaction("Sentry transaction started")
}
}
diff --git a/vector/src/main/java/im/vector/app/features/location/LocationSharingFragment.kt b/vector/src/main/java/im/vector/app/features/location/LocationSharingFragment.kt
index d5b0850ce8a..069c6686c81 100644
--- a/vector/src/main/java/im/vector/app/features/location/LocationSharingFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/location/LocationSharingFragment.kt
@@ -21,7 +21,6 @@ import androidx.lifecycle.lifecycleScope
import com.airbnb.mvrx.fragmentViewModel
import com.airbnb.mvrx.withState
import com.google.android.material.dialog.MaterialAlertDialogBuilder
-import com.mapbox.mapboxsdk.maps.MapView
import dagger.hilt.android.AndroidEntryPoint
import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment
import im.vector.app.core.platform.VectorBaseFragment
@@ -39,6 +38,7 @@ import im.vector.app.features.location.option.LocationSharingOption
import im.vector.app.features.settings.VectorPreferences
import im.vector.lib.strings.CommonStrings
import kotlinx.coroutines.launch
+import org.maplibre.android.maps.MapView
import org.matrix.android.sdk.api.util.MatrixItem
import java.lang.ref.WeakReference
import javax.inject.Inject
diff --git a/vector/src/main/java/im/vector/app/features/location/MapBoxMapExt.kt b/vector/src/main/java/im/vector/app/features/location/MapBoxMapExt.kt
index c187757dc70..be88d5809b5 100644
--- a/vector/src/main/java/im/vector/app/features/location/MapBoxMapExt.kt
+++ b/vector/src/main/java/im/vector/app/features/location/MapBoxMapExt.kt
@@ -7,14 +7,14 @@
package im.vector.app.features.location
-import com.mapbox.mapboxsdk.camera.CameraPosition
-import com.mapbox.mapboxsdk.camera.CameraUpdateFactory
-import com.mapbox.mapboxsdk.constants.MapboxConstants
-import com.mapbox.mapboxsdk.geometry.LatLng
-import com.mapbox.mapboxsdk.geometry.LatLngBounds
-import com.mapbox.mapboxsdk.maps.MapboxMap
+import org.maplibre.android.camera.CameraPosition
+import org.maplibre.android.camera.CameraUpdateFactory
+import org.maplibre.android.constants.MapLibreConstants
+import org.maplibre.android.geometry.LatLng
+import org.maplibre.android.geometry.LatLngBounds
+import org.maplibre.android.maps.MapLibreMap
-fun MapboxMap?.zoomToLocation(locationData: LocationData, preserveCurrentZoomLevel: Boolean = false) {
+fun MapLibreMap?.zoomToLocation(locationData: LocationData, preserveCurrentZoomLevel: Boolean = false) {
val zoomLevel = if (preserveCurrentZoomLevel && this?.cameraPosition != null) {
cameraPosition.zoom
} else {
@@ -28,11 +28,11 @@ fun MapboxMap?.zoomToLocation(locationData: LocationData, preserveCurrentZoomLev
this?.easeCamera(cameraUpdate)
}
-fun MapboxMap?.zoomToBounds(latLngBounds: LatLngBounds) {
+fun MapLibreMap?.zoomToBounds(latLngBounds: LatLngBounds) {
this?.getCameraForLatLngBounds(latLngBounds)?.let { camPosition ->
// unZoom a little to avoid having pins exactly at the edges of the map
cameraPosition = CameraPosition.Builder(camPosition)
- .zoom((camPosition.zoom - 1).coerceAtLeast(MapboxConstants.MINIMUM_ZOOM.toDouble()))
+ .zoom((camPosition.zoom - 1).coerceAtLeast(MapLibreConstants.MINIMUM_ZOOM.toDouble()))
.build()
}
}
diff --git a/vector/src/main/java/im/vector/app/features/location/MapTilerMapView.kt b/vector/src/main/java/im/vector/app/features/location/MapTilerMapView.kt
index 15af86a4da7..cfce7dffec3 100644
--- a/vector/src/main/java/im/vector/app/features/location/MapTilerMapView.kt
+++ b/vector/src/main/java/im/vector/app/features/location/MapTilerMapView.kt
@@ -19,16 +19,16 @@ import androidx.core.graphics.drawable.toBitmap
import androidx.core.view.marginBottom
import androidx.core.view.marginTop
import androidx.core.view.updateLayoutParams
-import com.mapbox.mapboxsdk.geometry.LatLng
-import com.mapbox.mapboxsdk.maps.MapView
-import com.mapbox.mapboxsdk.maps.MapboxMap
-import com.mapbox.mapboxsdk.maps.Style
-import com.mapbox.mapboxsdk.plugins.annotation.SymbolManager
-import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions
-import com.mapbox.mapboxsdk.style.layers.Property
import im.vector.app.R
import im.vector.app.core.utils.DimensionConverter
import im.vector.lib.strings.CommonStrings
+import org.maplibre.android.geometry.LatLng
+import org.maplibre.android.maps.MapLibreMap
+import org.maplibre.android.maps.MapView
+import org.maplibre.android.maps.Style
+import org.maplibre.android.plugins.annotation.SymbolManager
+import org.maplibre.android.plugins.annotation.SymbolOptions
+import org.maplibre.android.style.layers.Property
import timber.log.Timber
private const val USER_PIN_ID = "user-pin-id"
@@ -42,7 +42,7 @@ class MapTilerMapView @JvmOverloads constructor(
private var pendingState: MapState? = null
data class MapRefs(
- val map: MapboxMap,
+ val map: MapLibreMap,
val symbolManager: SymbolManager,
val style: Style
)
@@ -94,7 +94,7 @@ class MapTilerMapView @JvmOverloads constructor(
}
}
- private fun initMapStyle(map: MapboxMap, url: String) {
+ private fun initMapStyle(map: MapLibreMap, url: String) {
map.setStyle(url) { style ->
val symbolManager = SymbolManager(this, map, style)
symbolManager.iconAllowOverlap = true
@@ -108,7 +108,7 @@ class MapTilerMapView @JvmOverloads constructor(
}
}
- private fun initLocateButton(map: MapboxMap) {
+ private fun initLocateButton(map: MapLibreMap) {
if (showLocationButton) {
addView(locateButton)
adjustCompassButton(map)
@@ -132,7 +132,7 @@ class MapTilerMapView @JvmOverloads constructor(
}
}
- private fun adjustCompassButton(map: MapboxMap) {
+ private fun adjustCompassButton(map: MapLibreMap) {
locateButton.post {
val marginTop = locateButton.height + locateButton.marginTop + locateButton.marginBottom
val marginRight = context.resources.getDimensionPixelOffset(im.vector.lib.ui.styles.R.dimen.location_sharing_compass_button_margin_horizontal)
@@ -140,7 +140,7 @@ class MapTilerMapView @JvmOverloads constructor(
}
}
- private fun listenCameraMove(map: MapboxMap, locationTargetChangeListener: LocationTargetChangeListener?) {
+ private fun listenCameraMove(map: MapLibreMap, locationTargetChangeListener: LocationTargetChangeListener?) {
map.addOnCameraMoveListener {
notifyLocationOfMapCenter(locationTargetChangeListener)
}
diff --git a/vector/src/main/java/im/vector/app/features/location/domain/usecase/CompareLocationsUseCase.kt b/vector/src/main/java/im/vector/app/features/location/domain/usecase/CompareLocationsUseCase.kt
index 9c17ea8be30..00c05ca4acf 100644
--- a/vector/src/main/java/im/vector/app/features/location/domain/usecase/CompareLocationsUseCase.kt
+++ b/vector/src/main/java/im/vector/app/features/location/domain/usecase/CompareLocationsUseCase.kt
@@ -7,9 +7,9 @@
package im.vector.app.features.location.domain.usecase
-import com.mapbox.mapboxsdk.geometry.LatLng
import im.vector.app.features.location.LocationData
import kotlinx.coroutines.withContext
+import org.maplibre.android.geometry.LatLng
import org.matrix.android.sdk.api.session.Session
import javax.inject.Inject
diff --git a/vector/src/main/java/im/vector/app/features/location/live/map/LiveLocationMapViewFragment.kt b/vector/src/main/java/im/vector/app/features/location/live/map/LiveLocationMapViewFragment.kt
index dae3fe5acbc..7f5ce8c5480 100644
--- a/vector/src/main/java/im/vector/app/features/location/live/map/LiveLocationMapViewFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/location/live/map/LiveLocationMapViewFragment.kt
@@ -21,18 +21,6 @@ import androidx.lifecycle.lifecycleScope
import com.airbnb.mvrx.fragmentViewModel
import com.airbnb.mvrx.withState
import com.google.android.material.bottomsheet.BottomSheetBehavior
-import com.mapbox.mapboxsdk.geometry.LatLng
-import com.mapbox.mapboxsdk.geometry.LatLngBounds
-import com.mapbox.mapboxsdk.maps.MapView
-import com.mapbox.mapboxsdk.maps.MapboxMap
-import com.mapbox.mapboxsdk.maps.MapboxMapOptions
-import com.mapbox.mapboxsdk.maps.Style
-import com.mapbox.mapboxsdk.maps.SupportMapFragment
-import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolClickListener
-import com.mapbox.mapboxsdk.plugins.annotation.Symbol
-import com.mapbox.mapboxsdk.plugins.annotation.SymbolManager
-import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions
-import com.mapbox.mapboxsdk.style.layers.Property
import dagger.hilt.android.AndroidEntryPoint
import im.vector.app.R
import im.vector.app.core.extensions.addChildFragment
@@ -54,6 +42,18 @@ import im.vector.app.features.location.zoomToBounds
import im.vector.app.features.location.zoomToLocation
import im.vector.lib.strings.CommonStrings
import kotlinx.coroutines.launch
+import org.maplibre.android.geometry.LatLng
+import org.maplibre.android.geometry.LatLngBounds
+import org.maplibre.android.maps.MapLibreMap
+import org.maplibre.android.maps.MapLibreMapOptions
+import org.maplibre.android.maps.MapView
+import org.maplibre.android.maps.Style
+import org.maplibre.android.maps.SupportMapFragment
+import org.maplibre.android.plugins.annotation.OnSymbolClickListener
+import org.maplibre.android.plugins.annotation.Symbol
+import org.maplibre.android.plugins.annotation.SymbolManager
+import org.maplibre.android.plugins.annotation.SymbolOptions
+import org.maplibre.android.style.layers.Property
import timber.log.Timber
import java.lang.ref.WeakReference
import javax.inject.Inject
@@ -74,7 +74,7 @@ class LiveLocationMapViewFragment :
private val viewModel: LiveLocationMapViewModel by fragmentViewModel()
- private var mapboxMap: WeakReference? = null
+ private var mapboxMap: WeakReference? = null
private var mapView: MapView? = null
private var symbolManager: SymbolManager? = null
private var mapStyle: Style? = null
@@ -214,7 +214,7 @@ class LiveLocationMapViewFragment :
private fun getOrCreateSupportMapFragment() =
childFragmentManager.findFragmentByTag(MAP_FRAGMENT_TAG) as? SupportMapFragment
?: run {
- val options = MapboxMapOptions.createFromAttributes(requireContext(), null)
+ val options = MapLibreMapOptions.createFromAttributes(requireContext(), null)
SupportMapFragment.newInstance(options)
.also { addChildFragment(R.id.liveLocationMapFragmentContainer, it, tag = MAP_FRAGMENT_TAG) }
}
diff --git a/vector/src/main/java/im/vector/app/features/location/preview/LocationPreviewFragment.kt b/vector/src/main/java/im/vector/app/features/location/preview/LocationPreviewFragment.kt
index 62ea85ee9fe..84ac2a34cd6 100644
--- a/vector/src/main/java/im/vector/app/features/location/preview/LocationPreviewFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/location/preview/LocationPreviewFragment.kt
@@ -17,7 +17,6 @@ import androidx.lifecycle.lifecycleScope
import com.airbnb.mvrx.args
import com.airbnb.mvrx.fragmentViewModel
import com.airbnb.mvrx.withState
-import com.mapbox.mapboxsdk.maps.MapView
import dagger.hilt.android.AndroidEntryPoint
import im.vector.app.R
import im.vector.app.core.platform.VectorBaseFragment
@@ -35,6 +34,7 @@ import im.vector.app.features.location.UrlMapProvider
import im.vector.app.features.location.showUserLocationNotAvailableErrorDialog
import im.vector.lib.strings.CommonStrings
import kotlinx.coroutines.launch
+import org.maplibre.android.maps.MapView
import java.lang.ref.WeakReference
import javax.inject.Inject
diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/DevicesViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/devices/DevicesViewModel.kt
index 1c9fb718585..3ec7cd64aee 100644
--- a/vector/src/main/java/im/vector/app/features/settings/devices/DevicesViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/devices/DevicesViewModel.kt
@@ -337,12 +337,12 @@ class DevicesViewModel @AssistedInject constructor(
private fun handleDelete(action: DevicesAction.Delete) {
val deviceId = action.deviceId
- val accountManagementUrl = session.homeServerCapabilitiesService().getHomeServerCapabilities().externalAccountManagementUrl
- if (accountManagementUrl != null) {
+ val externalLogoutDeviceUrl = session.homeServerCapabilitiesService().getHomeServerCapabilities().getLogoutDeviceURL(deviceId)
+ if (externalLogoutDeviceUrl != null) {
// Open external browser to delete this session
_viewEvents.post(
DevicesViewEvents.OpenBrowser(
- url = accountManagementUrl.removeSuffix("/") + "?action=session_end&device_id=$deviceId"
+ url = externalLogoutDeviceUrl
)
)
} else {
diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewFragment.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewFragment.kt
index 0d90f4f2c98..56a13a77c0f 100644
--- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewFragment.kt
@@ -129,12 +129,12 @@ class SessionOverviewFragment :
}
private fun confirmSignoutOtherSession() = withState(viewModel) { state ->
- if (state.externalAccountManagementUrl != null) {
+ if (state.externalDeleteDeviceUrl != null) {
// Manage in external account manager
openUrlInChromeCustomTab(
requireContext(),
null,
- state.externalAccountManagementUrl.removeSuffix("/") + "?action=session_end&device_id=${state.deviceId}"
+ state.externalDeleteDeviceUrl,
)
} else {
activity?.let {
diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewViewModel.kt
index 8a34f6ce6ed..54cdde22e15 100644
--- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewViewModel.kt
@@ -66,16 +66,16 @@ class SessionOverviewViewModel @AssistedInject constructor(
observeNotificationsStatus(initialState.deviceId)
refreshIpAddressVisibility()
observePreferences()
- initExternalAccountManagementUrl()
+ initExternalDeleteDeviceUrl()
}
- private fun initExternalAccountManagementUrl() {
+ private fun initExternalDeleteDeviceUrl() {
setState {
copy(
- externalAccountManagementUrl = activeSessionHolder.getSafeActiveSession()
+ externalDeleteDeviceUrl = activeSessionHolder.getSafeActiveSession()
?.homeServerCapabilitiesService()
?.getHomeServerCapabilities()
- ?.externalAccountManagementUrl
+ ?.getLogoutDeviceURL(deviceId)
)
}
}
diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewViewState.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewViewState.kt
index f795d29969f..da1847a397b 100644
--- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewViewState.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewViewState.kt
@@ -20,7 +20,7 @@ data class SessionOverviewViewState(
val isLoading: Boolean = false,
val notificationsStatus: NotificationsStatus = NotificationsStatus.NOT_SUPPORTED,
val isShowingIpAddress: Boolean = false,
- val externalAccountManagementUrl: String? = null,
+ val externalDeleteDeviceUrl: String? = null,
) : MavericksState {
constructor(args: SessionOverviewArgs) : this(
deviceId = args.deviceId
diff --git a/vector/src/test/java/im/vector/app/test/fixtures/HomeserverCapabilityFixture.kt b/vector/src/test/java/im/vector/app/test/fixtures/HomeserverCapabilityFixture.kt
index a66fc201c70..ff30a37895f 100644
--- a/vector/src/test/java/im/vector/app/test/fixtures/HomeserverCapabilityFixture.kt
+++ b/vector/src/test/java/im/vector/app/test/fixtures/HomeserverCapabilityFixture.kt
@@ -21,6 +21,7 @@ fun aHomeServerCapabilities(
roomVersions: RoomVersionCapabilities? = null,
canRemotelyTogglePushNotificationsOfDevices: Boolean = true,
externalAccountManagementUrl: String? = null,
+ externalAccountManagementSupportedActions: List? = null,
) = HomeServerCapabilities(
canChangePassword = canChangePassword,
canChangeDisplayName = canChangeDisplayName,
@@ -32,4 +33,5 @@ fun aHomeServerCapabilities(
roomVersions = roomVersions,
canRemotelyTogglePushNotificationsOfDevices = canRemotelyTogglePushNotificationsOfDevices,
externalAccountManagementUrl = externalAccountManagementUrl,
+ externalAccountManagementSupportedActions = externalAccountManagementSupportedActions,
)