diff --git a/CHANGES.md b/CHANGES.md
index 118917fb93..ad9a362197 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -19,7 +19,7 @@ Translations 🗣:
  -
 
 SDK API changes ⚠️:
- - 
+ - Create a new RawService to get plain data from the server.
 
 Build 🧱:
  -
diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/api/Matrix.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/api/Matrix.kt
index df26bb1227..751b2a708c 100644
--- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/api/Matrix.kt
+++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/api/Matrix.kt
@@ -24,6 +24,7 @@ import com.zhuinden.monarchy.Monarchy
 import org.matrix.android.sdk.BuildConfig
 import org.matrix.android.sdk.api.auth.AuthenticationService
 import org.matrix.android.sdk.api.legacy.LegacySessionImporter
+import org.matrix.android.sdk.api.raw.RawService
 import org.matrix.android.sdk.common.DaggerTestMatrixComponent
 import org.matrix.android.sdk.internal.SessionManager
 import org.matrix.android.sdk.internal.network.UserAgentHolder
@@ -41,6 +42,7 @@ class Matrix private constructor(context: Context, matrixConfiguration: MatrixCo
 
     @Inject internal lateinit var legacySessionImporter: LegacySessionImporter
     @Inject internal lateinit var authenticationService: AuthenticationService
+    @Inject internal lateinit var rawService: RawService
     @Inject internal lateinit var userAgentHolder: UserAgentHolder
     @Inject internal lateinit var backgroundDetectionObserver: BackgroundDetectionObserver
     @Inject internal lateinit var olmManager: OlmManager
@@ -61,6 +63,8 @@ class Matrix private constructor(context: Context, matrixConfiguration: MatrixCo
         return authenticationService
     }
 
+    fun rawService() = rawService
+
     fun legacySessionImporter(): LegacySessionImporter {
         return legacySessionImporter
     }
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/Matrix.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/Matrix.kt
index aafefa2048..e6f982682b 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/Matrix.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/Matrix.kt
@@ -25,6 +25,7 @@ import com.zhuinden.monarchy.Monarchy
 import org.matrix.android.sdk.BuildConfig
 import org.matrix.android.sdk.api.auth.AuthenticationService
 import org.matrix.android.sdk.api.legacy.LegacySessionImporter
+import org.matrix.android.sdk.api.raw.RawService
 import org.matrix.android.sdk.internal.SessionManager
 import org.matrix.android.sdk.internal.di.DaggerMatrixComponent
 import org.matrix.android.sdk.internal.network.UserAgentHolder
@@ -42,6 +43,7 @@ class Matrix private constructor(context: Context, matrixConfiguration: MatrixCo
 
     @Inject internal lateinit var legacySessionImporter: LegacySessionImporter
     @Inject internal lateinit var authenticationService: AuthenticationService
+    @Inject internal lateinit var rawService: RawService
     @Inject internal lateinit var userAgentHolder: UserAgentHolder
     @Inject internal lateinit var backgroundDetectionObserver: BackgroundDetectionObserver
     @Inject internal lateinit var olmManager: OlmManager
@@ -62,6 +64,8 @@ class Matrix private constructor(context: Context, matrixConfiguration: MatrixCo
         return authenticationService
     }
 
+    fun rawService() = rawService
+
     fun legacySessionImporter(): LegacySessionImporter {
         return legacySessionImporter
     }
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/data/WellKnown.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/data/WellKnown.kt
index b10cae6171..4f7bc75556 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/data/WellKnown.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/data/WellKnown.kt
@@ -42,9 +42,6 @@ import org.matrix.android.sdk.api.util.JsonDict
  *              }
  *          ]
  *    }
- *     "im.vector.riot.jitsi": {
- *         "preferredDomain": "https://jitsi.riot.im/"
- *     }
  * }
  * </pre>
  */
@@ -57,24 +54,5 @@ data class WellKnown(
         val identityServer: WellKnownBaseConfig? = null,
 
         @Json(name = "m.integrations")
-        val integrations: JsonDict? = null,
-
-        @Json(name = "im.vector.riot.e2ee")
-        val e2eAdminSetting: E2EWellKnownConfig? = null,
-
-        @Json(name = "im.vector.riot.jitsi")
-        val jitsiServer: WellKnownPreferredConfig? = null
-
-)
-
-@JsonClass(generateAdapter = true)
-data class E2EWellKnownConfig(
-        @Json(name = "default")
-        val e2eDefault: Boolean = true
-)
-
-@JsonClass(generateAdapter = true)
-data class WellKnownPreferredConfig(
-        @Json(name = "preferredDomain")
-        val preferredDomain: String? = null
+        val integrations: JsonDict? = null
 )
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/raw/RawCacheStrategy.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/raw/RawCacheStrategy.kt
new file mode 100644
index 0000000000..06657a9869
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/raw/RawCacheStrategy.kt
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2020 New Vector Ltd
+ * Copyright 2020 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.raw
+
+sealed class RawCacheStrategy {
+    // Data is always fetched from the server
+    object NoCache: RawCacheStrategy()
+
+    // Once data is retrieved, it is stored for the provided amount of time.
+    // In case of error, and if strict is set to false, the cache can be returned if available
+    data class TtlCache(val validityDurationInMillis: Long, val strict: Boolean): RawCacheStrategy()
+
+    // Once retrieved, the data is stored in cache and will be always get from the cache
+    object InfiniteCache: RawCacheStrategy()
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/raw/RawService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/raw/RawService.kt
new file mode 100644
index 0000000000..5c96d175cb
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/raw/RawService.kt
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2020 New Vector Ltd
+ * Copyright 2020 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.raw
+
+import org.matrix.android.sdk.api.MatrixCallback
+import org.matrix.android.sdk.api.util.Cancelable
+
+/**
+ * Useful methods to fetch raw data from the server. The access token will not be used to fetched the data
+ */
+interface RawService {
+    /**
+     * Get a URL, either from cache or from the remote server, depending on the cache strategy
+     */
+    fun getUrl(url: String,
+               rawCacheStrategy: RawCacheStrategy,
+               matrixCallback: MatrixCallback<String>): Cancelable
+
+    /**
+     * Specific case for the well-known file. Cache validity is 8 hours
+     */
+    fun getWellknown(userId: String, matrixCallback: MatrixCallback<String>): Cancelable
+
+    /**
+     * Clear all the cache data
+     */
+    fun clearCache(matrixCallback: MatrixCallback<Unit>): Cancelable
+}
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 de7ac45bf3..e12d99d6b8 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
@@ -33,16 +33,7 @@ data class HomeServerCapabilities(
         /**
          * Default identity server url, provided in Wellknown
          */
-        val defaultIdentityServerUrl: String? = null,
-        /**
-         * Option to allow homeserver admins to set the default E2EE behaviour back to disabled for DMs / private rooms
-         * (as it was before) for various environments where this is desired.
-         */
-        val adminE2EByDefault: Boolean = true,
-        /**
-         * Preferred Jitsi domain, provided in Wellknown
-         */
-        val preferredJitsiDomain: String? = null
+        val defaultIdentityServerUrl: String? = null
 ) {
     companion object {
         const val MAX_UPLOAD_FILE_SIZE_UNKNOWN = -1L
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 ad05406aa0..26ce38e322 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
@@ -28,7 +28,7 @@ import javax.inject.Inject
 class RealmSessionStoreMigration @Inject constructor() : RealmMigration {
 
     companion object {
-        const val SESSION_STORE_SCHEMA_VERSION = 4L
+        const val SESSION_STORE_SCHEMA_VERSION = 5L
     }
 
     override fun migrate(realm: DynamicRealm, oldVersion: Long, newVersion: Long) {
@@ -38,6 +38,7 @@ class RealmSessionStoreMigration @Inject constructor() : RealmMigration {
         if (oldVersion <= 1) migrateTo2(realm)
         if (oldVersion <= 2) migrateTo3(realm)
         if (oldVersion <= 3) migrateTo4(realm)
+        if (oldVersion <= 4) migrateTo5(realm)
     }
 
     private fun migrateTo1(realm: DynamicRealm) {
@@ -54,16 +55,16 @@ class RealmSessionStoreMigration @Inject constructor() : RealmMigration {
     private fun migrateTo2(realm: DynamicRealm) {
         Timber.d("Step 1 -> 2")
         realm.schema.get("HomeServerCapabilitiesEntity")
-                ?.addField(HomeServerCapabilitiesEntityFields.ADMIN_E2_E_BY_DEFAULT, Boolean::class.java)
+                ?.addField("adminE2EByDefault", Boolean::class.java)
                 ?.transform { obj ->
-                    obj.setBoolean(HomeServerCapabilitiesEntityFields.ADMIN_E2_E_BY_DEFAULT, true)
+                    obj.setBoolean("adminE2EByDefault", true)
                 }
     }
 
     private fun migrateTo3(realm: DynamicRealm) {
         Timber.d("Step 2 -> 3")
         realm.schema.get("HomeServerCapabilitiesEntity")
-                ?.addField(HomeServerCapabilitiesEntityFields.PREFERRED_JITSI_DOMAIN, String::class.java)
+                ?.addField("preferredJitsiDomain", String::class.java)
                 ?.transform { obj ->
                     // Schedule a refresh of the capabilities
                     obj.setLong(HomeServerCapabilitiesEntityFields.LAST_UPDATED_TIMESTAMP, 0)
@@ -82,4 +83,11 @@ class RealmSessionStoreMigration @Inject constructor() : RealmMigration {
                 .setRequired(PendingThreePidEntityFields.SID, true)
                 .addField(PendingThreePidEntityFields.SUBMIT_URL, String::class.java)
     }
+
+    private fun migrateTo5(realm: DynamicRealm) {
+        Timber.d("Step 4 -> 5")
+        realm.schema.get("HomeServerCapabilitiesEntity")
+                ?.removeField("adminE2EByDefault")
+                ?.removeField("preferredJitsiDomain")
+    }
 }
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 e5de271d93..4eb9b4b47f 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
@@ -30,9 +30,7 @@ internal object HomeServerCapabilitiesMapper {
                 canChangePassword = entity.canChangePassword,
                 maxUploadFileSize = entity.maxUploadFileSize,
                 lastVersionIdentityServerSupported = entity.lastVersionIdentityServerSupported,
-                defaultIdentityServerUrl = entity.defaultIdentityServerUrl,
-                adminE2EByDefault = entity.adminE2EByDefault,
-                preferredJitsiDomain = entity.preferredJitsiDomain
+                defaultIdentityServerUrl = entity.defaultIdentityServerUrl
         )
     }
 }
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 7e3af69436..a905dc9535 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
@@ -17,17 +17,15 @@
 
 package org.matrix.android.sdk.internal.database.model
 
-import org.matrix.android.sdk.api.session.homeserver.HomeServerCapabilities
 import io.realm.RealmObject
+import org.matrix.android.sdk.api.session.homeserver.HomeServerCapabilities
 
 internal open class HomeServerCapabilitiesEntity(
         var canChangePassword: Boolean = true,
         var maxUploadFileSize: Long = HomeServerCapabilities.MAX_UPLOAD_FILE_SIZE_UNKNOWN,
         var lastVersionIdentityServerSupported: Boolean = false,
         var defaultIdentityServerUrl: String? = null,
-        var adminE2EByDefault: Boolean = true,
-        var lastUpdatedTimestamp: Long = 0L,
-        var preferredJitsiDomain: String? = null
+        var lastUpdatedTimestamp: Long = 0L
 ) : RealmObject() {
 
     companion object
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/RawCacheEntity.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/RawCacheEntity.kt
new file mode 100644
index 0000000000..3c0a280476
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/RawCacheEntity.kt
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2019 New Vector Ltd
+ * Copyright 2020 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.model
+
+import io.realm.RealmObject
+import io.realm.annotations.PrimaryKey
+
+internal open class RawCacheEntity(
+        @PrimaryKey
+        var url: String = "",
+        var data: String = "",
+        var lastUpdatedTimestamp: Long = 0L
+) : RealmObject() {
+
+    companion object
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/RawCacheQueries.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/RawCacheQueries.kt
new file mode 100644
index 0000000000..93753ff24b
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/RawCacheQueries.kt
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2019 New Vector Ltd
+ * Copyright 2020 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.query
+
+import io.realm.Realm
+import io.realm.kotlin.createObject
+import io.realm.kotlin.where
+import org.matrix.android.sdk.internal.database.model.RawCacheEntity
+import org.matrix.android.sdk.internal.database.model.RawCacheEntityFields
+
+/**
+ * Get the current RawCacheEntity, return null if it does not exist
+ */
+internal fun RawCacheEntity.Companion.get(realm: Realm, url: String): RawCacheEntity? {
+    return realm.where<RawCacheEntity>()
+            .equalTo(RawCacheEntityFields.URL, url)
+            .findFirst()
+}
+
+/**
+ * Get the current RawCacheEntity, create one if it does not exist
+ */
+internal fun RawCacheEntity.Companion.getOrCreate(realm: Realm, url: String): RawCacheEntity {
+    return get(realm, url) ?: realm.createObject(url)
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/di/DbQualifiers.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/di/DbQualifiers.kt
index 9442dc4865..2380ea68b8 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/di/DbQualifiers.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/di/DbQualifiers.kt
@@ -23,6 +23,10 @@ import javax.inject.Qualifier
 @Retention(AnnotationRetention.RUNTIME)
 internal annotation class AuthDatabase
 
+@Qualifier
+@Retention(AnnotationRetention.RUNTIME)
+internal annotation class GlobalDatabase
+
 @Qualifier
 @Retention(AnnotationRetention.RUNTIME)
 internal annotation class SessionDatabase
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/di/MatrixComponent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/di/MatrixComponent.kt
index 816a674d81..e51d8f3ad3 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/di/MatrixComponent.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/di/MatrixComponent.kt
@@ -22,22 +22,30 @@ import android.content.res.Resources
 import com.squareup.moshi.Moshi
 import dagger.BindsInstance
 import dagger.Component
+import okhttp3.OkHttpClient
 import org.matrix.android.sdk.api.Matrix
 import org.matrix.android.sdk.api.MatrixConfiguration
 import org.matrix.android.sdk.api.auth.AuthenticationService
+import org.matrix.android.sdk.api.raw.RawService
 import org.matrix.android.sdk.internal.SessionManager
 import org.matrix.android.sdk.internal.auth.AuthModule
 import org.matrix.android.sdk.internal.auth.SessionParamsStore
+import org.matrix.android.sdk.internal.raw.RawModule
 import org.matrix.android.sdk.internal.session.MockHttpInterceptor
 import org.matrix.android.sdk.internal.session.TestInterceptor
 import org.matrix.android.sdk.internal.task.TaskExecutor
 import org.matrix.android.sdk.internal.util.BackgroundDetectionObserver
 import org.matrix.android.sdk.internal.util.MatrixCoroutineDispatchers
-import okhttp3.OkHttpClient
 import org.matrix.olm.OlmManager
 import java.io.File
 
-@Component(modules = [MatrixModule::class, NetworkModule::class, AuthModule::class, NoOpTestModule::class])
+@Component(modules = [
+    MatrixModule::class,
+    NetworkModule::class,
+    AuthModule::class,
+    RawModule::class,
+    NoOpTestModule::class
+])
 @MatrixScope
 internal interface MatrixComponent {
 
@@ -53,6 +61,8 @@ internal interface MatrixComponent {
 
     fun authenticationService(): AuthenticationService
 
+    fun rawService(): RawService
+
     fun context(): Context
 
     fun matrixConfiguration(): MatrixConfiguration
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/raw/DefaultCleanRawCacheTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/raw/DefaultCleanRawCacheTask.kt
new file mode 100644
index 0000000000..7ab6645244
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/raw/DefaultCleanRawCacheTask.kt
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2019 New Vector Ltd
+ * Copyright 2020 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.raw
+
+import com.zhuinden.monarchy.Monarchy
+import io.realm.kotlin.where
+import org.matrix.android.sdk.internal.database.model.RawCacheEntity
+import org.matrix.android.sdk.internal.di.GlobalDatabase
+import org.matrix.android.sdk.internal.task.Task
+import org.matrix.android.sdk.internal.util.awaitTransaction
+import javax.inject.Inject
+
+internal interface CleanRawCacheTask : Task<Unit, Unit>
+
+internal class DefaultCleanRawCacheTask @Inject constructor(
+        @GlobalDatabase private val monarchy: Monarchy
+) : CleanRawCacheTask {
+
+    override suspend fun execute(params: Unit) {
+        monarchy.awaitTransaction { realm ->
+            realm.where<RawCacheEntity>()
+                    .findAll()
+                    .deleteAllFromRealm()
+        }
+    }
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/raw/DefaultGetUrlTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/raw/DefaultGetUrlTask.kt
new file mode 100644
index 0000000000..08594a766b
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/raw/DefaultGetUrlTask.kt
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2019 New Vector Ltd
+ * Copyright 2020 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.raw
+
+import com.zhuinden.monarchy.Monarchy
+import okhttp3.ResponseBody
+import org.matrix.android.sdk.api.raw.RawCacheStrategy
+import org.matrix.android.sdk.internal.database.model.RawCacheEntity
+import org.matrix.android.sdk.internal.database.query.get
+import org.matrix.android.sdk.internal.database.query.getOrCreate
+import org.matrix.android.sdk.internal.di.GlobalDatabase
+import org.matrix.android.sdk.internal.network.executeRequest
+import org.matrix.android.sdk.internal.task.Task
+import org.matrix.android.sdk.internal.util.awaitTransaction
+import java.util.Date
+import javax.inject.Inject
+
+internal interface GetUrlTask : Task<GetUrlTask.Params, String> {
+    data class Params(
+            val url: String,
+            val rawCacheStrategy: RawCacheStrategy
+    )
+}
+
+internal class DefaultGetUrlTask @Inject constructor(
+        private val rawAPI: RawAPI,
+        @GlobalDatabase private val monarchy: Monarchy
+) : GetUrlTask {
+
+    override suspend fun execute(params: GetUrlTask.Params): String {
+        return when (params.rawCacheStrategy) {
+            RawCacheStrategy.NoCache -> doRequest(params.url)
+            is RawCacheStrategy.TtlCache -> doRequestWithCache(
+                    params.url,
+                    params.rawCacheStrategy.validityDurationInMillis,
+                    params.rawCacheStrategy.strict
+            )
+            RawCacheStrategy.InfiniteCache -> doRequestWithCache(
+                    params.url,
+                    Long.MAX_VALUE,
+                    true
+            )
+        }
+    }
+
+    private suspend fun doRequest(url: String): String {
+        return executeRequest<ResponseBody>(null) {
+            apiCall = rawAPI.getUrl(url)
+        }
+                .string()
+    }
+
+    private suspend fun doRequestWithCache(url: String, validityDurationInMillis: Long, strict: Boolean): String {
+        // Get data from cache
+        var dataFromCache: String? = null
+        var isCacheValid = false
+        monarchy.awaitTransaction { realm ->
+            val entity = RawCacheEntity.get(realm, url)
+            dataFromCache = entity?.data
+            isCacheValid = entity != null && Date().time < entity.lastUpdatedTimestamp + validityDurationInMillis
+        }
+
+        if (dataFromCache != null && isCacheValid) {
+            return dataFromCache as String
+        }
+
+        // No cache or outdated cache
+        val data = try {
+            doRequest(url)
+        } catch (throwable: Throwable) {
+            // In case of error, we can return value from cache even if outdated
+            return dataFromCache
+                    ?.takeIf { !strict }
+                    ?: throw throwable
+        }
+
+        // Store cache
+        monarchy.awaitTransaction { realm ->
+            val rawCacheEntity = RawCacheEntity.getOrCreate(realm, url)
+            rawCacheEntity.data = data
+            rawCacheEntity.lastUpdatedTimestamp = Date().time
+        }
+
+        return data
+    }
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/raw/DefaultRawService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/raw/DefaultRawService.kt
new file mode 100644
index 0000000000..792a0b3aa7
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/raw/DefaultRawService.kt
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2020 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.matrix.android.sdk.internal.raw
+
+import org.matrix.android.sdk.api.MatrixCallback
+import org.matrix.android.sdk.api.raw.RawCacheStrategy
+import org.matrix.android.sdk.api.raw.RawService
+import org.matrix.android.sdk.api.util.Cancelable
+import org.matrix.android.sdk.internal.task.TaskExecutor
+import org.matrix.android.sdk.internal.task.configureWith
+import java.util.concurrent.TimeUnit
+import javax.inject.Inject
+
+internal class DefaultRawService @Inject constructor(
+        private val taskExecutor: TaskExecutor,
+        private val getUrlTask: GetUrlTask,
+        private val cleanRawCacheTask: CleanRawCacheTask
+) : RawService {
+    override fun getUrl(url: String,
+                        rawCacheStrategy: RawCacheStrategy,
+                        matrixCallback: MatrixCallback<String>): Cancelable {
+        return getUrlTask
+                .configureWith(GetUrlTask.Params(url, rawCacheStrategy)) {
+                    callback = matrixCallback
+                }
+                .executeBy(taskExecutor)
+    }
+
+    override fun getWellknown(userId: String,
+                              matrixCallback: MatrixCallback<String>): Cancelable {
+        val homeServerDomain = userId.substringAfter(":")
+        return getUrl(
+                "https://$homeServerDomain/.well-known/matrix/client",
+                RawCacheStrategy.TtlCache(TimeUnit.HOURS.toMillis(8), false),
+                matrixCallback
+        )
+    }
+
+    override fun clearCache(matrixCallback: MatrixCallback<Unit>): Cancelable {
+        return cleanRawCacheTask
+                .configureWith(Unit) {
+                    callback = matrixCallback
+                }
+                .executeBy(taskExecutor)
+    }
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/raw/GlobalRealmModule.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/raw/GlobalRealmModule.kt
new file mode 100644
index 0000000000..4df5edae88
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/raw/GlobalRealmModule.kt
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2019 New Vector Ltd
+ * Copyright 2020 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.raw
+
+import io.realm.annotations.RealmModule
+import org.matrix.android.sdk.internal.database.model.RawCacheEntity
+
+/**
+ * Realm module for global classes
+ */
+@RealmModule(library = true,
+        classes = [
+            RawCacheEntity::class
+        ])
+internal class GlobalRealmModule
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/raw/RawAPI.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/raw/RawAPI.kt
new file mode 100644
index 0000000000..f7aa738e90
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/raw/RawAPI.kt
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2020 New Vector Ltd
+ * Copyright 2020 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.raw
+
+import okhttp3.ResponseBody
+import retrofit2.Call
+import retrofit2.http.GET
+import retrofit2.http.Url
+
+internal interface RawAPI {
+    @GET
+    fun getUrl(@Url url: String): Call<ResponseBody>
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/raw/RawModule.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/raw/RawModule.kt
new file mode 100644
index 0000000000..6863ccb0a6
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/raw/RawModule.kt
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2020 New Vector Ltd
+ * Copyright 2020 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.raw
+
+import com.zhuinden.monarchy.Monarchy
+import dagger.Binds
+import dagger.Lazy
+import dagger.Module
+import dagger.Provides
+import io.realm.RealmConfiguration
+import okhttp3.OkHttpClient
+import org.matrix.android.sdk.api.raw.RawService
+import org.matrix.android.sdk.internal.database.RealmKeysUtils
+import org.matrix.android.sdk.internal.di.GlobalDatabase
+import org.matrix.android.sdk.internal.di.Unauthenticated
+import org.matrix.android.sdk.internal.network.RetrofitFactory
+
+@Module
+internal abstract class RawModule {
+
+    @Module
+    companion object {
+        private const val DB_ALIAS = "matrix-sdk-global"
+
+        @JvmStatic
+        @Provides
+        @GlobalDatabase
+        fun providesMonarchy(@GlobalDatabase realmConfiguration: RealmConfiguration): Monarchy {
+            return Monarchy.Builder()
+                    .setRealmConfiguration(realmConfiguration)
+                    .build()
+        }
+
+        @JvmStatic
+        @Provides
+        @GlobalDatabase
+        fun providesRealmConfiguration(realmKeysUtils: RealmKeysUtils): RealmConfiguration {
+            return RealmConfiguration.Builder()
+                    .apply {
+                        realmKeysUtils.configureEncryption(this, DB_ALIAS)
+                    }
+                    .name("matrix-sdk-global.realm")
+                    .modules(GlobalRealmModule())
+                    .build()
+        }
+
+        @Provides
+        @JvmStatic
+        fun providesRawAPI(@Unauthenticated okHttpClient: Lazy<OkHttpClient>,
+                           retrofitFactory: RetrofitFactory): RawAPI {
+            return retrofitFactory.create(okHttpClient, "https://example.org").create(RawAPI::class.java)
+        }
+    }
+
+    @Binds
+    abstract fun bindRawService(service: DefaultRawService): RawService
+
+    @Binds
+    abstract fun bindGetUrlTask(task: DefaultGetUrlTask): GetUrlTask
+
+    @Binds
+    abstract fun bindCleanRawCacheTask(task: DefaultCleanRawCacheTask): CleanRawCacheTask
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/homeserver/DefaultGetHomeServerCapabilitiesTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/homeserver/DefaultGetHomeServerCapabilitiesTask.kt
index 13ce84cf90..7e1ad600e3 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/homeserver/DefaultGetHomeServerCapabilitiesTask.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/homeserver/DefaultGetHomeServerCapabilitiesTask.kt
@@ -18,6 +18,7 @@
 package org.matrix.android.sdk.internal.session.homeserver
 
 import com.zhuinden.monarchy.Monarchy
+import org.greenrobot.eventbus.EventBus
 import org.matrix.android.sdk.api.auth.data.HomeServerConnectionConfig
 import org.matrix.android.sdk.api.auth.wellknown.WellknownResult
 import org.matrix.android.sdk.api.session.homeserver.HomeServerCapabilities
@@ -32,7 +33,6 @@ import org.matrix.android.sdk.internal.session.integrationmanager.IntegrationMan
 import org.matrix.android.sdk.internal.task.Task
 import org.matrix.android.sdk.internal.util.awaitTransaction
 import org.matrix.android.sdk.internal.wellknown.GetWellknownTask
-import org.greenrobot.eventbus.EventBus
 import timber.log.Timber
 import java.util.Date
 import javax.inject.Inject
@@ -109,16 +109,12 @@ internal class DefaultGetHomeServerCapabilitiesTask @Inject constructor(
 
             if (getWellknownResult != null && getWellknownResult is WellknownResult.Prompt) {
                 homeServerCapabilitiesEntity.defaultIdentityServerUrl = getWellknownResult.identityServerUrl
-                homeServerCapabilitiesEntity.adminE2EByDefault = getWellknownResult.wellKnown.e2eAdminSetting?.e2eDefault ?: true
-                homeServerCapabilitiesEntity.preferredJitsiDomain = getWellknownResult.wellKnown.jitsiServer?.preferredDomain
                 // We are also checking for integration manager configurations
                 val config = configExtractor.extract(getWellknownResult.wellKnown)
                 if (config != null) {
                     Timber.v("Extracted integration config : $config")
                     realm.insertOrUpdate(config)
                 }
-            } else {
-                homeServerCapabilitiesEntity.adminE2EByDefault = true
             }
             homeServerCapabilitiesEntity.lastUpdatedTimestamp = Date().time
         }
diff --git a/vector/src/main/java/im/vector/app/core/di/VectorComponent.kt b/vector/src/main/java/im/vector/app/core/di/VectorComponent.kt
index c6dfd3e10c..c750384485 100644
--- a/vector/src/main/java/im/vector/app/core/di/VectorComponent.kt
+++ b/vector/src/main/java/im/vector/app/core/di/VectorComponent.kt
@@ -57,6 +57,7 @@ import im.vector.app.features.settings.VectorPreferences
 import im.vector.app.features.ui.UiStateRepository
 import org.matrix.android.sdk.api.Matrix
 import org.matrix.android.sdk.api.auth.AuthenticationService
+import org.matrix.android.sdk.api.raw.RawService
 import org.matrix.android.sdk.api.session.Session
 import javax.inject.Singleton
 
@@ -118,6 +119,8 @@ interface VectorComponent {
 
     fun authenticationService(): AuthenticationService
 
+    fun rawService(): RawService
+
     fun bugReporter(): BugReporter
 
     fun vectorUncaughtExceptionHandler(): VectorUncaughtExceptionHandler
diff --git a/vector/src/main/java/im/vector/app/core/di/VectorModule.kt b/vector/src/main/java/im/vector/app/core/di/VectorModule.kt
index 87581628e7..1d7cd33241 100644
--- a/vector/src/main/java/im/vector/app/core/di/VectorModule.kt
+++ b/vector/src/main/java/im/vector/app/core/di/VectorModule.kt
@@ -34,6 +34,7 @@ import im.vector.app.features.ui.UiStateRepository
 import org.matrix.android.sdk.api.Matrix
 import org.matrix.android.sdk.api.auth.AuthenticationService
 import org.matrix.android.sdk.api.legacy.LegacySessionImporter
+import org.matrix.android.sdk.api.raw.RawService
 import org.matrix.android.sdk.api.session.Session
 
 @Module
@@ -78,6 +79,12 @@ abstract class VectorModule {
         fun providesAuthenticationService(matrix: Matrix): AuthenticationService {
             return matrix.authenticationService()
         }
+
+        @Provides
+        @JvmStatic
+        fun providesRawService(matrix: Matrix): RawService {
+            return matrix.rawService()
+        }
     }
 
     @Binds
diff --git a/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomViewModel.kt b/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomViewModel.kt
index a122ed2527..911faa4fb9 100644
--- a/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomViewModel.kt
@@ -16,6 +16,7 @@
 
 package im.vector.app.features.createdirect
 
+import androidx.lifecycle.viewModelScope
 import com.airbnb.mvrx.ActivityViewModelContext
 import com.airbnb.mvrx.MvRxViewModelFactory
 import com.airbnb.mvrx.ViewModelContext
@@ -23,13 +24,20 @@ import com.squareup.inject.assisted.Assisted
 import com.squareup.inject.assisted.AssistedInject
 import im.vector.app.core.extensions.exhaustive
 import im.vector.app.core.platform.VectorViewModel
+import im.vector.app.features.homeserver.ElementWellKnownMapper
+import im.vector.app.features.homeserver.isE2EByDefault
 import im.vector.app.features.userdirectory.PendingInvitee
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+import org.matrix.android.sdk.api.raw.RawService
 import org.matrix.android.sdk.api.session.Session
 import org.matrix.android.sdk.api.session.room.model.create.CreateRoomParams
+import org.matrix.android.sdk.internal.util.awaitCallback
 import org.matrix.android.sdk.rx.rx
 
 class CreateDirectRoomViewModel @AssistedInject constructor(@Assisted
                                                             initialState: CreateDirectRoomViewState,
+                                                            private val rawService: RawService,
                                                             private val session: Session)
     : VectorViewModel<CreateDirectRoomViewState, CreateDirectRoomAction, CreateDirectRoomViewEvents>(initialState) {
 
@@ -54,22 +62,29 @@ class CreateDirectRoomViewModel @AssistedInject constructor(@Assisted
     }
 
     private fun createRoomAndInviteSelectedUsers(invitees: Set<PendingInvitee>) {
-        val roomParams = CreateRoomParams()
-                .apply {
-                    invitees.forEach {
-                        when (it) {
-                            is PendingInvitee.UserPendingInvitee     -> invitedUserIds.add(it.user.userId)
-                            is PendingInvitee.ThreePidPendingInvitee -> invite3pids.add(it.threePid)
-                        }.exhaustive
-                    }
-                    setDirectMessage()
-                    enableEncryptionIfInvitedUsersSupportIt = session.getHomeServerCapabilities().adminE2EByDefault
-                }
+        viewModelScope.launch(Dispatchers.IO) {
+            val adminE2EByDefault = awaitCallback<String> { rawService.getWellknown(session.myUserId, it) }
+                    .let { ElementWellKnownMapper.from(it) }
+                    ?.isE2EByDefault()
+                    ?: true
 
-        session.rx()
-                .createRoom(roomParams)
-                .execute {
-                    copy(createAndInviteState = it)
-                }
+            val roomParams = CreateRoomParams()
+                    .apply {
+                        invitees.forEach {
+                            when (it) {
+                                is PendingInvitee.UserPendingInvitee -> invitedUserIds.add(it.user.userId)
+                                is PendingInvitee.ThreePidPendingInvitee -> invite3pids.add(it.threePid)
+                            }.exhaustive
+                        }
+                        setDirectMessage()
+                        enableEncryptionIfInvitedUsersSupportIt = adminE2EByDefault
+                    }
+
+            session.rx()
+                    .createRoom(roomParams)
+                    .execute {
+                        copy(createAndInviteState = it)
+                    }
+        }
     }
 }
diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewModel.kt
index a77d50d767..dc322f92a7 100644
--- a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewModel.kt
@@ -42,6 +42,7 @@ import im.vector.app.features.home.room.detail.sticker.StickerPickerActionHandle
 import im.vector.app.features.home.room.detail.timeline.helper.RoomSummaryHolder
 import im.vector.app.features.home.room.detail.timeline.helper.TimelineDisplayableEvents
 import im.vector.app.features.home.room.typing.TypingHelper
+import im.vector.app.features.homeserver.ElementWellKnownMapper
 import im.vector.app.features.powerlevel.PowerLevelsObservableFactory
 import im.vector.app.features.settings.VectorLocale
 import im.vector.app.features.settings.VectorPreferences
@@ -59,11 +60,12 @@ import org.matrix.android.sdk.api.MatrixPatterns
 import org.matrix.android.sdk.api.NoOpMatrixCallback
 import org.matrix.android.sdk.api.extensions.tryThis
 import org.matrix.android.sdk.api.query.QueryStringValue
+import org.matrix.android.sdk.api.raw.RawService
 import org.matrix.android.sdk.api.session.Session
 import org.matrix.android.sdk.api.session.crypto.MXCryptoError
 import org.matrix.android.sdk.api.session.events.model.EventType
-import org.matrix.android.sdk.api.session.events.model.isAttachmentMessage
 import org.matrix.android.sdk.api.session.events.model.LocalEcho
+import org.matrix.android.sdk.api.session.events.model.isAttachmentMessage
 import org.matrix.android.sdk.api.session.events.model.isTextMessage
 import org.matrix.android.sdk.api.session.events.model.toContent
 import org.matrix.android.sdk.api.session.events.model.toModel
@@ -110,6 +112,7 @@ class RoomDetailViewModel @AssistedInject constructor(
         private val stringProvider: StringProvider,
         private val rainbowGenerator: RainbowGenerator,
         private val session: Session,
+        private val rawService: RawService,
         private val supportedVerificationMethodsProvider: SupportedVerificationMethodsProvider,
         private val stickerPickerActionHandler: StickerPickerActionHandler,
         private val roomSummaryHolder: RoomSummaryHolder,
@@ -349,7 +352,13 @@ class RoomDetailViewModel @AssistedInject constructor(
             val roomId: String = room.roomId
             val confId = roomId.substring(1, roomId.indexOf(":") - 1) + widgetSessionId.toLowerCase(VectorLocale.applicationLocale)
 
-            val jitsiDomain = session.getHomeServerCapabilities().preferredJitsiDomain ?: stringProvider.getString(R.string.preferred_jitsi_domain)
+            val preferredJitsiDomain = tryThis {
+                awaitCallback<String> { rawService.getWellknown(session.myUserId, it) }
+                        .let { ElementWellKnownMapper.from(it) }
+                        ?.jitsiServer
+                        ?.preferredDomain
+            }
+            val jitsiDomain = preferredJitsiDomain ?: stringProvider.getString(R.string.preferred_jitsi_domain)
 
             // We use the default element wrapper for this widget
             // https://github.com/vector-im/element-web/blob/develop/docs/jitsi-dev.md
diff --git a/vector/src/main/java/im/vector/app/features/homeserver/HomeServerCapabilitiesViewModel.kt b/vector/src/main/java/im/vector/app/features/homeserver/HomeServerCapabilitiesViewModel.kt
index 672fa4c38e..43f66ebca2 100644
--- a/vector/src/main/java/im/vector/app/features/homeserver/HomeServerCapabilitiesViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/homeserver/HomeServerCapabilitiesViewModel.kt
@@ -16,18 +16,42 @@
 
 package im.vector.app.features.homeserver
 
+import androidx.lifecycle.viewModelScope
+import com.airbnb.mvrx.FragmentViewModelContext
 import com.airbnb.mvrx.MvRxViewModelFactory
 import com.airbnb.mvrx.ViewModelContext
+import com.squareup.inject.assisted.Assisted
+import com.squareup.inject.assisted.AssistedInject
 import im.vector.app.core.di.HasScreenInjector
 import im.vector.app.core.platform.EmptyAction
 import im.vector.app.core.platform.EmptyViewEvents
 import im.vector.app.core.platform.VectorViewModel
+import im.vector.app.features.userdirectory.KnownUsersFragment
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+import org.matrix.android.sdk.api.extensions.tryThis
+import org.matrix.android.sdk.api.raw.RawService
+import org.matrix.android.sdk.api.session.Session
 import org.matrix.android.sdk.api.session.homeserver.HomeServerCapabilities
+import org.matrix.android.sdk.internal.util.awaitCallback
 
-class HomeServerCapabilitiesViewModel(initialState: HomeServerCapabilitiesViewState)
-    : VectorViewModel<HomeServerCapabilitiesViewState, EmptyAction, EmptyViewEvents>(initialState) {
+class HomeServerCapabilitiesViewModel @AssistedInject constructor(
+        @Assisted initialState: HomeServerCapabilitiesViewState,
+        private val session: Session,
+        private val rawService: RawService
+) : VectorViewModel<HomeServerCapabilitiesViewState, EmptyAction, EmptyViewEvents>(initialState) {
+
+    @AssistedInject.Factory
+    interface Factory {
+        fun create(initialState: HomeServerCapabilitiesViewState): HomeServerCapabilitiesViewModel
+    }
 
     companion object : MvRxViewModelFactory<HomeServerCapabilitiesViewModel, HomeServerCapabilitiesViewState> {
+        @JvmStatic
+        override fun create(viewModelContext: ViewModelContext, state: HomeServerCapabilitiesViewState): HomeServerCapabilitiesViewModel? {
+            val fragment: KnownUsersFragment = (viewModelContext as FragmentViewModelContext).fragment()
+            return fragment.homeServerCapabilitiesViewModelFactory.create(state)
+        }
 
         override fun initialState(viewModelContext: ViewModelContext): HomeServerCapabilitiesViewState? {
             val session = (viewModelContext.activity as HasScreenInjector).injector().activeSessionHolder().getSafeActiveSession()
@@ -37,5 +61,26 @@ class HomeServerCapabilitiesViewModel(initialState: HomeServerCapabilitiesViewSt
         }
     }
 
+    init {
+        initAdminE2eByDefault()
+    }
+
+    private fun initAdminE2eByDefault() {
+        viewModelScope.launch(Dispatchers.IO) {
+            val adminE2EByDefault = tryThis {
+                awaitCallback<String> { rawService.getWellknown(session.myUserId, it) }
+                        .let { ElementWellKnownMapper.from(it) }
+                        ?.isE2EByDefault()
+                        ?: true
+            } ?: true
+
+            setState {
+                copy(
+                        isE2EByDefault = adminE2EByDefault
+                )
+            }
+        }
+    }
+
     override fun handle(action: EmptyAction) {}
 }
diff --git a/vector/src/main/java/im/vector/app/features/homeserver/HomeServerCapabilitiesViewState.kt b/vector/src/main/java/im/vector/app/features/homeserver/HomeServerCapabilitiesViewState.kt
index 98df020b6b..14d19b2e6a 100644
--- a/vector/src/main/java/im/vector/app/features/homeserver/HomeServerCapabilitiesViewState.kt
+++ b/vector/src/main/java/im/vector/app/features/homeserver/HomeServerCapabilitiesViewState.kt
@@ -20,5 +20,6 @@ import com.airbnb.mvrx.MvRxState
 import org.matrix.android.sdk.api.session.homeserver.HomeServerCapabilities
 
 data class HomeServerCapabilitiesViewState(
-        val capabilities: HomeServerCapabilities = HomeServerCapabilities()
+        val capabilities: HomeServerCapabilities = HomeServerCapabilities(),
+        val isE2EByDefault: Boolean = true
 ) : MvRxState
diff --git a/vector/src/main/java/im/vector/app/features/homeserver/WellKnownExt.kt b/vector/src/main/java/im/vector/app/features/homeserver/WellKnownExt.kt
new file mode 100644
index 0000000000..f5fbee29f5
--- /dev/null
+++ b/vector/src/main/java/im/vector/app/features/homeserver/WellKnownExt.kt
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2020 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.app.features.homeserver
+
+import com.squareup.moshi.Json
+import com.squareup.moshi.JsonAdapter
+import com.squareup.moshi.JsonClass
+import org.matrix.android.sdk.internal.di.MoshiProvider
+
+@JsonClass(generateAdapter = true)
+data class ElementWellKnown(
+        /**
+         *Preferred Jitsi domain, provided in Wellknown
+         */
+        @Json(name = "im.vector.riot.jitsi")
+        val jitsiServer: WellKnownPreferredConfig? = null,
+
+        /**
+         * The settings above were first proposed under a im.vector.riot.e2ee key, which is now deprecated.
+         * Element will check for either key, preferring io.element.e2ee if both exist.
+         */
+        @Json(name = "io.element.e2ee")
+        val elementE2E: E2EWellKnownConfig? = null,
+
+        @Json(name = "im.vector.riot.e2ee")
+        val riotE2E: E2EWellKnownConfig? = null
+)
+
+object ElementWellKnownMapper {
+
+    val adapter: JsonAdapter<ElementWellKnown> = MoshiProvider.providesMoshi().adapter(ElementWellKnown::class.java)
+
+    fun from(value: String): ElementWellKnown? {
+        return adapter.fromJson(value)
+    }
+}
+
+@JsonClass(generateAdapter = true)
+data class E2EWellKnownConfig(
+        /**
+         * Option to allow homeserver admins to set the default E2EE behaviour back to disabled for DMs / private rooms
+         * (as it was before) for various environments where this is desired.
+         */
+        @Json(name = "default")
+        val e2eDefault: Boolean? = null
+)
+
+@JsonClass(generateAdapter = true)
+data class WellKnownPreferredConfig(
+        @Json(name = "preferredDomain")
+        val preferredDomain: String? = null
+)
+
+fun ElementWellKnown.isE2EByDefault() = elementE2E?.e2eDefault ?: riotE2E?.e2eDefault ?: true
diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomViewModel.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomViewModel.kt
index a9c507ba7a..23cd9797b9 100644
--- a/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomViewModel.kt
@@ -17,6 +17,7 @@
 package im.vector.app.features.roomdirectory.createroom
 
 import androidx.fragment.app.FragmentActivity
+import androidx.lifecycle.viewModelScope
 import com.airbnb.mvrx.ActivityViewModelContext
 import com.airbnb.mvrx.Fail
 import com.airbnb.mvrx.Loading
@@ -27,15 +28,23 @@ import com.squareup.inject.assisted.Assisted
 import com.squareup.inject.assisted.AssistedInject
 import im.vector.app.core.platform.EmptyViewEvents
 import im.vector.app.core.platform.VectorViewModel
+import im.vector.app.features.homeserver.ElementWellKnownMapper
+import im.vector.app.features.homeserver.isE2EByDefault
 import im.vector.app.features.roomdirectory.RoomDirectoryActivity
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
 import org.matrix.android.sdk.api.MatrixCallback
+import org.matrix.android.sdk.api.extensions.tryThis
+import org.matrix.android.sdk.api.raw.RawService
 import org.matrix.android.sdk.api.session.Session
 import org.matrix.android.sdk.api.session.room.model.RoomDirectoryVisibility
 import org.matrix.android.sdk.api.session.room.model.create.CreateRoomParams
 import org.matrix.android.sdk.api.session.room.model.create.CreateRoomPreset
+import org.matrix.android.sdk.internal.util.awaitCallback
 
 class CreateRoomViewModel @AssistedInject constructor(@Assisted initialState: CreateRoomViewState,
-                                                      private val session: Session
+                                                      private val session: Session,
+                                                      private val rawService: RawService
 ) : VectorViewModel<CreateRoomViewState, CreateRoomAction, EmptyViewEvents>(initialState) {
 
     @AssistedInject.Factory
@@ -44,11 +53,26 @@ class CreateRoomViewModel @AssistedInject constructor(@Assisted initialState: Cr
     }
 
     init {
-        setState {
-            copy(
-                    isEncrypted = !this.isPublic && session.getHomeServerCapabilities().adminE2EByDefault,
-                    hsAdminHasDisabledE2E = !session.getHomeServerCapabilities().adminE2EByDefault
-            )
+        initAdminE2eByDefault()
+    }
+
+    private var adminE2EByDefault = true
+
+    private fun initAdminE2eByDefault() {
+        viewModelScope.launch(Dispatchers.IO) {
+            adminE2EByDefault = tryThis {
+                awaitCallback<String> { rawService.getWellknown(session.myUserId, it) }
+                        .let { ElementWellKnownMapper.from(it) }
+                        ?.isE2EByDefault()
+                        ?: true
+            } ?: true
+
+            setState {
+                copy(
+                        isEncrypted = !isPublic && adminE2EByDefault,
+                        hsAdminHasDisabledE2E = !adminE2EByDefault
+                )
+            }
         }
     }
 
@@ -81,7 +105,7 @@ class CreateRoomViewModel @AssistedInject constructor(@Assisted initialState: Cr
     private fun setIsPublic(action: CreateRoomAction.SetIsPublic) = setState {
         copy(
                 isPublic = action.isPublic,
-                isEncrypted = !action.isPublic && session.getHomeServerCapabilities().adminE2EByDefault
+                isEncrypted = !action.isPublic && adminE2EByDefault
         )
     }
 
diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsSecurityPrivacyFragment.kt b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsSecurityPrivacyFragment.kt
index 2dc35fb653..4508836da1 100644
--- a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsSecurityPrivacyFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsSecurityPrivacyFragment.kt
@@ -51,6 +51,8 @@ import im.vector.app.features.crypto.keys.KeysExporter
 import im.vector.app.features.crypto.keys.KeysImporter
 import im.vector.app.features.crypto.keysbackup.settings.KeysBackupManageActivity
 import im.vector.app.features.crypto.recover.BootstrapBottomSheet
+import im.vector.app.features.homeserver.ElementWellKnownMapper
+import im.vector.app.features.homeserver.isE2EByDefault
 import im.vector.app.features.navigation.Navigator
 import im.vector.app.features.pin.PinActivity
 import im.vector.app.features.pin.PinCodeStore
@@ -151,8 +153,14 @@ class VectorSettingsSecurityPrivacyFragment @Inject constructor(
                     disposables.add(it)
                 }
 
-        val e2eByDefault = session.getHomeServerCapabilities().adminE2EByDefault
-        findPreference<VectorPreference>(VectorPreferences.SETTINGS_CRYPTOGRAPHY_HS_ADMIN_DISABLED_E2E_DEFAULT)?.isVisible = !e2eByDefault
+        vectorActivity.getVectorComponent()
+                .rawService()
+                .getWellknown(session.myUserId, object : MatrixCallback<String> {
+            override fun onSuccess(data: String) {
+                findPreference<VectorPreference>(VectorPreferences.SETTINGS_CRYPTOGRAPHY_HS_ADMIN_DISABLED_E2E_DEFAULT)?.isVisible =
+                        ElementWellKnownMapper.from(data)?.isE2EByDefault() == false
+            }
+        })
     }
 
     private val secureBackupCategory by lazy {
@@ -273,8 +281,6 @@ class VectorSettingsSecurityPrivacyFragment @Inject constructor(
                 text = getString(R.string.settings_hs_admin_e2e_disabled)
                 textColor = ContextCompat.getColor(requireContext(), R.color.riotx_destructive_accent)
             }
-
-            it.isVisible = session.getHomeServerCapabilities().adminE2EByDefault
         }
     }
 
diff --git a/vector/src/main/java/im/vector/app/features/userdirectory/KnownUsersFragment.kt b/vector/src/main/java/im/vector/app/features/userdirectory/KnownUsersFragment.kt
index 07c77bfdd4..c832fe4833 100644
--- a/vector/src/main/java/im/vector/app/features/userdirectory/KnownUsersFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/userdirectory/KnownUsersFragment.kt
@@ -29,7 +29,6 @@ import com.airbnb.mvrx.fragmentViewModel
 import com.airbnb.mvrx.withState
 import com.google.android.material.chip.Chip
 import com.jakewharton.rxbinding3.widget.textChanges
-import org.matrix.android.sdk.api.session.user.model.User
 import im.vector.app.R
 import im.vector.app.core.extensions.cleanup
 import im.vector.app.core.extensions.configureWith
@@ -39,12 +38,14 @@ import im.vector.app.core.platform.VectorBaseFragment
 import im.vector.app.core.utils.DimensionConverter
 import im.vector.app.features.homeserver.HomeServerCapabilitiesViewModel
 import kotlinx.android.synthetic.main.fragment_known_users.*
+import org.matrix.android.sdk.api.session.user.model.User
 import javax.inject.Inject
 
 class KnownUsersFragment @Inject constructor(
         val userDirectoryViewModelFactory: UserDirectoryViewModel.Factory,
         private val knownUsersController: KnownUsersController,
-        private val dimensionConverter: DimensionConverter
+        private val dimensionConverter: DimensionConverter,
+        val homeServerCapabilitiesViewModelFactory: HomeServerCapabilitiesViewModel.Factory
 ) : VectorBaseFragment(), KnownUsersController.Callback {
 
     private val args: KnownUsersFragmentArgs by args()
@@ -71,7 +72,7 @@ class KnownUsersFragment @Inject constructor(
         setupCloseView()
 
         homeServerCapabilitiesViewModel.subscribe {
-            knownUsersE2EbyDefaultDisabled.isVisible = !it.capabilities.adminE2EByDefault
+            knownUsersE2EbyDefaultDisabled.isVisible = !it.isE2EByDefault
         }
 
         viewModel.selectSubscribe(this, UserDirectoryViewState::pendingInvitees) {