diff --git a/.idea/dictionaries/bmarty.xml b/.idea/dictionaries/bmarty.xml
index 7e9a9e1b03..1f93d1feee 100644
--- a/.idea/dictionaries/bmarty.xml
+++ b/.idea/dictionaries/bmarty.xml
@@ -25,6 +25,7 @@
       <w>signup</w>
       <w>ssss</w>
       <w>threepid</w>
+      <w>unwedging</w>
     </words>
   </dictionary>
 </component>
\ No newline at end of file
diff --git a/.travis.yml b/.travis.yml
index 6b9e9f9946..85bddac7f3 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -23,10 +23,10 @@ android:
     - platform-tools
 
     # The BuildTools version used by your project
-    - build-tools-28.0.3
+    - build-tools-29.0.3
 
     # The SDK version used to compile your project
-    - android-28
+    - android-29
 
 before_cache:
   - rm -f  $HOME/.gradle/caches/modules-2/modules-2.lock
diff --git a/CHANGES.md b/CHANGES.md
index 2bdef0f177..e4e0ae9df0 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -1,31 +1,14 @@
-Changes in RiotX 0.19.0 (2020-XX-XX)
+Changes in RiotX 0.20.0 (2020-XX-XX)
 ===================================================
 
 Features ✨:
- - Cross-Signing | Support SSSS secret sharing (#944)
- - Cross-Signing | Verify new session from existing session (#1134)
- - Cross-Signing | Bootstraping cross signing with 4S from mobile (#985)
-
+ -
 
 Improvements 🙌:
- - Verification DM / Handle concurrent .start after .ready (#794)
- - Cross-Signing | Update Shield Logic for DM (#963)
- - Cross-Signing | Complete security new session design update (#1135)
- - Cross-Signing | Setup key backup as part of SSSS bootstrapping (#1201)
- - Cross-Signing | Gossip key backup recovery key (#1200)
- - Show room encryption status as a bubble tile (#1078)
- - Cross-Signing | Restore history after recover from passphrase (#1214)
- - Cross-Sign | QR code scan confirmation screens design update (#1187)
- - Emoji Verification | It's not the same butterfly! (#1220)
  - Improve notification accessibility with ticker text (#1226)
 
 Bugfix 🐛:
- - Missing avatar/displayname after verification request message (#841)
- - Crypto | RiotX sometimes rotate the current device keys (#1170)
- - RiotX can't restore cross signing keys saved by web in SSSS (#1174)
- - Cross- Signing | After signin in new session, verification paper trail in DM is off (#1191)
- - Failed to encrypt message in room (message stays in red), [thanks to pwr22] (#925)
- - Cross-Signing | web <-> riotX After QR code scan, gossiping fails (#1210)
+ - Sometimes the same device appears twice in the list of devices of a user (#1329)
 
 Translations 🗣:
  -
@@ -37,6 +20,71 @@ Build 🧱:
  -
 
 Other changes:
+ -
+
+Changes in RiotX 0.19.0 (2020-05-04)
+===================================================
+
+Features ✨:
+ - Change password (#528)
+ - Cross-Signing | Support SSSS secret sharing (#944)
+ - Cross-Signing | Verify new session from existing session (#1134)
+ - Cross-Signing | Bootstraping cross signing with 4S from mobile (#985)
+ - Save media files to Gallery (#973)
+ - Account deactivation (with password only) (#35)
+
+Improvements 🙌:
+ - Verification DM / Handle concurrent .start after .ready (#794)
+ - Reimplementation of multiple attachment picker
+ - Cross-Signing | Update Shield Logic for DM (#963)
+ - Cross-Signing | Complete security new session design update (#1135)
+ - Cross-Signing | Setup key backup as part of SSSS bootstrapping (#1201)
+ - Cross-Signing | Gossip key backup recovery key (#1200)
+ - Show room encryption status as a bubble tile (#1078)
+ - UX/UI | Add indicator to home tab on invite (#957)
+ - Cross-Signing | Restore history after recover from passphrase (#1214)
+ - Cross-Sign | QR code scan confirmation screens design update (#1187)
+ - Emoji Verification | It's not the same butterfly! (#1220)
+ - Cross-Signing | Composer decoration: shields (#1077)
+ - Cross-Signing | Migrate existing keybackup to cross signing with 4S from mobile (#1197)
+ - Show a warning dialog if the text of the clicked link does not match the link target (#922)
+ - Cross-Signing | Consider not using a spinner on the 'complete security' prompt (#1271)
+ - Restart broken Olm sessions ([MSC1719](https://github.com/matrix-org/matrix-doc/pull/1719))
+ - Cross-Signing | Hide Use recovery key when 4S is not setup (#1007)
+ - Cross-Signing | Trust account xSigning keys by entering Recovery Key (select file or copy) #1199
+ - E2E timeline decoration (#1279)
+ - Manage Session Settings / Cross Signing update (#1295)
+ - Cross-Signing | Review sessions toast update old vs new (#1293, #1306)
+
+Bugfix 🐛:
+ - Fix summary notification staying after "mark as read"
+ - Missing avatar/displayname after verification request message (#841)
+ - Crypto | RiotX sometimes rotate the current device keys (#1170)
+ - RiotX can't restore cross signing keys saved by web in SSSS (#1174)
+ - Cross- Signing | After signin in new session, verification paper trail in DM is off (#1191)
+ - Failed to encrypt message in room (message stays in red), [thanks to pwr22] (#925)
+ - Cross-Signing | web <-> riotX After QR code scan, gossiping fails (#1210)
+ - Fix crash when trying to download file without internet connection (#1229)
+ - Local echo are not updated in timeline (for failed & encrypted states)
+ - Render image event even if thumbnail_info does not have mimetype defined (#1209)
+ - RiotX now uses as many threads as it needs to do work and send messages (#1221)
+ - Fix issue with media path (#1227)
+ - Add user to direct chat by user id (#1065)
+ - Use correct URL for SSO connection (#1178)
+ - Emoji completion :tada: does not completes to 🎉 like on web (#1285)
+ - Fix bad Shield Logic for DM (#963)
+
+Translations 🗣:
+ - Weblate now create PR directly to RiotX GitHub project
+
+SDK API changes ⚠️:
+ - Increase targetSdkVersion to 29
+
+Build 🧱:
+ - Compile with Android SDK 29 (Android Q)
+
+Other changes:
+ - Add a setting to prevent screenshots of the application, disabled by default (#1027)
  - Increase File Logger capacities ( + use dev log preferences)
 
 Changes in RiotX 0.18.1 (2020-03-17)
@@ -445,6 +493,7 @@ Bugfix:
  - Fix messages with empty `in_reply_to` not rendering (#447)
  - Fix clear cache (#408) and Logout (#205)
  - Fix `(edited)` link can be copied to clipboard (#402)
+ - KeyBackup / SSSS | Should get the key from SSSS instead of asking recovery Key (#1163)
 
 Build:
  - Split APK: generate one APK per arch, to reduce APK size of about 30%
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 176a6ee9c1..b36843adee 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -13,6 +13,24 @@ Dedicated room for RiotX: [![RiotX Android Matrix room #riot-android:matrix.org]
 Please set the "hard wrap" setting of Android Studio to 160 chars, this is the setting we use internally to format the source code (Menu `Settings/Editor/Code Style` then `Hard wrap at`).
 Please ensure that your using the project formatting rules (which are in the project at .idea/codeStyles/), and format the file before committing them.
 
+### Template
+
+An Android Studio template has been added to the project to help creating all files needed when adding a new screen to the application. Fragment, ViewModel, Activity, etc.
+
+To install the template (to be done only once):
+- Go to folder `./tools/template`.
+- Run the script `./configure.sh`.
+- Restart Android Studio.
+
+To create a new screen:
+- First create a new package in your code.
+- Then right click on the package, and select `New/New Vector/RiotX Feature`.
+- Follow the Wizard, especially replace `Main` by something more relevant to your feature.
+- Click on `Finish`.
+- Remainning steps are described as TODO in the generated files, or will be pointed out by the compilator, or at runtime :)
+
+Note that if the templates are modified, the only things to do is to restart Android Studio for the change to take effect.
+
 ## Compilation
 
 For now, the Matrix SDK and the RiotX application are in the same project. So there is no specific thing to do, this project should compile without any special action.
diff --git a/docs/notifications.md b/docs/notifications.md
index 328eb86954..8efcb87bf3 100644
--- a/docs/notifications.md
+++ b/docs/notifications.md
@@ -38,10 +38,10 @@ When the client receives the new information, it immediately sends another reque
 This effectively emulates a server push feature.
 
 The HTTP long Polling can be fine tuned in the **SDK** using two parameters:
-* timout (Sync request timeout)
+* timeout (Sync request timeout)
 * delay (Delay between each sync)
 
-**timeout** is a server paramter, defined by:
+**timeout** is a server parameter, defined by:
 ```
 The maximum time to wait, in milliseconds, before returning this request.`
 If no events (or other data) become available before this time elapses, the server will return a response with empty fields.
diff --git a/docs/signin.md b/docs/signin.md
index 245ea444f6..e7368137ae 100644
--- a/docs/signin.md
+++ b/docs/signin.md
@@ -57,7 +57,7 @@ We get credential (200)
 
 ```json
 {
-  "user_id": "@benoit0816:matrix.org",
+  "user_id": "@alice:matrix.org",
   "access_token": "MDAxOGxvY2F0aW9uIG1hdHREDACTEDb2l0MDgxNjptYXRyaXgub3JnCjAwMTZjaWQgdHlwZSA9IGFjY2VzcwowMDIxY2lkIG5vbmNlID0gfnYrSypfdTtkNXIuNWx1KgowMDJmc2lnbmF0dXJlIOsh1XqeAkXexh4qcofl_aR4kHJoSOWYGOhE7-ubX-DZCg",
   "home_server": "matrix.org",
   "device_id": "GTVREDALBF",
@@ -128,6 +128,8 @@ We get the credentials (200)
 }
 ```
 
+It's worth noting that the response from the homeserver contains the userId of Alice.
+
 ### Login with Msisdn
 
 Not supported yet in RiotX
diff --git a/matrix-sdk-android-rx/build.gradle b/matrix-sdk-android-rx/build.gradle
index 8907ee8b50..734ff0c130 100644
--- a/matrix-sdk-android-rx/build.gradle
+++ b/matrix-sdk-android-rx/build.gradle
@@ -3,11 +3,11 @@ apply plugin: 'kotlin-android'
 apply plugin: 'kotlin-kapt'
 
 android {
-    compileSdkVersion 28
+    compileSdkVersion 29
 
     defaultConfig {
         minSdkVersion 16
-        targetSdkVersion 28
+        targetSdkVersion 29
         versionCode 1
         versionName "1.0"
 
diff --git a/matrix-sdk-android-rx/src/main/java/im/vector/matrix/rx/RxSession.kt b/matrix-sdk-android-rx/src/main/java/im/vector/matrix/rx/RxSession.kt
index 87ff6f0390..c2c8978500 100644
--- a/matrix-sdk-android-rx/src/main/java/im/vector/matrix/rx/RxSession.kt
+++ b/matrix-sdk-android-rx/src/main/java/im/vector/matrix/rx/RxSession.kt
@@ -31,6 +31,8 @@ import im.vector.matrix.android.api.util.JsonDict
 import im.vector.matrix.android.api.util.Optional
 import im.vector.matrix.android.api.util.toOptional
 import im.vector.matrix.android.internal.crypto.model.CryptoDeviceInfo
+import im.vector.matrix.android.internal.crypto.model.rest.DeviceInfo
+import im.vector.matrix.android.internal.crypto.store.PrivateKeysInfo
 import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataEvent
 import io.reactivex.Observable
 import io.reactivex.Single
@@ -58,6 +60,13 @@ class RxSession(private val session: Session) {
                 }
     }
 
+    fun liveMyDeviceInfo(): Observable<List<DeviceInfo>> {
+        return session.cryptoService().getLiveMyDevicesInfo().asObservable()
+                .startWithCallable {
+                    session.cryptoService().getMyDevicesInfo()
+                }
+    }
+
     fun liveSyncState(): Observable<SyncState> {
         return session.getSyncStateLive().asObservable()
     }
@@ -123,6 +132,13 @@ class RxSession(private val session: Session) {
                 }
     }
 
+    fun liveCrossSigningPrivateKeys(): Observable<Optional<PrivateKeysInfo>> {
+        return session.cryptoService().crossSigningService().getLiveCrossSigningPrivateKeys().asObservable()
+                .startWithCallable {
+                    session.cryptoService().crossSigningService().getCrossSigningPrivateKeys().toOptional()
+                }
+    }
+
     fun liveAccountData(types: Set<String>): Observable<List<UserAccountDataEvent>> {
         return session.getLiveAccountDataEvents(types).asObservable()
                 .startWithCallable {
diff --git a/matrix-sdk-android/build.gradle b/matrix-sdk-android/build.gradle
index ca6c2ce6d9..514d1accae 100644
--- a/matrix-sdk-android/build.gradle
+++ b/matrix-sdk-android/build.gradle
@@ -19,12 +19,12 @@ androidExtensions {
 }
 
 android {
-    compileSdkVersion 28
+    compileSdkVersion 29
     testOptions.unitTests.includeAndroidResources = true
 
     defaultConfig {
         minSdkVersion 16
-        targetSdkVersion 28
+        targetSdkVersion 29
         versionCode 1
         versionName "0.0.1"
         // Multidex is useful for tests
@@ -71,6 +71,15 @@ android {
     kotlinOptions {
         jvmTarget = "1.8"
     }
+
+    sourceSets {
+        androidTest {
+            java.srcDirs += "src/sharedTest/java"
+        }
+        test {
+            java.srcDirs += "src/sharedTest/java"
+        }
+    }
 }
 
 static def gitRevision() {
@@ -160,6 +169,8 @@ dependencies {
     testImplementation 'io.mockk:mockk:1.9.2.kotlin12'
     testImplementation 'org.amshove.kluent:kluent-android:1.44'
     testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines_version"
+    // Plant Timber tree for test
+    testImplementation 'net.lachlanmckee:timber-junit-rule:1.0.1'
 
     androidTestImplementation 'androidx.test:core:1.2.0'
     androidTestImplementation 'androidx.test:runner:1.2.0'
@@ -171,5 +182,6 @@ dependencies {
     androidTestImplementation 'io.mockk:mockk-android:1.9.2.kotlin12'
     androidTestImplementation "androidx.arch.core:core-testing:$arch_version"
     androidTestImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines_version"
-
+    // Plant Timber tree for test
+    androidTestImplementation 'net.lachlanmckee:timber-junit-rule:1.0.1'
 }
diff --git a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/InstrumentedTest.kt b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/InstrumentedTest.kt
index 56b358c69f..374a1fc399 100644
--- a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/InstrumentedTest.kt
+++ b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/InstrumentedTest.kt
@@ -18,10 +18,15 @@ package im.vector.matrix.android
 
 import android.content.Context
 import androidx.test.core.app.ApplicationProvider
+import im.vector.matrix.android.test.shared.createTimberTestRule
+import org.junit.Rule
 import java.io.File
 
 interface InstrumentedTest {
 
+    @Rule
+    fun timberTestRule() = createTimberTestRule()
+
     fun context(): Context {
         return ApplicationProvider.getApplicationContext()
     }
diff --git a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/account/ChangePasswordTest.kt b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/account/ChangePasswordTest.kt
new file mode 100644
index 0000000000..2574700d49
--- /dev/null
+++ b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/account/ChangePasswordTest.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 im.vector.matrix.android.account
+
+import im.vector.matrix.android.InstrumentedTest
+import im.vector.matrix.android.api.failure.isInvalidPassword
+import im.vector.matrix.android.common.CommonTestHelper
+import im.vector.matrix.android.common.SessionTestParams
+import im.vector.matrix.android.common.TestConstants
+import org.amshove.kluent.shouldBeTrue
+import org.junit.FixMethodOrder
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+import org.junit.runners.MethodSorters
+
+@RunWith(JUnit4::class)
+@FixMethodOrder(MethodSorters.JVM)
+class ChangePasswordTest : InstrumentedTest {
+
+    private val commonTestHelper = CommonTestHelper(context())
+
+    companion object {
+        private const val NEW_PASSWORD = "this is a new password"
+    }
+
+    @Test
+    fun changePasswordTest() {
+        val session = commonTestHelper.createAccount(TestConstants.USER_ALICE, SessionTestParams(withInitialSync = false))
+
+        // Change password
+        commonTestHelper.doSync<Unit> {
+            session.changePassword(TestConstants.PASSWORD, NEW_PASSWORD, it)
+        }
+
+        // Try to login with the previous password, it will fail
+        val throwable = commonTestHelper.logAccountWithError(session.myUserId, TestConstants.PASSWORD)
+        throwable.isInvalidPassword().shouldBeTrue()
+
+        // Try to login with the new password, should work
+        val session2 = commonTestHelper.logIntoAccount(session.myUserId, NEW_PASSWORD, SessionTestParams(withInitialSync = false))
+
+        commonTestHelper.signOutAndClose(session)
+        commonTestHelper.signOutAndClose(session2)
+    }
+}
diff --git a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/account/DeactivateAccountTest.kt b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/account/DeactivateAccountTest.kt
new file mode 100644
index 0000000000..17ff984bc8
--- /dev/null
+++ b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/account/DeactivateAccountTest.kt
@@ -0,0 +1,88 @@
+/*
+ * 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.matrix.android.account
+
+import im.vector.matrix.android.InstrumentedTest
+import im.vector.matrix.android.api.auth.data.LoginFlowResult
+import im.vector.matrix.android.api.auth.registration.RegistrationResult
+import im.vector.matrix.android.api.failure.Failure
+import im.vector.matrix.android.api.failure.MatrixError
+import im.vector.matrix.android.common.CommonTestHelper
+import im.vector.matrix.android.common.SessionTestParams
+import im.vector.matrix.android.common.TestConstants
+import im.vector.matrix.android.common.TestMatrixCallback
+import org.junit.Assert.assertTrue
+import org.junit.FixMethodOrder
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+import org.junit.runners.MethodSorters
+
+@RunWith(JUnit4::class)
+@FixMethodOrder(MethodSorters.JVM)
+class DeactivateAccountTest : InstrumentedTest {
+
+    private val commonTestHelper = CommonTestHelper(context())
+
+    @Test
+    fun deactivateAccountTest() {
+        val session = commonTestHelper.createAccount(TestConstants.USER_ALICE, SessionTestParams(withInitialSync = false))
+
+        // Deactivate the account
+        commonTestHelper.doSync<Unit> {
+            session.deactivateAccount(TestConstants.PASSWORD, false, it)
+        }
+
+        // Try to login on the previous account, it will fail (M_USER_DEACTIVATED)
+        val throwable = commonTestHelper.logAccountWithError(session.myUserId, TestConstants.PASSWORD)
+
+        // Test the error
+        assertTrue(throwable is Failure.ServerError
+                && throwable.error.code == MatrixError.M_USER_DEACTIVATED
+                && throwable.error.message == "This account has been deactivated")
+
+        // Try to create an account with the deactivate account user id, it will fail (M_USER_IN_USE)
+        val hs = commonTestHelper.createHomeServerConfig()
+
+        commonTestHelper.doSync<LoginFlowResult> {
+            commonTestHelper.matrix.authenticationService.getLoginFlow(hs, it)
+        }
+
+        var accountCreationError: Throwable? = null
+        commonTestHelper.waitWithLatch {
+            commonTestHelper.matrix.authenticationService
+                    .getRegistrationWizard()
+                    .createAccount(session.myUserId.substringAfter("@").substringBefore(":"),
+                            TestConstants.PASSWORD,
+                            null,
+                            object : TestMatrixCallback<RegistrationResult>(it, false) {
+                                override fun onFailure(failure: Throwable) {
+                                    accountCreationError = failure
+                                    super.onFailure(failure)
+                                }
+                            })
+        }
+
+        // Test the error
+        accountCreationError.let {
+            assertTrue(it is Failure.ServerError
+                    && it.error.code == MatrixError.M_USER_IN_USE)
+        }
+
+        // No need to close the session, it has been deactivated
+    }
+}
diff --git a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/common/CommonTestHelper.kt b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/common/CommonTestHelper.kt
index 3cf03fff53..5bc8653f3d 100644
--- a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/common/CommonTestHelper.kt
+++ b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/common/CommonTestHelper.kt
@@ -183,9 +183,9 @@ class CommonTestHelper(context: Context) {
      * @param testParams test params about the session
      * @return the session associated with the existing account
      */
-    private fun logIntoAccount(userId: String,
-                               password: String,
-                               testParams: SessionTestParams): Session {
+    fun logIntoAccount(userId: String,
+                       password: String,
+                       testParams: SessionTestParams): Session {
         val session = logAccountAndSync(userId, password, testParams)
         assertNotNull(session)
         return session
@@ -260,14 +260,45 @@ class CommonTestHelper(context: Context) {
         return session
     }
 
+    /**
+     * Log into the account and expect an error
+     *
+     * @param userName the account username
+     * @param password the password
+     */
+    fun logAccountWithError(userName: String,
+                            password: String): Throwable {
+        val hs = createHomeServerConfig()
+
+        doSync<LoginFlowResult> {
+            matrix.authenticationService
+                    .getLoginFlow(hs, it)
+        }
+
+        var requestFailure: Throwable? = null
+        waitWithLatch { latch ->
+            matrix.authenticationService
+                    .getLoginWizard()
+                    .login(userName, password, "myDevice", object : TestMatrixCallback<Session>(latch, onlySuccessful = false) {
+                        override fun onFailure(failure: Throwable) {
+                            requestFailure = failure
+                            super.onFailure(failure)
+                        }
+                    })
+        }
+
+        assertNotNull(requestFailure)
+        return requestFailure!!
+    }
+
     /**
      * Await for a latch and ensure the result is true
      *
      * @param latch
      * @throws InterruptedException
      */
-    fun await(latch: CountDownLatch, timout: Long? = TestConstants.timeOutMillis) {
-        assertTrue(latch.await(timout ?: TestConstants.timeOutMillis, TimeUnit.MILLISECONDS))
+    fun await(latch: CountDownLatch, timeout: Long? = TestConstants.timeOutMillis) {
+        assertTrue(latch.await(timeout ?: TestConstants.timeOutMillis, TimeUnit.MILLISECONDS))
     }
 
     fun retryPeriodicallyWithLatch(latch: CountDownLatch, condition: (() -> Boolean)) {
@@ -282,10 +313,10 @@ class CommonTestHelper(context: Context) {
         }
     }
 
-    fun waitWithLatch(timout: Long? = TestConstants.timeOutMillis, block: (CountDownLatch) -> Unit) {
+    fun waitWithLatch(timeout: Long? = TestConstants.timeOutMillis, block: (CountDownLatch) -> Unit) {
         val latch = CountDownLatch(1)
         block(latch)
-        await(latch, timout)
+        await(latch, timeout)
     }
 
     // Transform a method with a MatrixCallback to a synchronous method
diff --git a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/common/CryptoTestHelper.kt b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/common/CryptoTestHelper.kt
index 826c70a63f..9278bed918 100644
--- a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/common/CryptoTestHelper.kt
+++ b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/common/CryptoTestHelper.kt
@@ -22,6 +22,7 @@ import im.vector.matrix.android.api.session.Session
 import im.vector.matrix.android.api.session.events.model.Event
 import im.vector.matrix.android.api.session.events.model.EventType
 import im.vector.matrix.android.api.session.events.model.toContent
+import im.vector.matrix.android.api.session.room.Room
 import im.vector.matrix.android.api.session.room.model.Membership
 import im.vector.matrix.android.api.session.room.model.RoomSummary
 import im.vector.matrix.android.api.session.room.model.create.CreateRoomParams
@@ -40,8 +41,6 @@ import kotlinx.coroutines.runBlocking
 import org.junit.Assert.assertEquals
 import org.junit.Assert.assertNotNull
 import org.junit.Assert.assertNull
-import org.junit.Assert.assertTrue
-import java.util.HashMap
 import java.util.concurrent.CountDownLatch
 
 class CryptoTestHelper(private val mTestHelper: CommonTestHelper) {
@@ -140,64 +139,38 @@ class CryptoTestHelper(private val mTestHelper: CommonTestHelper) {
      * @return Alice, Bob and Sam session
      */
     fun doE2ETestWithAliceAndBobAndSamInARoom(): CryptoTestData {
-        val statuses = HashMap<String, String>()
-
         val cryptoTestData = doE2ETestWithAliceAndBobInARoom()
         val aliceSession = cryptoTestData.firstSession
         val aliceRoomId = cryptoTestData.roomId
 
         val room = aliceSession.getRoom(aliceRoomId)!!
 
-        val samSession = mTestHelper.createAccount(TestConstants.USER_SAM, defaultSessionParams)
-
-        val lock1 = CountDownLatch(2)
-
-//        val samEventListener = object : MXEventListener() {
-//            override fun onNewRoom(roomId: String) {
-//                if (TextUtils.equals(roomId, aliceRoomId)) {
-//                    if (!statuses.containsKey("onNewRoom")) {
-//                        statuses["onNewRoom"] = "onNewRoom"
-//                        lock1.countDown()
-//                    }
-//                }
-//            }
-//        }
-//
-//        samSession.dataHandler.addListener(samEventListener)
-
-        room.invite(samSession.myUserId, null, object : TestMatrixCallback<Unit>(lock1) {
-            override fun onSuccess(data: Unit) {
-                statuses["invite"] = "invite"
-                super.onSuccess(data)
-            }
-        })
-
-        mTestHelper.await(lock1)
-
-        assertTrue(statuses.containsKey("invite") && statuses.containsKey("onNewRoom"))
-
-//        samSession.dataHandler.removeListener(samEventListener)
-
-        val lock2 = CountDownLatch(1)
-
-        samSession.joinRoom(aliceRoomId, null, object : TestMatrixCallback<Unit>(lock2) {
-            override fun onSuccess(data: Unit) {
-                statuses["joinRoom"] = "joinRoom"
-                super.onSuccess(data)
-            }
-        })
-
-        mTestHelper.await(lock2)
-        assertTrue(statuses.containsKey("joinRoom"))
+        val samSession = createSamAccountAndInviteToTheRoom(room)
 
         // wait the initial sync
         SystemClock.sleep(1000)
 
-//        samSession.dataHandler.removeListener(samEventListener)
-
         return CryptoTestData(aliceSession, aliceRoomId, cryptoTestData.secondSession, samSession)
     }
 
+    /**
+     * Create Sam account and invite him in the room. He will accept the invitation
+     * @Return Sam session
+     */
+    fun createSamAccountAndInviteToTheRoom(room: Room): Session {
+        val samSession = mTestHelper.createAccount(TestConstants.USER_SAM, defaultSessionParams)
+
+        mTestHelper.doSync<Unit> {
+            room.invite(samSession.myUserId, null, it)
+        }
+
+        mTestHelper.doSync<Unit> {
+            samSession.joinRoom(room.roomId, null, it)
+        }
+
+        return samSession
+    }
+
     /**
      * @return Alice and Bob sessions
      */
diff --git a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/CryptoStoreHelper.kt b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/CryptoStoreHelper.kt
index 6b0ebbf6a4..7b4020bf04 100644
--- a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/CryptoStoreHelper.kt
+++ b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/CryptoStoreHelper.kt
@@ -20,6 +20,8 @@ import im.vector.matrix.android.api.auth.data.Credentials
 import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore
 import im.vector.matrix.android.internal.crypto.store.db.RealmCryptoStore
 import im.vector.matrix.android.internal.crypto.store.db.RealmCryptoStoreModule
+import im.vector.matrix.android.internal.crypto.store.db.mapper.CrossSigningKeysMapper
+import im.vector.matrix.android.internal.di.MoshiProvider
 import io.realm.RealmConfiguration
 import kotlin.random.Random
 
@@ -31,6 +33,7 @@ internal class CryptoStoreHelper {
                         .name("test.realm")
                         .modules(RealmCryptoStoreModule())
                         .build(),
+                crossSigningKeysMapper = CrossSigningKeysMapper(MoshiProvider.providesMoshi()),
                 credentials = createCredential())
     }
 
diff --git a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/UnwedgingTest.kt b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/UnwedgingTest.kt
new file mode 100644
index 0000000000..6391c0392c
--- /dev/null
+++ b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/UnwedgingTest.kt
@@ -0,0 +1,247 @@
+/*
+ * 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.matrix.android.internal.crypto
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import im.vector.matrix.android.InstrumentedTest
+import im.vector.matrix.android.api.extensions.tryThis
+import im.vector.matrix.android.api.session.crypto.MXCryptoError
+import im.vector.matrix.android.api.session.events.model.EventType
+import im.vector.matrix.android.api.session.events.model.toModel
+import im.vector.matrix.android.api.session.room.timeline.Timeline
+import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
+import im.vector.matrix.android.api.session.room.timeline.TimelineSettings
+import im.vector.matrix.android.common.CommonTestHelper
+import im.vector.matrix.android.common.CryptoTestHelper
+import im.vector.matrix.android.common.TestConstants
+import im.vector.matrix.android.internal.crypto.model.OlmSessionWrapper
+import im.vector.matrix.android.internal.crypto.model.event.EncryptedEventContent
+import im.vector.matrix.android.internal.crypto.model.rest.UserPasswordAuth
+import im.vector.matrix.android.internal.crypto.store.db.deserializeFromRealm
+import im.vector.matrix.android.internal.crypto.store.db.serializeForRealm
+import org.amshove.kluent.shouldBe
+import org.junit.Assert
+import org.junit.Before
+import org.junit.FixMethodOrder
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.matrix.olm.OlmSession
+import timber.log.Timber
+import java.util.concurrent.CountDownLatch
+
+/**
+ * Ref:
+ * - https://github.com/matrix-org/matrix-doc/pull/1719
+ * - https://matrix.org/docs/spec/client_server/latest#recovering-from-undecryptable-messages
+ * - https://github.com/matrix-org/matrix-js-sdk/pull/780
+ * - https://github.com/matrix-org/matrix-ios-sdk/pull/778
+ * - https://github.com/matrix-org/matrix-ios-sdk/pull/784
+ */
+@RunWith(AndroidJUnit4::class)
+@FixMethodOrder(MethodSorters.JVM)
+class UnwedgingTest : InstrumentedTest {
+
+    private lateinit var messagesReceivedByBob: List<TimelineEvent>
+    private val mTestHelper = CommonTestHelper(context())
+    private val mCryptoTestHelper = CryptoTestHelper(mTestHelper)
+
+    @Before
+    fun init() {
+        messagesReceivedByBob = emptyList()
+    }
+
+    /**
+     * - Alice & Bob in a e2e room
+     * - Alice sends a 1st message with a 1st megolm session
+     * - Store the olm session between A&B devices
+     * - Alice sends a 2nd message with a 2nd megolm session
+     * - Simulate Alice using a backup of her OS and make her crypto state like after the first message
+     * - Alice sends a 3rd message with a 3rd megolm session but a wedged olm session
+     *
+     * What Bob must see:
+     * -> No issue with the 2 first messages
+     * -> The third event must fail to decrypt at first because Bob the olm session is wedged
+     * -> This is automatically fixed after SDKs restarted the olm session
+     */
+    @Test
+    fun testUnwedging() {
+        val cryptoTestData = mCryptoTestHelper.doE2ETestWithAliceAndBobInARoom()
+
+        val aliceSession = cryptoTestData.firstSession
+        val aliceRoomId = cryptoTestData.roomId
+        val bobSession = cryptoTestData.secondSession!!
+
+        val aliceCryptoStore = (aliceSession.cryptoService() as DefaultCryptoService).cryptoStoreForTesting
+
+        // bobSession.cryptoService().setWarnOnUnknownDevices(false)
+        // aliceSession.cryptoService().setWarnOnUnknownDevices(false)
+
+        val roomFromBobPOV = bobSession.getRoom(aliceRoomId)!!
+        val roomFromAlicePOV = aliceSession.getRoom(aliceRoomId)!!
+
+        val bobTimeline = roomFromBobPOV.createTimeline(null, TimelineSettings(20))
+        bobTimeline.start()
+
+        val bobFinalLatch = CountDownLatch(1)
+        val bobHasThreeDecryptedEventsListener = object : Timeline.Listener {
+            override fun onTimelineFailure(throwable: Throwable) {
+                // noop
+            }
+
+            override fun onNewTimelineEvents(eventIds: List<String>) {
+                // noop
+            }
+
+            override fun onTimelineUpdated(snapshot: List<TimelineEvent>) {
+                val decryptedEventReceivedByBob = snapshot.filter { it.root.type == EventType.ENCRYPTED }
+                Timber.d("Bob can now decrypt ${decryptedEventReceivedByBob.size} messages")
+                if (decryptedEventReceivedByBob.size == 3) {
+                    if (decryptedEventReceivedByBob[0].root.mCryptoError == MXCryptoError.ErrorType.UNKNOWN_INBOUND_SESSION_ID) {
+                        bobFinalLatch.countDown()
+                    }
+                }
+            }
+        }
+        bobTimeline.addListener(bobHasThreeDecryptedEventsListener)
+
+        var latch = CountDownLatch(1)
+        var bobEventsListener = createEventListener(latch, 1)
+        bobTimeline.addListener(bobEventsListener)
+        messagesReceivedByBob = emptyList()
+
+        // - Alice sends a 1st message with a 1st megolm session
+        roomFromAlicePOV.sendTextMessage("First message")
+
+        // Wait for the message to be received by Bob
+        mTestHelper.await(latch)
+        bobTimeline.removeListener(bobEventsListener)
+
+        messagesReceivedByBob.size shouldBe 1
+        val firstMessageSession = messagesReceivedByBob[0].root.content.toModel<EncryptedEventContent>()!!.sessionId!!
+
+        //  - Store the olm session between A&B devices
+        // Let us pickle our session with bob here so we can later unpickle it
+        // and wedge our session.
+        val sessionIdsForBob = aliceCryptoStore.getDeviceSessionIds(bobSession.cryptoService().getMyDevice().identityKey()!!)
+        sessionIdsForBob!!.size shouldBe 1
+        val olmSession = aliceCryptoStore.getDeviceSession(sessionIdsForBob.first(), bobSession.cryptoService().getMyDevice().identityKey()!!)!!
+
+        val oldSession = serializeForRealm(olmSession.olmSession)
+
+        aliceSession.cryptoService().discardOutboundSession(roomFromAlicePOV.roomId)
+        Thread.sleep(6_000)
+
+        latch = CountDownLatch(1)
+        bobEventsListener = createEventListener(latch, 2)
+        bobTimeline.addListener(bobEventsListener)
+        messagesReceivedByBob = emptyList()
+
+        Timber.i("## CRYPTO | testUnwedging:  Alice sends a 2nd message with a 2nd megolm session")
+        // - Alice sends a 2nd message with a 2nd megolm session
+        roomFromAlicePOV.sendTextMessage("Second message")
+
+        // Wait for the message to be received by Bob
+        mTestHelper.await(latch)
+        bobTimeline.removeListener(bobEventsListener)
+
+        messagesReceivedByBob.size shouldBe 2
+        // Session should have changed
+        val secondMessageSession = messagesReceivedByBob[0].root.content.toModel<EncryptedEventContent>()!!.sessionId!!
+        Assert.assertNotEquals(firstMessageSession, secondMessageSession)
+
+        // Let us wedge the session now. Set crypto state like after the first message
+        Timber.i("## CRYPTO | testUnwedging: wedge the session now. Set crypto state like after the first message")
+
+        aliceCryptoStore.storeSession(OlmSessionWrapper(deserializeFromRealm<OlmSession>(oldSession)!!), bobSession.cryptoService().getMyDevice().identityKey()!!)
+        Thread.sleep(6_000)
+
+        // Force new session, and key share
+        aliceSession.cryptoService().discardOutboundSession(roomFromAlicePOV.roomId)
+
+        // Wait for the message to be received by Bob
+        mTestHelper.waitWithLatch {
+            bobEventsListener = createEventListener(it, 3)
+            bobTimeline.addListener(bobEventsListener)
+            messagesReceivedByBob = emptyList()
+
+            Timber.i("## CRYPTO | testUnwedging: Alice sends a 3rd message with a 3rd megolm session but a wedged olm session")
+            // - Alice sends a 3rd message with a 3rd megolm session but a wedged olm session
+            roomFromAlicePOV.sendTextMessage("Third message")
+            // Bob should not be able to decrypt, because the session key could not be sent
+        }
+        bobTimeline.removeListener(bobEventsListener)
+
+        messagesReceivedByBob.size shouldBe 3
+
+        val thirdMessageSession = messagesReceivedByBob[0].root.content.toModel<EncryptedEventContent>()!!.sessionId!!
+        Timber.i("## CRYPTO | testUnwedging: third message session ID $thirdMessageSession")
+        Assert.assertNotEquals(secondMessageSession, thirdMessageSession)
+
+        Assert.assertEquals(EventType.ENCRYPTED, messagesReceivedByBob[0].root.getClearType())
+        Assert.assertEquals(EventType.MESSAGE, messagesReceivedByBob[1].root.getClearType())
+        Assert.assertEquals(EventType.MESSAGE, messagesReceivedByBob[2].root.getClearType())
+        // Bob Should not be able to decrypt last message, because session could not be sent as the olm channel was wedged
+        mTestHelper.await(bobFinalLatch)
+        bobTimeline.removeListener(bobHasThreeDecryptedEventsListener)
+
+        // It's a trick to force key request on fail to decrypt
+        mTestHelper.doSync<Unit> {
+            bobSession.cryptoService().crossSigningService()
+                    .initializeCrossSigning(UserPasswordAuth(
+                            user = bobSession.myUserId,
+                            password = TestConstants.PASSWORD
+                    ), it)
+        }
+
+        // Wait until we received back the key
+        mTestHelper.waitWithLatch {
+            mTestHelper.retryPeriodicallyWithLatch(it) {
+                // we should get back the key and be able to decrypt
+                val result = tryThis {
+                    bobSession.cryptoService().decryptEvent(messagesReceivedByBob[0].root, "")
+                }
+                Timber.i("## CRYPTO | testUnwedging: decrypt result  ${result?.clearEvent}")
+                result != null
+            }
+        }
+
+        bobTimeline.dispose()
+
+        cryptoTestData.cleanUp(mTestHelper)
+    }
+
+    private fun createEventListener(latch: CountDownLatch, expectedNumberOfMessages: Int): Timeline.Listener {
+        return object : Timeline.Listener {
+            override fun onTimelineFailure(throwable: Throwable) {
+                // noop
+            }
+
+            override fun onNewTimelineEvents(eventIds: List<String>) {
+                // noop
+            }
+
+            override fun onTimelineUpdated(snapshot: List<TimelineEvent>) {
+                messagesReceivedByBob = snapshot.filter { it.root.type == EventType.ENCRYPTED }
+
+                if (messagesReceivedByBob.size == expectedNumberOfMessages) {
+                    latch.countDown()
+                }
+            }
+        }
+    }
+}
diff --git a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/keysbackup/KeysBackupScenarioData.kt b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/keysbackup/KeysBackupScenarioData.kt
new file mode 100644
index 0000000000..0270c34a37
--- /dev/null
+++ b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/keysbackup/KeysBackupScenarioData.kt
@@ -0,0 +1,35 @@
+/*
+ * 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.matrix.android.internal.crypto.keysbackup
+
+import im.vector.matrix.android.api.session.Session
+import im.vector.matrix.android.common.CommonTestHelper
+import im.vector.matrix.android.common.CryptoTestData
+import im.vector.matrix.android.internal.crypto.model.OlmInboundGroupSessionWrapper2
+
+/**
+ * Data class to store result of [KeysBackupTestHelper.createKeysBackupScenarioWithPassword]
+ */
+data class KeysBackupScenarioData(val cryptoTestData: CryptoTestData,
+                                  val aliceKeys: List<OlmInboundGroupSessionWrapper2>,
+                                  val prepareKeysBackupDataResult: PrepareKeysBackupDataResult,
+                                  val aliceSession2: Session) {
+    fun cleanUp(testHelper: CommonTestHelper) {
+        cryptoTestData.cleanUp(testHelper)
+        testHelper.signOutAndClose(aliceSession2)
+    }
+}
diff --git a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/keysbackup/KeysBackupTest.kt b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/keysbackup/KeysBackupTest.kt
index 3042a3c68f..59ef24beec 100644
--- a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/keysbackup/KeysBackupTest.kt
+++ b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/keysbackup/KeysBackupTest.kt
@@ -20,27 +20,19 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
 import im.vector.matrix.android.InstrumentedTest
 import im.vector.matrix.android.api.listeners.ProgressListener
 import im.vector.matrix.android.api.listeners.StepProgressListener
-import im.vector.matrix.android.api.session.Session
-import im.vector.matrix.android.api.session.crypto.keysbackup.KeysBackupService
 import im.vector.matrix.android.api.session.crypto.keysbackup.KeysBackupState
 import im.vector.matrix.android.api.session.crypto.keysbackup.KeysBackupStateListener
 import im.vector.matrix.android.common.CommonTestHelper
-import im.vector.matrix.android.common.CryptoTestData
 import im.vector.matrix.android.common.CryptoTestHelper
-import im.vector.matrix.android.common.SessionTestParams
 import im.vector.matrix.android.common.TestConstants
 import im.vector.matrix.android.common.TestMatrixCallback
-import im.vector.matrix.android.common.assertDictEquals
-import im.vector.matrix.android.common.assertListEquals
 import im.vector.matrix.android.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM_BACKUP
-import im.vector.matrix.android.internal.crypto.MegolmSessionData
 import im.vector.matrix.android.internal.crypto.crosssigning.DeviceTrustLevel
 import im.vector.matrix.android.internal.crypto.keysbackup.model.KeysBackupVersionTrust
 import im.vector.matrix.android.internal.crypto.keysbackup.model.MegolmBackupCreationInfo
 import im.vector.matrix.android.internal.crypto.keysbackup.model.rest.KeysVersion
 import im.vector.matrix.android.internal.crypto.keysbackup.model.rest.KeysVersionResult
 import im.vector.matrix.android.internal.crypto.model.ImportRoomKeysResult
-import im.vector.matrix.android.internal.crypto.model.OlmInboundGroupSessionWrapper
 import org.junit.Assert.assertEquals
 import org.junit.Assert.assertFalse
 import org.junit.Assert.assertNotNull
@@ -61,9 +53,7 @@ class KeysBackupTest : InstrumentedTest {
 
     private val mTestHelper = CommonTestHelper(context())
     private val mCryptoTestHelper = CryptoTestHelper(mTestHelper)
-
-    private val defaultSessionParams = SessionTestParams(withInitialSync = false)
-    private val defaultSessionParamsWithInitialSync = SessionTestParams(withInitialSync = true)
+    private val mKeysBackupTestHelper = KeysBackupTestHelper(mTestHelper, mCryptoTestHelper)
 
     /**
      * - From doE2ETestWithAliceAndBobInARoomWithEncryptedMessages, we should have no backed up keys
@@ -110,7 +100,7 @@ class KeysBackupTest : InstrumentedTest {
      */
     @Test
     fun prepareKeysBackupVersionTest() {
-        val bobSession = mTestHelper.createAccount(TestConstants.USER_BOB, defaultSessionParams)
+        val bobSession = mTestHelper.createAccount(TestConstants.USER_BOB, KeysBackupTestConstants.defaultSessionParams)
 
         assertNotNull(bobSession.cryptoService().keysBackupService())
 
@@ -139,7 +129,7 @@ class KeysBackupTest : InstrumentedTest {
      */
     @Test
     fun createKeysBackupVersionTest() {
-        val bobSession = mTestHelper.createAccount(TestConstants.USER_BOB, defaultSessionParams)
+        val bobSession = mTestHelper.createAccount(TestConstants.USER_BOB, KeysBackupTestConstants.defaultSessionParams)
 
         val keysBackup = bobSession.cryptoService().keysBackupService()
 
@@ -182,7 +172,7 @@ class KeysBackupTest : InstrumentedTest {
 
         val stateObserver = StateObserver(keysBackup, latch, 5)
 
-        prepareAndCreateKeysBackupData(keysBackup)
+        mKeysBackupTestHelper.prepareAndCreateKeysBackupData(keysBackup)
 
         mTestHelper.await(latch)
 
@@ -216,7 +206,7 @@ class KeysBackupTest : InstrumentedTest {
 
         val stateObserver = StateObserver(keysBackup)
 
-        prepareAndCreateKeysBackupData(keysBackup)
+        mKeysBackupTestHelper.prepareAndCreateKeysBackupData(keysBackup)
 
         // Check that backupAllGroupSessions returns valid data
         val nbOfKeys = cryptoTestData.firstSession.cryptoService().inboundGroupSessionsCount(false)
@@ -263,7 +253,7 @@ class KeysBackupTest : InstrumentedTest {
         // - Pick a megolm key
         val session = keysBackup.store.inboundGroupSessionsToBackup(1)[0]
 
-        val keyBackupCreationInfo = prepareAndCreateKeysBackupData(keysBackup).megolmBackupCreationInfo
+        val keyBackupCreationInfo = mKeysBackupTestHelper.prepareAndCreateKeysBackupData(keysBackup).megolmBackupCreationInfo
 
         // - Check encryptGroupSession() returns stg
         val keyBackupData = keysBackup.encryptGroupSession(session)
@@ -281,7 +271,7 @@ class KeysBackupTest : InstrumentedTest {
                         decryption!!)
         assertNotNull(sessionData)
         // - Compare the decrypted megolm key with the original one
-        assertKeysEquals(session.exportKeys(), sessionData)
+        mKeysBackupTestHelper.assertKeysEquals(session.exportKeys(), sessionData)
 
         stateObserver.stopAndCheckStates(null)
         cryptoTestData.cleanUp(mTestHelper)
@@ -295,7 +285,7 @@ class KeysBackupTest : InstrumentedTest {
      */
     @Test
     fun restoreKeysBackupTest() {
-        val testData = createKeysBackupScenarioWithPassword(null)
+        val testData = mKeysBackupTestHelper.createKeysBackupScenarioWithPassword(null)
 
         // - Restore the e2e backup from the homeserver
         val importRoomKeysResult = mTestHelper.doSync<ImportRoomKeysResult> {
@@ -308,7 +298,7 @@ class KeysBackupTest : InstrumentedTest {
             )
         }
 
-        checkRestoreSuccess(testData, importRoomKeysResult.totalNumberOfKeys, importRoomKeysResult.successfullyNumberOfImportedKeys)
+        mKeysBackupTestHelper.checkRestoreSuccess(testData, importRoomKeysResult.totalNumberOfKeys, importRoomKeysResult.successfullyNumberOfImportedKeys)
 
         testData.cleanUp(mTestHelper)
     }
@@ -329,7 +319,7 @@ class KeysBackupTest : InstrumentedTest {
 //    fun restoreKeysBackupAndKeyShareRequestTest() {
 //        fail("Check with Valere for this test. I think we do not send key share request")
 //
-//        val testData = createKeysBackupScenarioWithPassword(null)
+//        val testData = mKeysBackupTestHelper.createKeysBackupScenarioWithPassword(null)
 //
 //        // - Check the SDK sent key share requests
 //        val cryptoStore2 = (testData.aliceSession2.cryptoService().keysBackupService() as DefaultKeysBackupService).store
@@ -352,7 +342,7 @@ class KeysBackupTest : InstrumentedTest {
 //            )
 //        }
 //
-//        checkRestoreSuccess(testData, importRoomKeysResult.totalNumberOfKeys, importRoomKeysResult.successfullyNumberOfImportedKeys)
+//        mKeysBackupTestHelper.checkRestoreSuccess(testData, importRoomKeysResult.totalNumberOfKeys, importRoomKeysResult.successfullyNumberOfImportedKeys)
 //
 //        // - There must be no more pending key share requests
 //        val unsentRequestAfterRestoration = cryptoStore2
@@ -380,7 +370,7 @@ class KeysBackupTest : InstrumentedTest {
     fun trustKeyBackupVersionTest() {
         // - Do an e2e backup to the homeserver with a recovery key
         // - And log Alice on a new device
-        val testData = createKeysBackupScenarioWithPassword(null)
+        val testData = mKeysBackupTestHelper.createKeysBackupScenarioWithPassword(null)
 
         val stateObserver = StateObserver(testData.aliceSession2.cryptoService().keysBackupService())
 
@@ -399,7 +389,7 @@ class KeysBackupTest : InstrumentedTest {
         }
 
         // Wait for backup state to be ReadyToBackUp
-        waitForKeysBackupToBeInState(testData.aliceSession2, KeysBackupState.ReadyToBackUp)
+        mKeysBackupTestHelper.waitForKeysBackupToBeInState(testData.aliceSession2, KeysBackupState.ReadyToBackUp)
 
         // - Backup must be enabled on the new device, on the same version
         assertEquals(testData.prepareKeysBackupDataResult.version, testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion?.version)
@@ -439,7 +429,7 @@ class KeysBackupTest : InstrumentedTest {
     fun trustKeyBackupVersionWithRecoveryKeyTest() {
         // - Do an e2e backup to the homeserver with a recovery key
         // - And log Alice on a new device
-        val testData = createKeysBackupScenarioWithPassword(null)
+        val testData = mKeysBackupTestHelper.createKeysBackupScenarioWithPassword(null)
 
         val stateObserver = StateObserver(testData.aliceSession2.cryptoService().keysBackupService())
 
@@ -458,7 +448,7 @@ class KeysBackupTest : InstrumentedTest {
         }
 
         // Wait for backup state to be ReadyToBackUp
-        waitForKeysBackupToBeInState(testData.aliceSession2, KeysBackupState.ReadyToBackUp)
+        mKeysBackupTestHelper.waitForKeysBackupToBeInState(testData.aliceSession2, KeysBackupState.ReadyToBackUp)
 
         // - Backup must be enabled on the new device, on the same version
         assertEquals(testData.prepareKeysBackupDataResult.version, testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion?.version)
@@ -496,7 +486,7 @@ class KeysBackupTest : InstrumentedTest {
     fun trustKeyBackupVersionWithWrongRecoveryKeyTest() {
         // - Do an e2e backup to the homeserver with a recovery key
         // - And log Alice on a new device
-        val testData = createKeysBackupScenarioWithPassword(null)
+        val testData = mKeysBackupTestHelper.createKeysBackupScenarioWithPassword(null)
 
         val stateObserver = StateObserver(testData.aliceSession2.cryptoService().keysBackupService())
 
@@ -539,7 +529,7 @@ class KeysBackupTest : InstrumentedTest {
 
         // - Do an e2e backup to the homeserver with a password
         // - And log Alice on a new device
-        val testData = createKeysBackupScenarioWithPassword(password)
+        val testData = mKeysBackupTestHelper.createKeysBackupScenarioWithPassword(password)
 
         val stateObserver = StateObserver(testData.aliceSession2.cryptoService().keysBackupService())
 
@@ -558,7 +548,7 @@ class KeysBackupTest : InstrumentedTest {
         }
 
         // Wait for backup state to be ReadyToBackUp
-        waitForKeysBackupToBeInState(testData.aliceSession2, KeysBackupState.ReadyToBackUp)
+        mKeysBackupTestHelper.waitForKeysBackupToBeInState(testData.aliceSession2, KeysBackupState.ReadyToBackUp)
 
         // - Backup must be enabled on the new device, on the same version
         assertEquals(testData.prepareKeysBackupDataResult.version, testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion?.version)
@@ -599,7 +589,7 @@ class KeysBackupTest : InstrumentedTest {
 
         // - Do an e2e backup to the homeserver with a password
         // - And log Alice on a new device
-        val testData = createKeysBackupScenarioWithPassword(password)
+        val testData = mKeysBackupTestHelper.createKeysBackupScenarioWithPassword(password)
 
         val stateObserver = StateObserver(testData.aliceSession2.cryptoService().keysBackupService())
 
@@ -634,7 +624,7 @@ class KeysBackupTest : InstrumentedTest {
      */
     @Test
     fun restoreKeysBackupWithAWrongRecoveryKeyTest() {
-        val testData = createKeysBackupScenarioWithPassword(null)
+        val testData = mKeysBackupTestHelper.createKeysBackupScenarioWithPassword(null)
 
         // - Try to restore the e2e backup with a wrong recovery key
         val latch2 = CountDownLatch(1)
@@ -669,7 +659,7 @@ class KeysBackupTest : InstrumentedTest {
     fun testBackupWithPassword() {
         val password = "password"
 
-        val testData = createKeysBackupScenarioWithPassword(password)
+        val testData = mKeysBackupTestHelper.createKeysBackupScenarioWithPassword(password)
 
         // - Restore the e2e backup with the password
         val steps = ArrayList<StepProgressListener.Step>()
@@ -709,7 +699,7 @@ class KeysBackupTest : InstrumentedTest {
         assertEquals(50, (steps[103] as StepProgressListener.Step.ImportingKey).progress)
         assertEquals(100, (steps[104] as StepProgressListener.Step.ImportingKey).progress)
 
-        checkRestoreSuccess(testData, importRoomKeysResult.totalNumberOfKeys, importRoomKeysResult.successfullyNumberOfImportedKeys)
+        mKeysBackupTestHelper.checkRestoreSuccess(testData, importRoomKeysResult.totalNumberOfKeys, importRoomKeysResult.successfullyNumberOfImportedKeys)
 
         testData.cleanUp(mTestHelper)
     }
@@ -725,7 +715,7 @@ class KeysBackupTest : InstrumentedTest {
         val password = "password"
         val wrongPassword = "passw0rd"
 
-        val testData = createKeysBackupScenarioWithPassword(password)
+        val testData = mKeysBackupTestHelper.createKeysBackupScenarioWithPassword(password)
 
         // - Try to restore the e2e backup with a wrong password
         val latch2 = CountDownLatch(1)
@@ -760,7 +750,7 @@ class KeysBackupTest : InstrumentedTest {
     fun testUseRecoveryKeyToRestoreAPasswordBasedKeysBackup() {
         val password = "password"
 
-        val testData = createKeysBackupScenarioWithPassword(password)
+        val testData = mKeysBackupTestHelper.createKeysBackupScenarioWithPassword(password)
 
         // - Restore the e2e backup with the recovery key.
         val importRoomKeysResult = mTestHelper.doSync<ImportRoomKeysResult> {
@@ -773,7 +763,7 @@ class KeysBackupTest : InstrumentedTest {
             )
         }
 
-        checkRestoreSuccess(testData, importRoomKeysResult.totalNumberOfKeys, importRoomKeysResult.successfullyNumberOfImportedKeys)
+        mKeysBackupTestHelper.checkRestoreSuccess(testData, importRoomKeysResult.totalNumberOfKeys, importRoomKeysResult.successfullyNumberOfImportedKeys)
 
         testData.cleanUp(mTestHelper)
     }
@@ -786,7 +776,7 @@ class KeysBackupTest : InstrumentedTest {
      */
     @Test
     fun testUsePasswordToRestoreARecoveryKeyBasedKeysBackup() {
-        val testData = createKeysBackupScenarioWithPassword(null)
+        val testData = mKeysBackupTestHelper.createKeysBackupScenarioWithPassword(null)
 
         // - Try to restore the e2e backup with a password
         val latch2 = CountDownLatch(1)
@@ -825,7 +815,7 @@ class KeysBackupTest : InstrumentedTest {
         val stateObserver = StateObserver(keysBackup)
 
         // - Do an e2e backup to the homeserver
-        prepareAndCreateKeysBackupData(keysBackup)
+        mKeysBackupTestHelper.prepareAndCreateKeysBackupData(keysBackup)
 
         // Get key backup version from the home server
         val keysVersionResult = mTestHelper.doSync<KeysVersionResult?> {
@@ -870,13 +860,13 @@ class KeysBackupTest : InstrumentedTest {
 
         assertFalse(keysBackup.isEnabled)
 
-        val keyBackupCreationInfo = prepareAndCreateKeysBackupData(keysBackup)
+        val keyBackupCreationInfo = mKeysBackupTestHelper.prepareAndCreateKeysBackupData(keysBackup)
 
         assertTrue(keysBackup.isEnabled)
 
         // - Restart alice session
         // - Log Alice on a new device
-        val aliceSession2 = mTestHelper.logIntoAccount(cryptoTestData.firstSession.myUserId, defaultSessionParamsWithInitialSync)
+        val aliceSession2 = mTestHelper.logIntoAccount(cryptoTestData.firstSession.myUserId, KeysBackupTestConstants.defaultSessionParamsWithInitialSync)
 
         cryptoTestData.cleanUp(mTestHelper)
 
@@ -950,7 +940,7 @@ class KeysBackupTest : InstrumentedTest {
         })
 
         // - Make alice back up her keys to her homeserver
-        prepareAndCreateKeysBackupData(keysBackup)
+        mKeysBackupTestHelper.prepareAndCreateKeysBackupData(keysBackup)
 
         assertTrue(keysBackup.isEnabled)
 
@@ -1000,7 +990,7 @@ class KeysBackupTest : InstrumentedTest {
         val stateObserver = StateObserver(keysBackup)
 
         // - Make alice back up her keys to her homeserver
-        prepareAndCreateKeysBackupData(keysBackup)
+        mKeysBackupTestHelper.prepareAndCreateKeysBackupData(keysBackup)
 
         // Wait for keys backup to finish by asking again to backup keys.
         mTestHelper.doSync<Unit> {
@@ -1012,7 +1002,7 @@ class KeysBackupTest : InstrumentedTest {
         val aliceUserId = cryptoTestData.firstSession.myUserId
 
         // - Log Alice on a new device
-        val aliceSession2 = mTestHelper.logIntoAccount(aliceUserId, defaultSessionParamsWithInitialSync)
+        val aliceSession2 = mTestHelper.logIntoAccount(aliceUserId, KeysBackupTestConstants.defaultSessionParamsWithInitialSync)
 
         // - Post a message to have a new megolm session
         aliceSession2.cryptoService().setWarnOnUnknownDevices(false)
@@ -1093,7 +1083,7 @@ class KeysBackupTest : InstrumentedTest {
 
         assertFalse(keysBackup.isEnabled)
 
-        val keyBackupCreationInfo = prepareAndCreateKeysBackupData(keysBackup)
+        val keyBackupCreationInfo = mKeysBackupTestHelper.prepareAndCreateKeysBackupData(keysBackup)
 
         assertTrue(keysBackup.isEnabled)
 
@@ -1106,169 +1096,4 @@ class KeysBackupTest : InstrumentedTest {
         stateObserver.stopAndCheckStates(null)
         cryptoTestData.cleanUp(mTestHelper)
     }
-
-    /* ==========================================================================================
-     * Private
-     * ========================================================================================== */
-
-    /**
-     * As KeysBackup is doing asynchronous call to update its internal state, this method help to wait for the
-     * KeysBackup object to be in the specified state
-     */
-    private fun waitForKeysBackupToBeInState(session: Session, state: KeysBackupState) {
-        // If already in the wanted state, return
-        if (session.cryptoService().keysBackupService().state == state) {
-            return
-        }
-
-        // Else observe state changes
-        val latch = CountDownLatch(1)
-
-        session.cryptoService().keysBackupService().addListener(object : KeysBackupStateListener {
-            override fun onStateChange(newState: KeysBackupState) {
-                if (newState == state) {
-                    session.cryptoService().keysBackupService().removeListener(this)
-                    latch.countDown()
-                }
-            }
-        })
-
-        mTestHelper.await(latch)
-    }
-
-    private data class PrepareKeysBackupDataResult(val megolmBackupCreationInfo: MegolmBackupCreationInfo,
-                                                   val version: String)
-
-    private fun prepareAndCreateKeysBackupData(keysBackup: KeysBackupService,
-                                               password: String? = null): PrepareKeysBackupDataResult {
-        val stateObserver = StateObserver(keysBackup)
-
-        val megolmBackupCreationInfo = mTestHelper.doSync<MegolmBackupCreationInfo> {
-            keysBackup.prepareKeysBackupVersion(password, null, it)
-        }
-
-        assertNotNull(megolmBackupCreationInfo)
-
-        assertFalse(keysBackup.isEnabled)
-
-        // Create the version
-        val keysVersion = mTestHelper.doSync<KeysVersion> {
-            keysBackup.createKeysBackupVersion(megolmBackupCreationInfo, it)
-        }
-
-        assertNotNull(keysVersion.version)
-
-        // Backup must be enable now
-        assertTrue(keysBackup.isEnabled)
-
-        stateObserver.stopAndCheckStates(null)
-        return PrepareKeysBackupDataResult(megolmBackupCreationInfo, keysVersion.version!!)
-    }
-
-    private fun assertKeysEquals(keys1: MegolmSessionData?, keys2: MegolmSessionData?) {
-        assertNotNull(keys1)
-        assertNotNull(keys2)
-
-        assertEquals(keys1?.algorithm, keys2?.algorithm)
-        assertEquals(keys1?.roomId, keys2?.roomId)
-        // No need to compare the shortcut
-        // assertEquals(keys1?.sender_claimed_ed25519_key, keys2?.sender_claimed_ed25519_key)
-        assertEquals(keys1?.senderKey, keys2?.senderKey)
-        assertEquals(keys1?.sessionId, keys2?.sessionId)
-        assertEquals(keys1?.sessionKey, keys2?.sessionKey)
-
-        assertListEquals(keys1?.forwardingCurve25519KeyChain, keys2?.forwardingCurve25519KeyChain)
-        assertDictEquals(keys1?.senderClaimedKeys, keys2?.senderClaimedKeys)
-    }
-
-    /**
-     * Data class to store result of [createKeysBackupScenarioWithPassword]
-     */
-    private data class KeysBackupScenarioData(val cryptoTestData: CryptoTestData,
-                                              val aliceKeys: List<OlmInboundGroupSessionWrapper>,
-                                              val prepareKeysBackupDataResult: PrepareKeysBackupDataResult,
-                                              val aliceSession2: Session) {
-        fun cleanUp(testHelper: CommonTestHelper) {
-            cryptoTestData.cleanUp(testHelper)
-            testHelper.signOutAndClose(aliceSession2)
-        }
-    }
-
-    /**
-     * Common initial condition
-     * - Do an e2e backup to the homeserver
-     * - Log Alice on a new device, and wait for its keysBackup object to be ready (in state NotTrusted)
-     *
-     * @param password optional password
-     */
-    private fun createKeysBackupScenarioWithPassword(password: String?): KeysBackupScenarioData {
-        val cryptoTestData = mCryptoTestHelper.doE2ETestWithAliceAndBobInARoomWithEncryptedMessages()
-
-        val cryptoStore = (cryptoTestData.firstSession.cryptoService().keysBackupService() as DefaultKeysBackupService).store
-        val keysBackup = cryptoTestData.firstSession.cryptoService().keysBackupService()
-
-        val stateObserver = StateObserver(keysBackup)
-
-        val aliceKeys = cryptoStore.inboundGroupSessionsToBackup(100)
-
-        // - Do an e2e backup to the homeserver
-        val prepareKeysBackupDataResult = prepareAndCreateKeysBackupData(keysBackup, password)
-
-        var lastProgress = 0
-        var lastTotal = 0
-        mTestHelper.doSync<Unit> {
-            keysBackup.backupAllGroupSessions(object : ProgressListener {
-                override fun onProgress(progress: Int, total: Int) {
-                    lastProgress = progress
-                    lastTotal = total
-                }
-            }, it)
-        }
-
-        assertEquals(2, lastProgress)
-        assertEquals(2, lastTotal)
-
-        val aliceUserId = cryptoTestData.firstSession.myUserId
-
-        // - Log Alice on a new device
-        val aliceSession2 = mTestHelper.logIntoAccount(aliceUserId, defaultSessionParamsWithInitialSync)
-
-        // Test check: aliceSession2 has no keys at login
-        assertEquals(0, aliceSession2.cryptoService().inboundGroupSessionsCount(false))
-
-        // Wait for backup state to be NotTrusted
-        waitForKeysBackupToBeInState(aliceSession2, KeysBackupState.NotTrusted)
-
-        stateObserver.stopAndCheckStates(null)
-
-        return KeysBackupScenarioData(cryptoTestData,
-                aliceKeys,
-                prepareKeysBackupDataResult,
-                aliceSession2)
-    }
-
-    /**
-     * Common restore success check after [createKeysBackupScenarioWithPassword]:
-     * - Imported keys number must be correct
-     * - The new device must have the same count of megolm keys
-     * - Alice must have the same keys on both devices
-     */
-    private fun checkRestoreSuccess(testData: KeysBackupScenarioData,
-                                    total: Int,
-                                    imported: Int) {
-        // - Imported keys number must be correct
-        assertEquals(testData.aliceKeys.size, total)
-        assertEquals(total, imported)
-
-        // - The new device must have the same count of megolm keys
-        assertEquals(testData.aliceKeys.size, testData.aliceSession2.cryptoService().inboundGroupSessionsCount(false))
-
-        // - Alice must have the same keys on both devices
-        for (aliceKey1 in testData.aliceKeys) {
-            val aliceKey2 = (testData.aliceSession2.cryptoService().keysBackupService() as DefaultKeysBackupService).store
-                    .getInboundGroupSession(aliceKey1.olmInboundGroupSession!!.sessionIdentifier(), aliceKey1.senderKey!!)
-            assertNotNull(aliceKey2)
-            assertKeysEquals(aliceKey1.exportKeys(), aliceKey2!!.exportKeys())
-        }
-    }
 }
diff --git a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/keysbackup/KeysBackupTestConstants.kt b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/keysbackup/KeysBackupTestConstants.kt
new file mode 100644
index 0000000000..0f3a23df3f
--- /dev/null
+++ b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/keysbackup/KeysBackupTestConstants.kt
@@ -0,0 +1,24 @@
+/*
+ * 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.matrix.android.internal.crypto.keysbackup
+
+import im.vector.matrix.android.common.SessionTestParams
+
+object KeysBackupTestConstants {
+    val defaultSessionParams = SessionTestParams(withInitialSync = false)
+    val defaultSessionParamsWithInitialSync = SessionTestParams(withInitialSync = true)
+}
diff --git a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/keysbackup/KeysBackupTestHelper.kt b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/keysbackup/KeysBackupTestHelper.kt
new file mode 100644
index 0000000000..bb1436b8d4
--- /dev/null
+++ b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/keysbackup/KeysBackupTestHelper.kt
@@ -0,0 +1,182 @@
+/*
+ * 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.matrix.android.internal.crypto.keysbackup
+
+import im.vector.matrix.android.api.listeners.ProgressListener
+import im.vector.matrix.android.api.session.Session
+import im.vector.matrix.android.api.session.crypto.keysbackup.KeysBackupService
+import im.vector.matrix.android.api.session.crypto.keysbackup.KeysBackupState
+import im.vector.matrix.android.api.session.crypto.keysbackup.KeysBackupStateListener
+import im.vector.matrix.android.common.CommonTestHelper
+import im.vector.matrix.android.common.CryptoTestHelper
+import im.vector.matrix.android.common.assertDictEquals
+import im.vector.matrix.android.common.assertListEquals
+import im.vector.matrix.android.internal.crypto.MegolmSessionData
+import im.vector.matrix.android.internal.crypto.keysbackup.model.MegolmBackupCreationInfo
+import im.vector.matrix.android.internal.crypto.keysbackup.model.rest.KeysVersion
+import org.junit.Assert
+import java.util.concurrent.CountDownLatch
+
+class KeysBackupTestHelper(
+        private val mTestHelper: CommonTestHelper,
+        private val mCryptoTestHelper: CryptoTestHelper) {
+
+    /**
+     * Common initial condition
+     * - Do an e2e backup to the homeserver
+     * - Log Alice on a new device, and wait for its keysBackup object to be ready (in state NotTrusted)
+     *
+     * @param password optional password
+     */
+    fun createKeysBackupScenarioWithPassword(password: String?): KeysBackupScenarioData {
+        val cryptoTestData = mCryptoTestHelper.doE2ETestWithAliceAndBobInARoomWithEncryptedMessages()
+
+        val cryptoStore = (cryptoTestData.firstSession.cryptoService().keysBackupService() as DefaultKeysBackupService).store
+        val keysBackup = cryptoTestData.firstSession.cryptoService().keysBackupService()
+
+        val stateObserver = StateObserver(keysBackup)
+
+        val aliceKeys = cryptoStore.inboundGroupSessionsToBackup(100)
+
+        // - Do an e2e backup to the homeserver
+        val prepareKeysBackupDataResult = prepareAndCreateKeysBackupData(keysBackup, password)
+
+        var lastProgress = 0
+        var lastTotal = 0
+        mTestHelper.doSync<Unit> {
+            keysBackup.backupAllGroupSessions(object : ProgressListener {
+                override fun onProgress(progress: Int, total: Int) {
+                    lastProgress = progress
+                    lastTotal = total
+                }
+            }, it)
+        }
+
+        Assert.assertEquals(2, lastProgress)
+        Assert.assertEquals(2, lastTotal)
+
+        val aliceUserId = cryptoTestData.firstSession.myUserId
+
+        // - Log Alice on a new device
+        val aliceSession2 = mTestHelper.logIntoAccount(aliceUserId, KeysBackupTestConstants.defaultSessionParamsWithInitialSync)
+
+        // Test check: aliceSession2 has no keys at login
+        Assert.assertEquals(0, aliceSession2.cryptoService().inboundGroupSessionsCount(false))
+
+        // Wait for backup state to be NotTrusted
+        waitForKeysBackupToBeInState(aliceSession2, KeysBackupState.NotTrusted)
+
+        stateObserver.stopAndCheckStates(null)
+
+        return KeysBackupScenarioData(cryptoTestData,
+                aliceKeys,
+                prepareKeysBackupDataResult,
+                aliceSession2)
+    }
+
+    fun prepareAndCreateKeysBackupData(keysBackup: KeysBackupService,
+                                       password: String? = null): PrepareKeysBackupDataResult {
+        val stateObserver = StateObserver(keysBackup)
+
+        val megolmBackupCreationInfo = mTestHelper.doSync<MegolmBackupCreationInfo> {
+            keysBackup.prepareKeysBackupVersion(password, null, it)
+        }
+
+        Assert.assertNotNull(megolmBackupCreationInfo)
+
+        Assert.assertFalse(keysBackup.isEnabled)
+
+        // Create the version
+        val keysVersion = mTestHelper.doSync<KeysVersion> {
+            keysBackup.createKeysBackupVersion(megolmBackupCreationInfo, it)
+        }
+
+        Assert.assertNotNull(keysVersion.version)
+
+        // Backup must be enable now
+        Assert.assertTrue(keysBackup.isEnabled)
+
+        stateObserver.stopAndCheckStates(null)
+        return PrepareKeysBackupDataResult(megolmBackupCreationInfo, keysVersion.version!!)
+    }
+
+    /**
+     * As KeysBackup is doing asynchronous call to update its internal state, this method help to wait for the
+     * KeysBackup object to be in the specified state
+     */
+    fun waitForKeysBackupToBeInState(session: Session, state: KeysBackupState) {
+        // If already in the wanted state, return
+        if (session.cryptoService().keysBackupService().state == state) {
+            return
+        }
+
+        // Else observe state changes
+        val latch = CountDownLatch(1)
+
+        session.cryptoService().keysBackupService().addListener(object : KeysBackupStateListener {
+            override fun onStateChange(newState: KeysBackupState) {
+                if (newState == state) {
+                    session.cryptoService().keysBackupService().removeListener(this)
+                    latch.countDown()
+                }
+            }
+        })
+
+        mTestHelper.await(latch)
+    }
+
+    fun assertKeysEquals(keys1: MegolmSessionData?, keys2: MegolmSessionData?) {
+        Assert.assertNotNull(keys1)
+        Assert.assertNotNull(keys2)
+
+        Assert.assertEquals(keys1?.algorithm, keys2?.algorithm)
+        Assert.assertEquals(keys1?.roomId, keys2?.roomId)
+        // No need to compare the shortcut
+        // assertEquals(keys1?.sender_claimed_ed25519_key, keys2?.sender_claimed_ed25519_key)
+        Assert.assertEquals(keys1?.senderKey, keys2?.senderKey)
+        Assert.assertEquals(keys1?.sessionId, keys2?.sessionId)
+        Assert.assertEquals(keys1?.sessionKey, keys2?.sessionKey)
+
+        assertListEquals(keys1?.forwardingCurve25519KeyChain, keys2?.forwardingCurve25519KeyChain)
+        assertDictEquals(keys1?.senderClaimedKeys, keys2?.senderClaimedKeys)
+    }
+
+    /**
+     * Common restore success check after [KeysBackupTestHelper.createKeysBackupScenarioWithPassword]:
+     * - Imported keys number must be correct
+     * - The new device must have the same count of megolm keys
+     * - Alice must have the same keys on both devices
+     */
+    fun checkRestoreSuccess(testData: KeysBackupScenarioData,
+                            total: Int,
+                            imported: Int) {
+        // - Imported keys number must be correct
+        Assert.assertEquals(testData.aliceKeys.size, total)
+        Assert.assertEquals(total, imported)
+
+        // - The new device must have the same count of megolm keys
+        Assert.assertEquals(testData.aliceKeys.size, testData.aliceSession2.cryptoService().inboundGroupSessionsCount(false))
+
+        // - Alice must have the same keys on both devices
+        for (aliceKey1 in testData.aliceKeys) {
+            val aliceKey2 = (testData.aliceSession2.cryptoService().keysBackupService() as DefaultKeysBackupService).store
+                    .getInboundGroupSession(aliceKey1.olmInboundGroupSession!!.sessionIdentifier(), aliceKey1.senderKey!!)
+            Assert.assertNotNull(aliceKey2)
+            assertKeysEquals(aliceKey1.exportKeys(), aliceKey2!!.exportKeys())
+        }
+    }
+}
diff --git a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/keysbackup/PrepareKeysBackupDataResult.kt b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/keysbackup/PrepareKeysBackupDataResult.kt
new file mode 100644
index 0000000000..91d00cbe21
--- /dev/null
+++ b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/keysbackup/PrepareKeysBackupDataResult.kt
@@ -0,0 +1,22 @@
+/*
+ * 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.matrix.android.internal.crypto.keysbackup
+
+import im.vector.matrix.android.internal.crypto.keysbackup.model.MegolmBackupCreationInfo
+
+data class PrepareKeysBackupDataResult(val megolmBackupCreationInfo: MegolmBackupCreationInfo,
+                                       val version: String)
diff --git a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/ssss/QuadSTests.kt b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/ssss/QuadSTests.kt
index 1a0723c725..cbd175f53f 100644
--- a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/ssss/QuadSTests.kt
+++ b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/ssss/QuadSTests.kt
@@ -71,7 +71,7 @@ class QuadSTests : InstrumentedTest {
         val TEST_KEY_ID = "my.test.Key"
 
         mTestHelper.doSync<SsssKeyCreationInfo> {
-            quadS.generateKey(TEST_KEY_ID, "Test Key", emptyKeySigner, it)
+            quadS.generateKey(TEST_KEY_ID, null, "Test Key", emptyKeySigner, it)
         }
 
         // Assert Account data is updated
@@ -177,7 +177,7 @@ class QuadSTests : InstrumentedTest {
         val TEST_KEY_ID = "my.test.Key"
 
         mTestHelper.doSync<SsssKeyCreationInfo> {
-            quadS.generateKey(TEST_KEY_ID, "Test Key", emptyKeySigner, it)
+            quadS.generateKey(TEST_KEY_ID, null, "Test Key", emptyKeySigner, it)
         }
 
         // Test that we don't need to wait for an account data sync to access directly the keyid from DB
@@ -322,7 +322,7 @@ class QuadSTests : InstrumentedTest {
         val quadS = session.sharedSecretStorageService
 
         val creationInfo = mTestHelper.doSync<SsssKeyCreationInfo> {
-            quadS.generateKey(keyId, keyId, emptyKeySigner, it)
+            quadS.generateKey(keyId, null, keyId, emptyKeySigner, it)
         }
 
         assertAccountData(session, "${DefaultSharedSecretStorageService.KEY_ID_BASE}.$keyId")
diff --git a/matrix-sdk-android/src/debug/java/im/vector/matrix/android/internal/network/interceptors/CurlLoggingInterceptor.kt b/matrix-sdk-android/src/debug/java/im/vector/matrix/android/internal/network/interceptors/CurlLoggingInterceptor.kt
index c96786ba3b..eb05e26362 100644
--- a/matrix-sdk-android/src/debug/java/im/vector/matrix/android/internal/network/interceptors/CurlLoggingInterceptor.kt
+++ b/matrix-sdk-android/src/debug/java/im/vector/matrix/android/internal/network/interceptors/CurlLoggingInterceptor.kt
@@ -20,7 +20,6 @@ package im.vector.matrix.android.internal.network.interceptors
 import im.vector.matrix.android.internal.di.MatrixScope
 import okhttp3.Interceptor
 import okhttp3.Response
-import okhttp3.logging.HttpLoggingInterceptor
 import okio.Buffer
 import timber.log.Timber
 import java.io.IOException
@@ -37,7 +36,7 @@ import javax.inject.Inject
  * non-production environment.
  */
 @MatrixScope
-internal class CurlLoggingInterceptor @Inject constructor(private val logger: HttpLoggingInterceptor.Logger)
+internal class CurlLoggingInterceptor @Inject constructor()
     : Interceptor {
 
     /**
@@ -97,8 +96,8 @@ internal class CurlLoggingInterceptor @Inject constructor(private val logger: Ht
         // Add Json formatting
         curlCmd += " | python -m json.tool"
 
-        logger.log("--- cURL (" + request.url + ")")
-        logger.log(curlCmd)
+        Timber.d("--- cURL (${request.url})")
+        Timber.d(curlCmd)
 
         return chain.proceed(request)
     }
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/Matrix.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/Matrix.kt
index 22ac0324cf..4c6e3ea3bd 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/Matrix.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/Matrix.kt
@@ -33,6 +33,7 @@ import im.vector.matrix.android.internal.util.BackgroundDetectionObserver
 import org.matrix.olm.OlmManager
 import java.io.InputStream
 import java.util.concurrent.atomic.AtomicBoolean
+import java.util.concurrent.Executors
 import javax.inject.Inject
 
 data class MatrixConfiguration(
@@ -61,7 +62,7 @@ class Matrix private constructor(context: Context, matrixConfiguration: MatrixCo
         Monarchy.init(context)
         DaggerMatrixComponent.factory().create(context, matrixConfiguration).inject(this)
         if (context.applicationContext !is Configuration.Provider) {
-            WorkManager.initialize(context, Configuration.Builder().build())
+            WorkManager.initialize(context, Configuration.Builder().setExecutor(Executors.newCachedThreadPool()).build())
         }
         ProcessLifecycleOwner.get().lifecycle.addObserver(backgroundDetectionObserver)
     }
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/auth/Constants.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/auth/Constants.kt
new file mode 100644
index 0000000000..af6e2277f4
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/auth/Constants.kt
@@ -0,0 +1,37 @@
+/*
+ * 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.matrix.android.api.auth
+
+/**
+ * Path to use when the client does not supported any or all login flows
+ * Ref: https://matrix.org/docs/spec/client_server/latest#login-fallback
+ * */
+const val LOGIN_FALLBACK_PATH = "/_matrix/static/client/login/"
+
+/**
+ * Path to use when the client does not supported any or all registration flows
+ * Not documented
+ */
+const val REGISTER_FALLBACK_PATH = "/_matrix/static/client/register/"
+
+/**
+ * Path to use when the client want to connect using SSO
+ * Ref: https://matrix.org/docs/spec/client_server/latest#sso-client-login
+ */
+const val SSO_FALLBACK_PATH = "/_matrix/client/r0/login/sso/redirect"
+
+const val SSO_REDIRECT_URL_PARAM = "redirectUrl"
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/failure/Extensions.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/failure/Extensions.kt
index 5dfb0eab9b..7b5dffb21e 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/failure/Extensions.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/failure/Extensions.kt
@@ -16,6 +16,10 @@
 
 package im.vector.matrix.android.api.failure
 
+import im.vector.matrix.android.api.extensions.tryThis
+import im.vector.matrix.android.internal.auth.registration.RegistrationFlowResponse
+import im.vector.matrix.android.internal.di.MoshiProvider
+import java.io.IOException
 import javax.net.ssl.HttpsURLConnection
 
 fun Throwable.is401() =
@@ -29,5 +33,27 @@ fun Throwable.isTokenError() =
 
 fun Throwable.shouldBeRetried(): Boolean {
     return this is Failure.NetworkConnection
+            || this is IOException
             || (this is Failure.ServerError && error.code == MatrixError.M_LIMIT_EXCEEDED)
 }
+
+fun Throwable.isInvalidPassword(): Boolean {
+    return this is Failure.ServerError
+            && error.code == MatrixError.M_FORBIDDEN
+            && error.message == "Invalid password"
+}
+
+/**
+ * Try to convert to a RegistrationFlowResponse. Return null in the cases it's not possible
+ */
+fun Throwable.toRegistrationFlowResponse(): RegistrationFlowResponse? {
+    return if (this is Failure.OtherServerError && this.httpCode == 401) {
+        tryThis {
+            MoshiProvider.providesMoshi()
+                    .adapter(RegistrationFlowResponse::class.java)
+                    .fromJson(this.errorBody)
+        }
+    } else {
+        null
+    }
+}
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/Session.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/Session.kt
index c2fa7d2d32..1afeed922f 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/Session.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/Session.kt
@@ -21,6 +21,7 @@ import androidx.lifecycle.LiveData
 import im.vector.matrix.android.api.auth.data.SessionParams
 import im.vector.matrix.android.api.failure.GlobalError
 import im.vector.matrix.android.api.pushrules.PushRuleService
+import im.vector.matrix.android.api.session.account.AccountService
 import im.vector.matrix.android.api.session.accountdata.AccountDataService
 import im.vector.matrix.android.api.session.cache.CacheService
 import im.vector.matrix.android.api.session.content.ContentUploadStateTracker
@@ -59,7 +60,8 @@ interface Session :
         InitialSyncProgressService,
         HomeServerCapabilitiesService,
         SecureStorageService,
-        AccountDataService {
+        AccountDataService,
+        AccountService {
 
     /**
      * The params associated to the session
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/account/AccountService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/account/AccountService.kt
new file mode 100644
index 0000000000..ddbaaea6ef
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/account/AccountService.kt
@@ -0,0 +1,50 @@
+/*
+ * 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.matrix.android.api.session.account
+
+import im.vector.matrix.android.api.MatrixCallback
+import im.vector.matrix.android.api.util.Cancelable
+
+/**
+ * This interface defines methods to manage the account. It's implemented at the session level.
+ */
+interface AccountService {
+    /**
+     * Ask the homeserver to change the password.
+     * @param password Current password.
+     * @param newPassword New password
+     */
+    fun changePassword(password: String, newPassword: String, callback: MatrixCallback<Unit>): Cancelable
+
+    /**
+     * Deactivate the account.
+     *
+     * This will make your account permanently unusable. You will not be able to log in, and no one will be able to re-register
+     * the same user ID. This will cause your account to leave all rooms it is participating in, and it will remove your account
+     * details from your identity server. <b>This action is irreversible</b>.\n\nDeactivating your account <b>does not by default
+     * cause us to forget messages you have sent</b>. If you would like us to forget your messages, please tick the box below.
+     *
+     * Message visibility in Matrix is similar to email. Our forgetting your messages means that messages you have sent will not
+     * be shared with any new or unregistered users, but registered users who already have access to these messages will still
+     * have access to their copy.
+     *
+     * @param password the account password
+     * @param eraseAllData set to true to forget all messages that have been sent. Warning: this will cause future users to see
+     * an incomplete view of conversations
+     */
+    fun deactivateAccount(password: String, eraseAllData: Boolean, callback: MatrixCallback<Unit>): Cancelable
+}
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/content/ContentUrlResolver.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/content/ContentUrlResolver.kt
index 9ba1631aec..6ed0b92e38 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/content/ContentUrlResolver.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/content/ContentUrlResolver.kt
@@ -26,6 +26,11 @@ interface ContentUrlResolver {
         SCALE("scale")
     }
 
+    /**
+     * URL to use to upload content
+     */
+    val uploadUrl: String
+
     /**
      * Get the actual URL for accessing the full-size image of a Matrix media content URI.
      *
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/CryptoService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/CryptoService.kt
index ab8417b542..2c96465313 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/CryptoService.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/CryptoService.kt
@@ -98,7 +98,9 @@ interface CryptoService {
 
     fun removeRoomKeysRequestListener(listener: GossipingRequestListener)
 
-    fun getDevicesList(callback: MatrixCallback<DevicesListResponse>)
+    fun fetchDevicesList(callback: MatrixCallback<DevicesListResponse>)
+    fun getMyDevicesInfo() : List<DeviceInfo>
+    fun getLiveMyDevicesInfo() : LiveData<List<DeviceInfo>>
 
     fun getDeviceInfo(deviceId: String, callback: MatrixCallback<DeviceInfo>)
 
@@ -111,6 +113,8 @@ interface CryptoService {
                             roomId: String,
                             callback: MatrixCallback<MXEncryptEventContentResult>)
 
+    fun discardOutboundSession(roomId: String)
+
     @Throws(MXCryptoError::class)
     fun decryptEvent(event: Event, timeline: String): MXEventDecryptionResult
 
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/crosssigning/CrossSigningService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/crosssigning/CrossSigningService.kt
index 4085e1233d..f1c998cee5 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/crosssigning/CrossSigningService.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/crosssigning/CrossSigningService.kt
@@ -55,6 +55,8 @@ interface CrossSigningService {
 
     fun getCrossSigningPrivateKeys(): PrivateKeysInfo?
 
+    fun getLiveCrossSigningPrivateKeys(): LiveData<Optional<PrivateKeysInfo>>
+
     fun canCrossSign(): Boolean
 
     fun trustUser(otherUserId: String,
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/keysbackup/KeysBackupService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/keysbackup/KeysBackupService.kt
index e9ed36ba23..9ad39d45fd 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/keysbackup/KeysBackupService.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/keysbackup/KeysBackupService.kt
@@ -217,4 +217,6 @@ interface KeysBackupService {
     // For gossiping
     fun saveBackupRecoveryKey(recoveryKey: String?, version: String?)
     fun getKeyBackupRecoveryKeyInfo() : SavedKeyBackupKeyInfo?
+
+    fun isValidRecoveryKeyForCurrentVersion(recoveryKey: String, callback: MatrixCallback<Boolean>)
 }
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/events/model/EventType.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/events/model/EventType.kt
index 9a3107a8ca..3cdd433516 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/events/model/EventType.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/events/model/EventType.kt
@@ -81,6 +81,9 @@ object EventType {
     // Relation Events
     const val REACTION = "m.reaction"
 
+    // Unwedging
+    internal const val DUMMY = "m.dummy"
+
     private val STATE_EVENTS = listOf(
             STATE_ROOM_NAME,
             STATE_ROOM_TOPIC,
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/homeserver/HomeServerCapabilities.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/homeserver/HomeServerCapabilities.kt
index 9b01cdef3b..c8526985e1 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/homeserver/HomeServerCapabilities.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/homeserver/HomeServerCapabilities.kt
@@ -17,6 +17,10 @@
 package im.vector.matrix.android.api.session.homeserver
 
 data class HomeServerCapabilities(
+        /**
+         * True if it is possible to change the password of the account.
+         */
+        val canChangePassword: Boolean = true,
         /**
          * Max size of file which can be uploaded to the homeserver in bytes. [MAX_UPLOAD_FILE_SIZE_UNKNOWN] if unknown or not retrieved yet
          */
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/RoomSummary.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/RoomSummary.kt
index 6171b2633b..1ad6112f2c 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/RoomSummary.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/RoomSummary.kt
@@ -46,10 +46,10 @@ data class RoomSummary constructor(
         val readMarkerId: String? = null,
         val userDrafts: List<UserDraft> = emptyList(),
         val isEncrypted: Boolean,
+        val encryptionEventTs: Long?,
         val inviterId: String? = null,
         val typingRoomMemberIds: List<String> = emptyList(),
         val breadcrumbsIndex: Int = NOT_IN_BREADCRUMBS,
-        // TODO Plug it
         val roomEncryptionTrustLevel: RoomEncryptionTrustLevel? = null
 ) {
 
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/message/AudioInfo.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/message/AudioInfo.kt
index eef6b283c6..877746705f 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/message/AudioInfo.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/message/AudioInfo.kt
@@ -24,7 +24,7 @@ data class AudioInfo(
         /**
          * The mimetype of the audio e.g. "audio/aac".
          */
-        @Json(name = "mimetype") val mimeType: String,
+        @Json(name = "mimetype") val mimeType: String?,
 
         /**
          * The size of the audio clip in bytes.
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/message/MessageLocationContent.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/message/MessageLocationContent.kt
index 02ba9eae6e..4bbd821819 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/message/MessageLocationContent.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/message/MessageLocationContent.kt
@@ -29,7 +29,8 @@ data class MessageLocationContent(
         @Json(name = "msgtype") override val msgType: String,
 
         /**
-         * Required. A description of the location e.g. 'Big Ben, London, UK', or some kind of content description for accessibility e.g. 'location attachment'.
+         * Required. A description of the location e.g. 'Big Ben, London, UK', or some kind
+         * of content description for accessibility e.g. 'location attachment'.
          */
         @Json(name = "body") override val body: String,
 
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/message/ThumbnailInfo.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/message/ThumbnailInfo.kt
index 0ef1b8f658..0ee6b88e01 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/message/ThumbnailInfo.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/message/ThumbnailInfo.kt
@@ -39,5 +39,5 @@ data class ThumbnailInfo(
         /**
          * The mimetype of the image, e.g. "image/jpeg".
          */
-        @Json(name = "mimetype") val mimeType: String
+        @Json(name = "mimetype") val mimeType: String?
 )
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/timeline/Timeline.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/timeline/Timeline.kt
index eb4a9b59e4..d7d6682046 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/timeline/Timeline.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/timeline/Timeline.kt
@@ -104,6 +104,7 @@ interface Timeline {
     interface Listener {
         /**
          * Call when the timeline has been updated through pagination or sync.
+         * The latest event is the first in the list
          * @param snapshot the most up to date snapshot
          */
         fun onTimelineUpdated(snapshot: List<TimelineEvent>)
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/securestorage/SharedSecretStorageService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/securestorage/SharedSecretStorageService.kt
index d32e459dd6..5fd0975f1a 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/securestorage/SharedSecretStorageService.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/securestorage/SharedSecretStorageService.kt
@@ -35,12 +35,14 @@ interface SharedSecretStorageService {
      * Use the SsssKeyCreationInfo object returned by the callback to get more information about the created key (recovery key ...)
      *
      * @param keyId the ID of the key
+     * @param key keep null if you want to generate a random key
      * @param keyName a human readable name
      * @param keySigner Used to add a signature to the key (client should check key signature before storing secret)
      *
      * @param callback Get key creation info
      */
     fun generateKey(keyId: String,
+                    key: SsssKeySpec?,
                     keyName: String,
                     keySigner: KeySigner?,
                     callback: MatrixCallback<SsssKeyCreationInfo>)
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/registration/RegisterTask.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/registration/RegisterTask.kt
index 69976b063f..473b960d94 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/registration/RegisterTask.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/registration/RegisterTask.kt
@@ -18,8 +18,8 @@ package im.vector.matrix.android.internal.auth.registration
 
 import im.vector.matrix.android.api.auth.data.Credentials
 import im.vector.matrix.android.api.failure.Failure
+import im.vector.matrix.android.api.failure.toRegistrationFlowResponse
 import im.vector.matrix.android.internal.auth.AuthAPI
-import im.vector.matrix.android.internal.di.MoshiProvider
 import im.vector.matrix.android.internal.network.executeRequest
 import im.vector.matrix.android.internal.task.Task
 
@@ -39,25 +39,9 @@ internal class DefaultRegisterTask(
                 apiCall = authAPI.register(params.registrationParams)
             }
         } catch (throwable: Throwable) {
-            if (throwable is Failure.OtherServerError && throwable.httpCode == 401) {
-                // Parse to get a RegistrationFlowResponse
-                val registrationFlowResponse = try {
-                    MoshiProvider.providesMoshi()
-                            .adapter(RegistrationFlowResponse::class.java)
-                            .fromJson(throwable.errorBody)
-                } catch (e: Exception) {
-                    null
-                }
-                // check if the server response can be cast
-                if (registrationFlowResponse != null) {
-                    throw Failure.RegistrationFlowError(registrationFlowResponse)
-                } else {
-                    throw throwable
-                }
-            } else {
-                // Other error
-                throw throwable
-            }
+            throw throwable.toRegistrationFlowResponse()
+                    ?.let { Failure.RegistrationFlowError(it) }
+                    ?: throwable
         }
     }
 }
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/CryptoModule.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/CryptoModule.kt
index 28375a091b..1efdffdb06 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/CryptoModule.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/CryptoModule.kt
@@ -66,6 +66,7 @@ import im.vector.matrix.android.internal.crypto.tasks.DefaultDownloadKeysForUser
 import im.vector.matrix.android.internal.crypto.tasks.DefaultEncryptEventTask
 import im.vector.matrix.android.internal.crypto.tasks.DefaultGetDeviceInfoTask
 import im.vector.matrix.android.internal.crypto.tasks.DefaultGetDevicesTask
+import im.vector.matrix.android.internal.crypto.tasks.DefaultInitializeCrossSigningTask
 import im.vector.matrix.android.internal.crypto.tasks.DefaultSendToDeviceTask
 import im.vector.matrix.android.internal.crypto.tasks.DefaultSendVerificationMessageTask
 import im.vector.matrix.android.internal.crypto.tasks.DefaultSetDeviceNameTask
@@ -78,6 +79,7 @@ import im.vector.matrix.android.internal.crypto.tasks.DownloadKeysForUsersTask
 import im.vector.matrix.android.internal.crypto.tasks.EncryptEventTask
 import im.vector.matrix.android.internal.crypto.tasks.GetDeviceInfoTask
 import im.vector.matrix.android.internal.crypto.tasks.GetDevicesTask
+import im.vector.matrix.android.internal.crypto.tasks.InitializeCrossSigningTask
 import im.vector.matrix.android.internal.crypto.tasks.SendToDeviceTask
 import im.vector.matrix.android.internal.crypto.tasks.SendVerificationMessageTask
 import im.vector.matrix.android.internal.crypto.tasks.SetDeviceNameTask
@@ -110,6 +112,7 @@ internal abstract class CryptoModule {
         @SessionScope
         fun providesRealmConfiguration(@SessionFilesDirectory directory: File,
                                        @UserMd5 userMd5: String,
+                                       realmCryptoStoreMigration: RealmCryptoStoreMigration,
                                        realmKeysUtils: RealmKeysUtils): RealmConfiguration {
             return RealmConfiguration.Builder()
                     .directory(directory)
@@ -119,7 +122,7 @@ internal abstract class CryptoModule {
                     .name("crypto_store.realm")
                     .modules(RealmCryptoStoreModule())
                     .schemaVersion(RealmCryptoStoreMigration.CRYPTO_STORE_SCHEMA_VERSION)
-                    .migration(RealmCryptoStoreMigration)
+                    .migration(realmCryptoStoreMigration)
                     .build()
         }
 
@@ -245,4 +248,7 @@ internal abstract class CryptoModule {
 
     @Binds
     abstract fun bindComputeShieldTrustTask(task: DefaultComputeTrustTask): ComputeTrustTask
+
+    @Binds
+    abstract fun bindInitializeCrossSigningTask(task: DefaultInitializeCrossSigningTask): InitializeCrossSigningTask
 }
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/DefaultCryptoService.kt
index ee96e45e85..d529cf4ae5 100755
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/DefaultCryptoService.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/DefaultCryptoService.kt
@@ -21,13 +21,13 @@ package im.vector.matrix.android.internal.crypto
 import android.content.Context
 import android.os.Handler
 import android.os.Looper
+import androidx.annotation.VisibleForTesting
 import androidx.lifecycle.LiveData
 import com.squareup.moshi.Types
 import com.zhuinden.monarchy.Monarchy
 import dagger.Lazy
 import im.vector.matrix.android.api.MatrixCallback
 import im.vector.matrix.android.api.NoOpMatrixCallback
-import im.vector.matrix.android.api.auth.data.Credentials
 import im.vector.matrix.android.api.crypto.MXCryptoConfig
 import im.vector.matrix.android.api.failure.Failure
 import im.vector.matrix.android.api.listeners.ProgressListener
@@ -45,7 +45,9 @@ import im.vector.matrix.android.api.session.room.model.Membership
 import im.vector.matrix.android.api.session.room.model.RoomHistoryVisibility
 import im.vector.matrix.android.api.session.room.model.RoomHistoryVisibilityContent
 import im.vector.matrix.android.api.session.room.model.RoomMemberSummary
+import im.vector.matrix.android.internal.crypto.actions.EnsureOlmSessionsForDevicesAction
 import im.vector.matrix.android.internal.crypto.actions.MegolmSessionDataImporter
+import im.vector.matrix.android.internal.crypto.actions.MessageEncrypter
 import im.vector.matrix.android.internal.crypto.actions.SetDeviceVerificationAction
 import im.vector.matrix.android.internal.crypto.algorithms.IMXEncrypting
 import im.vector.matrix.android.internal.crypto.algorithms.megolm.MXMegolmEncryptionFactory
@@ -59,6 +61,7 @@ import im.vector.matrix.android.internal.crypto.model.MXDeviceInfo
 import im.vector.matrix.android.internal.crypto.model.MXEncryptEventContentResult
 import im.vector.matrix.android.internal.crypto.model.MXUsersDevicesMap
 import im.vector.matrix.android.internal.crypto.model.event.EncryptedEventContent
+import im.vector.matrix.android.internal.crypto.model.event.OlmEventContent
 import im.vector.matrix.android.internal.crypto.model.event.RoomKeyContent
 import im.vector.matrix.android.internal.crypto.model.event.SecretSendEventContent
 import im.vector.matrix.android.internal.crypto.model.rest.DeviceInfo
@@ -72,13 +75,16 @@ import im.vector.matrix.android.internal.crypto.tasks.DeleteDeviceTask
 import im.vector.matrix.android.internal.crypto.tasks.DeleteDeviceWithUserPasswordTask
 import im.vector.matrix.android.internal.crypto.tasks.GetDeviceInfoTask
 import im.vector.matrix.android.internal.crypto.tasks.GetDevicesTask
+import im.vector.matrix.android.internal.crypto.tasks.SendToDeviceTask
 import im.vector.matrix.android.internal.crypto.tasks.SetDeviceNameTask
 import im.vector.matrix.android.internal.crypto.tasks.UploadKeysTask
 import im.vector.matrix.android.internal.crypto.verification.DefaultVerificationService
 import im.vector.matrix.android.internal.database.model.EventEntity
 import im.vector.matrix.android.internal.database.model.EventEntityFields
 import im.vector.matrix.android.internal.database.query.whereType
+import im.vector.matrix.android.internal.di.DeviceId
 import im.vector.matrix.android.internal.di.MoshiProvider
+import im.vector.matrix.android.internal.di.UserId
 import im.vector.matrix.android.internal.extensions.foldToCallback
 import im.vector.matrix.android.internal.session.SessionScope
 import im.vector.matrix.android.internal.session.room.membership.LoadRoomMembersTask
@@ -116,12 +122,15 @@ import kotlin.math.max
 internal class DefaultCryptoService @Inject constructor(
         // Olm Manager
         private val olmManager: OlmManager,
-        // The credentials,
-        private val credentials: Credentials,
+        @UserId
+        private val userId: String,
+        @DeviceId
+        private val deviceId: String?,
         private val myDeviceInfoHolder: Lazy<MyDeviceInfoHolder>,
         // the crypto store
         private val cryptoStore: IMXCryptoStore,
-
+        // Room encryptors store
+        private val roomEncryptorsStore: RoomEncryptorsStore,
         // Olm device
         private val olmDevice: MXOlmDevice,
         // Set of parameters used to configure/customize the end-to-end crypto.
@@ -162,7 +171,10 @@ internal class DefaultCryptoService @Inject constructor(
         private val monarchy: Monarchy,
         private val coroutineDispatchers: MatrixCoroutineDispatchers,
         private val taskExecutor: TaskExecutor,
-        private val cryptoCoroutineScope: CoroutineScope
+        private val cryptoCoroutineScope: CoroutineScope,
+        private val ensureOlmSessionsForDevicesAction: EnsureOlmSessionsForDevicesAction,
+        private val sendToDeviceTask: SendToDeviceTask,
+        private val messageEncrypter: MessageEncrypter
 ) : CryptoService {
 
     init {
@@ -171,11 +183,13 @@ internal class DefaultCryptoService @Inject constructor(
 
     private val uiHandler = Handler(Looper.getMainLooper())
 
-    // MXEncrypting instance for each room.
-    private val roomEncryptors: MutableMap<String, IMXEncrypting> = HashMap()
     private val isStarting = AtomicBoolean(false)
     private val isStarted = AtomicBoolean(false)
 
+    // The date of the last time we forced establishment
+    // of a new session for each user:device.
+    private val lastNewSessionForcedDates = MXUsersDevicesMap<Long>()
+
     fun onStateEvent(roomId: String, event: Event) {
         when {
             event.getClearType() == EventType.STATE_ROOM_ENCRYPTION         -> onRoomEncryptionEvent(roomId, event)
@@ -199,7 +213,7 @@ internal class DefaultCryptoService @Inject constructor(
                     this.callback = object : MatrixCallback<Unit> {
                         override fun onSuccess(data: Unit) {
                             // bg refresh of crypto device
-                            downloadKeys(listOf(credentials.userId), true, NoOpMatrixCallback())
+                            downloadKeys(listOf(userId), true, NoOpMatrixCallback())
                             callback.onSuccess(data)
                         }
 
@@ -237,15 +251,33 @@ internal class DefaultCryptoService @Inject constructor(
         return myDeviceInfoHolder.get().myDevice
     }
 
-    override fun getDevicesList(callback: MatrixCallback<DevicesListResponse>) {
+    override fun fetchDevicesList(callback: MatrixCallback<DevicesListResponse>) {
         getDevicesTask
                 .configureWith {
                     //                    this.executionThread = TaskThread.CRYPTO
-                    this.callback = callback
+                    this.callback = object : MatrixCallback<DevicesListResponse> {
+                        override fun onFailure(failure: Throwable) {
+                            callback.onFailure(failure)
+                        }
+
+                        override fun onSuccess(data: DevicesListResponse) {
+                            // Save in local DB
+                            cryptoStore.saveMyDevicesInfo(data.devices ?: emptyList())
+                            callback.onSuccess(data)
+                        }
+                    }
                 }
                 .executeBy(taskExecutor)
     }
 
+    override fun getLiveMyDevicesInfo(): LiveData<List<DeviceInfo>> {
+        return cryptoStore.getLiveMyDevicesInfo()
+    }
+
+    override fun getMyDevicesInfo(): List<DeviceInfo> {
+        return cryptoStore.getMyDevicesInfo()
+    }
+
     override fun getDeviceInfo(deviceId: String, callback: MatrixCallback<DeviceInfo>) {
         getDeviceInfoTask
                 .configureWith(GetDeviceInfoTask.Params(deviceId)) {
@@ -304,6 +336,8 @@ internal class DefaultCryptoService @Inject constructor(
         cryptoCoroutineScope.launch(coroutineDispatchers.crypto) {
             internalStart(isInitialSync)
         }
+        // Just update
+        fetchDevicesList(NoOpMatrixCallback())
     }
 
     private suspend fun internalStart(isInitialSync: Boolean) {
@@ -398,7 +432,7 @@ internal class DefaultCryptoService @Inject constructor(
     }
 
     /**
-     * Provides the device information for a device id and a user Id
+     * Provides the device information for a user id and a device Id
      *
      * @param userId   the user id
      * @param deviceId the device id
@@ -412,7 +446,7 @@ internal class DefaultCryptoService @Inject constructor(
     }
 
     override fun getCryptoDeviceInfo(userId: String): List<CryptoDeviceInfo> {
-        return cryptoStore.getUserDevices(userId)?.map { it.value } ?: emptyList()
+        return cryptoStore.getUserDeviceList(userId) ?: emptyList()
     }
 
     override fun getLiveCryptoDeviceInfo(): LiveData<List<CryptoDeviceInfo>> {
@@ -493,14 +527,14 @@ internal class DefaultCryptoService @Inject constructor(
         val existingAlgorithm = cryptoStore.getRoomAlgorithm(roomId)
 
         if (!existingAlgorithm.isNullOrEmpty() && existingAlgorithm != algorithm) {
-            Timber.e("## setEncryptionInRoom() : Ignoring m.room.encryption event which requests a change of config in $roomId")
+            Timber.e("## CRYPTO | setEncryptionInRoom() : Ignoring m.room.encryption event which requests a change of config in $roomId")
             return false
         }
 
         val encryptingClass = MXCryptoAlgorithms.hasEncryptorClassForAlgorithm(algorithm)
 
         if (!encryptingClass) {
-            Timber.e("## setEncryptionInRoom() : Unable to encrypt room $roomId with $algorithm")
+            Timber.e("## CRYPTO | setEncryptionInRoom() : Unable to encrypt room $roomId with $algorithm")
             return false
         }
 
@@ -511,9 +545,7 @@ internal class DefaultCryptoService @Inject constructor(
             else                      -> olmEncryptionFactory.create(roomId)
         }
 
-        synchronized(roomEncryptors) {
-            roomEncryptors.put(roomId, alg)
-        }
+        roomEncryptorsStore.put(roomId, alg)
 
         // if encryption was not previously enabled in this room, we will have been
         // ignoring new device events for these users so far. We may well have
@@ -591,42 +623,44 @@ internal class DefaultCryptoService @Inject constructor(
                                      callback: MatrixCallback<MXEncryptEventContentResult>) {
         cryptoCoroutineScope.launch(coroutineDispatchers.crypto) {
             if (!isStarted()) {
-                Timber.v("## encryptEventContent() : wait after e2e init")
+                Timber.v("## CRYPTO | encryptEventContent() : wait after e2e init")
                 internalStart(false)
             }
             val userIds = getRoomUserIds(roomId)
-            var alg = synchronized(roomEncryptors) {
-                roomEncryptors[roomId]
-            }
+            var alg = roomEncryptorsStore.get(roomId)
             if (alg == null) {
                 val algorithm = getEncryptionAlgorithm(roomId)
                 if (algorithm != null) {
                     if (setEncryptionInRoom(roomId, algorithm, false, userIds)) {
-                        synchronized(roomEncryptors) {
-                            alg = roomEncryptors[roomId]
-                        }
+                        alg = roomEncryptorsStore.get(roomId)
                     }
                 }
             }
             val safeAlgorithm = alg
             if (safeAlgorithm != null) {
                 val t0 = System.currentTimeMillis()
-                Timber.v("## encryptEventContent() starts")
+                Timber.v("## CRYPTO | encryptEventContent() starts")
                 runCatching {
                     val content = safeAlgorithm.encryptEventContent(eventContent, eventType, userIds)
-                    Timber.v("## encryptEventContent() : succeeds after ${System.currentTimeMillis() - t0} ms")
+                    Timber.v("## CRYPTO | encryptEventContent() : succeeds after ${System.currentTimeMillis() - t0} ms")
                     MXEncryptEventContentResult(content, EventType.ENCRYPTED)
                 }.foldToCallback(callback)
             } else {
                 val algorithm = getEncryptionAlgorithm(roomId)
                 val reason = String.format(MXCryptoError.UNABLE_TO_ENCRYPT_REASON,
                         algorithm ?: MXCryptoError.NO_MORE_ALGORITHM_REASON)
-                Timber.e("## encryptEventContent() : $reason")
+                Timber.e("## CRYPTO | encryptEventContent() : $reason")
                 callback.onFailure(Failure.CryptoError(MXCryptoError.Base(MXCryptoError.ErrorType.UNABLE_TO_ENCRYPT, reason)))
             }
         }
     }
 
+    override fun discardOutboundSession(roomId: String) {
+        cryptoCoroutineScope.launch(coroutineDispatchers.crypto) {
+            roomEncryptorsStore.get(roomId)?.discardSessionKey()
+        }
+    }
+
     /**
      * Decrypt an event
      *
@@ -664,20 +698,42 @@ internal class DefaultCryptoService @Inject constructor(
      * @param timeline the id of the timeline where the event is decrypted. It is used to prevent replay attack.
      * @return the MXEventDecryptionResult data, or null in case of error
      */
+    @Throws(MXCryptoError::class)
     private fun internalDecryptEvent(event: Event, timeline: String): MXEventDecryptionResult {
         val eventContent = event.content
         if (eventContent == null) {
-            Timber.e("## decryptEvent : empty event content")
+            Timber.e("## CRYPTO | decryptEvent : empty event content")
             throw MXCryptoError.Base(MXCryptoError.ErrorType.BAD_ENCRYPTED_MESSAGE, MXCryptoError.BAD_ENCRYPTED_MESSAGE_REASON)
         } else {
             val algorithm = eventContent["algorithm"]?.toString()
             val alg = roomDecryptorProvider.getOrCreateRoomDecryptor(event.roomId, algorithm)
             if (alg == null) {
                 val reason = String.format(MXCryptoError.UNABLE_TO_DECRYPT_REASON, event.eventId, algorithm)
-                Timber.e("## decryptEvent() : $reason")
+                Timber.e("## CRYPTO | decryptEvent() : $reason")
                 throw MXCryptoError.Base(MXCryptoError.ErrorType.UNABLE_TO_DECRYPT, reason)
             } else {
-                return alg.decryptEvent(event, timeline)
+                try {
+                    return alg.decryptEvent(event, timeline)
+                } catch (mxCryptoError: MXCryptoError) {
+                    Timber.d("## CRYPTO | internalDecryptEvent : Failed to decrypt ${event.eventId} reason: $mxCryptoError")
+                    if (algorithm == MXCRYPTO_ALGORITHM_OLM) {
+                        if (mxCryptoError is MXCryptoError.Base
+                                && mxCryptoError.errorType == MXCryptoError.ErrorType.BAD_ENCRYPTED_MESSAGE) {
+                            // need to find sending device
+                            val olmContent = event.content.toModel<OlmEventContent>()
+                            cryptoStore.getUserDevices(event.senderId ?: "")
+                                    ?.values
+                                    ?.firstOrNull { it.identityKey() == olmContent?.senderKey }
+                                    ?.let {
+                                        markOlmSessionForUnwedging(event.senderId ?: "", it)
+                                    }
+                                    ?: run {
+                                        Timber.v("## CRYPTO | markOlmSessionForUnwedging() : Failed to find sender crypto device")
+                                    }
+                        }
+                    }
+                    throw mxCryptoError
+                }
             }
         }
     }
@@ -730,30 +786,30 @@ internal class DefaultCryptoService @Inject constructor(
      */
     private fun onRoomKeyEvent(event: Event) {
         val roomKeyContent = event.getClearContent().toModel<RoomKeyContent>() ?: return
-        Timber.v("## GOSSIP onRoomKeyEvent() : type<${event.type}> , sessionId<${roomKeyContent.sessionId}>")
+        Timber.v("## CRYPTO | GOSSIP onRoomKeyEvent() : type<${event.type}> , sessionId<${roomKeyContent.sessionId}>")
         if (roomKeyContent.roomId.isNullOrEmpty() || roomKeyContent.algorithm.isNullOrEmpty()) {
-            Timber.e("## GOSSIP onRoomKeyEvent() : missing fields")
+            Timber.e("## CRYPTO | GOSSIP onRoomKeyEvent() : missing fields")
             return
         }
         val alg = roomDecryptorProvider.getOrCreateRoomDecryptor(roomKeyContent.roomId, roomKeyContent.algorithm)
         if (alg == null) {
-            Timber.e("## GOSSIP onRoomKeyEvent() : Unable to handle keys for ${roomKeyContent.algorithm}")
+            Timber.e("## CRYPTO | GOSSIP onRoomKeyEvent() : Unable to handle keys for ${roomKeyContent.algorithm}")
             return
         }
         alg.onRoomKeyEvent(event, keysBackupService)
     }
 
     private fun onSecretSendReceived(event: Event) {
-        Timber.i("## GOSSIP onSecretSend() : onSecretSendReceived ${event.content?.get("sender_key")}")
+        Timber.i("## CRYPTO | GOSSIP onSecretSend() : onSecretSendReceived ${event.content?.get("sender_key")}")
         if (!event.isEncrypted()) {
             // secret send messages must be encrypted
-            Timber.e("## GOSSIP onSecretSend() :Received unencrypted secret send event")
+            Timber.e("## CRYPTO | GOSSIP onSecretSend() :Received unencrypted secret send event")
             return
         }
 
         // Was that sent by us?
-        if (event.senderId != credentials.userId) {
-            Timber.e("## GOSSIP onSecretSend() : Ignore secret from other user ${event.senderId}")
+        if (event.senderId != userId) {
+            Timber.e("## CRYPTO | GOSSIP onSecretSend() : Ignore secret from other user ${event.senderId}")
             return
         }
 
@@ -763,13 +819,13 @@ internal class DefaultCryptoService @Inject constructor(
                 .getOutgoingSecretKeyRequests().firstOrNull { it.requestId == secretContent.requestId }
 
         if (existingRequest == null) {
-            Timber.i("## GOSSIP onSecretSend() : Ignore secret that was not requested: ${secretContent.requestId}")
+            Timber.i("## CRYPTO | GOSSIP onSecretSend() : Ignore secret that was not requested: ${secretContent.requestId}")
             return
         }
 
         if (!handleSDKLevelGossip(existingRequest.secretName, secretContent.secretValue)) {
             // TODO Ask to application layer?
-            Timber.v("## onSecretSend() : secret not handled by SDK")
+            Timber.v("## CRYPTO | onSecretSend() : secret not handled by SDK")
         }
     }
 
@@ -805,7 +861,7 @@ internal class DefaultCryptoService @Inject constructor(
             try {
                 loadRoomMembersTask.execute(params)
             } catch (throwable: Throwable) {
-                Timber.e(throwable, "## onRoomEncryptionEvent ERROR FAILED TO SETUP CRYPTO ")
+                Timber.e(throwable, "## CRYPTO | onRoomEncryptionEvent ERROR FAILED TO SETUP CRYPTO ")
             } finally {
                 val userIds = getRoomUserIds(roomId)
                 setEncryptionInRoom(roomId, event.content?.get("algorithm")?.toString(), true, userIds)
@@ -835,16 +891,8 @@ internal class DefaultCryptoService @Inject constructor(
      * @param event the membership event causing the change
      */
     private fun onRoomMembershipEvent(roomId: String, event: Event) {
-        val alg: IMXEncrypting?
+        roomEncryptorsStore.get(roomId) ?: /* No encrypting in this room */ return
 
-        synchronized(roomEncryptors) {
-            alg = roomEncryptors[roomId]
-        }
-
-        if (null == alg) {
-            // No encrypting in this room
-            return
-        }
         event.stateKey?.let { userId ->
             val roomMember: RoomMemberSummary? = event.content.toModel()
             val membership = roomMember?.membership
@@ -938,13 +986,13 @@ internal class DefaultCryptoService @Inject constructor(
         cryptoCoroutineScope.launch(coroutineDispatchers.main) {
             runCatching {
                 withContext(coroutineDispatchers.crypto) {
-                    Timber.v("## importRoomKeys starts")
+                    Timber.v("## CRYPTO | importRoomKeys starts")
 
                     val t0 = System.currentTimeMillis()
                     val roomKeys = MXMegolmExportEncryption.decryptMegolmKeyFile(roomKeysAsArray, password)
                     val t1 = System.currentTimeMillis()
 
-                    Timber.v("## importRoomKeys : decryptMegolmKeyFile done in ${t1 - t0} ms")
+                    Timber.v("## CRYPTO | importRoomKeys : decryptMegolmKeyFile done in ${t1 - t0} ms")
 
                     val importedSessions = MoshiProvider.providesMoshi()
                             .adapter<List<MegolmSessionData>>(Types.newParameterizedType(List::class.java, MegolmSessionData::class.java))
@@ -952,7 +1000,7 @@ internal class DefaultCryptoService @Inject constructor(
 
                     val t2 = System.currentTimeMillis()
 
-                    Timber.v("## importRoomKeys : JSON parsing ${t2 - t1} ms")
+                    Timber.v("## CRYPTO | importRoomKeys : JSON parsing ${t2 - t1} ms")
 
                     if (importedSessions == null) {
                         throw Exception("Error")
@@ -1087,7 +1135,7 @@ internal class DefaultCryptoService @Inject constructor(
      */
     override fun reRequestRoomKeyForEvent(event: Event) {
         val wireContent = event.content.toModel<EncryptedEventContent>() ?: return Unit.also {
-            Timber.e("## reRequestRoomKeyForEvent Failed to re-request key, null content")
+            Timber.e("## CRYPTO | reRequestRoomKeyForEvent Failed to re-request key, null content")
         }
 
         val requestBody = RoomKeyRequestBody(
@@ -1102,18 +1150,18 @@ internal class DefaultCryptoService @Inject constructor(
 
     override fun requestRoomKeyForEvent(event: Event) {
         val wireContent = event.content.toModel<EncryptedEventContent>() ?: return Unit.also {
-            Timber.e("## requestRoomKeyForEvent Failed to request key, null content eventId: ${event.eventId}")
+            Timber.e("## CRYPTO | requestRoomKeyForEvent Failed to request key, null content eventId: ${event.eventId}")
         }
 
         cryptoCoroutineScope.launch(coroutineDispatchers.crypto) {
             if (!isStarted()) {
-                Timber.v("## requestRoomKeyForEvent() : wait after e2e init")
+                Timber.v("## CRYPTO | requestRoomKeyForEvent() : wait after e2e init")
                 internalStart(false)
             }
             roomDecryptorProvider
                     .getOrCreateRoomDecryptor(event.roomId, wireContent.algorithm)
                     ?.requestKeysForEvent(event) ?: run {
-                Timber.v("## requestRoomKeyForEvent() : No room decryptor for roomId:${event.roomId} algorithm:${wireContent.algorithm}")
+                Timber.v("## CRYPTO | requestRoomKeyForEvent() : No room decryptor for roomId:${event.roomId} algorithm:${wireContent.algorithm}")
             }
         }
     }
@@ -1136,6 +1184,39 @@ internal class DefaultCryptoService @Inject constructor(
         incomingGossipingRequestManager.removeRoomKeysRequestListener(listener)
     }
 
+    private fun markOlmSessionForUnwedging(senderId: String, deviceInfo: CryptoDeviceInfo) {
+        val deviceKey = deviceInfo.identityKey()
+
+        val lastForcedDate = lastNewSessionForcedDates.getObject(senderId, deviceKey) ?: 0
+        val now = System.currentTimeMillis()
+        if (now - lastForcedDate < CRYPTO_MIN_FORCE_SESSION_PERIOD_MILLIS) {
+            Timber.d("## CRYPTO | markOlmSessionForUnwedging: New session already forced with device at $lastForcedDate. Not forcing another")
+            return
+        }
+
+        Timber.d("## CRYPTO | markOlmSessionForUnwedging from $senderId:${deviceInfo.deviceId}")
+        lastNewSessionForcedDates.setObject(senderId, deviceKey, now)
+
+        cryptoCoroutineScope.launch(coroutineDispatchers.crypto) {
+            ensureOlmSessionsForDevicesAction.handle(mapOf(senderId to listOf(deviceInfo)), force = true)
+
+            // Now send a blank message on that session so the other side knows about it.
+            // (The keyshare request is sent in the clear so that won't do)
+            // We send this first such that, as long as the toDevice messages arrive in the
+            // same order we sent them, the other end will get this first, set up the new session,
+            // then get the keyshare request and send the key over this new session (because it
+            // is the session it has most recently received a message on).
+            val payloadJson = mapOf<String, Any>("type" to EventType.DUMMY)
+
+            val encodedPayload = messageEncrypter.encryptMessage(payloadJson, listOf(deviceInfo))
+            val sendToDeviceMap = MXUsersDevicesMap<Any>()
+            sendToDeviceMap.setObject(senderId, deviceInfo.deviceId, encodedPayload)
+            Timber.v("## CRYPTO | markOlmSessionForUnwedging() : sending to $senderId:${deviceInfo.deviceId}")
+            val sendToDeviceParams = SendToDeviceTask.Params(EventType.ENCRYPTED, sendToDeviceMap)
+            sendToDeviceTask.execute(sendToDeviceParams)
+        }
+    }
+
     /**
      * Provides the list of unknown devices
      *
@@ -1178,7 +1259,7 @@ internal class DefaultCryptoService @Inject constructor(
  * ========================================================================================== */
 
     override fun toString(): String {
-        return "DefaultCryptoService of " + credentials.userId + " (" + credentials.deviceId + ")"
+        return "DefaultCryptoService of $userId ($deviceId)"
     }
 
     override fun getOutgoingRoomKeyRequest(): List<OutgoingRoomKeyRequest> {
@@ -1192,4 +1273,15 @@ internal class DefaultCryptoService @Inject constructor(
     override fun getGossipingEventsTrail(): List<Event> {
         return cryptoStore.getGossipingEventsTrail()
     }
+
+    /* ==========================================================================================
+     * For test only
+     * ========================================================================================== */
+
+    @VisibleForTesting
+    val cryptoStoreForTesting = cryptoStore
+
+    companion object {
+        const val CRYPTO_MIN_FORCE_SESSION_PERIOD_MILLIS = 3_600_000 // one hour
+    }
 }
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/DeviceListManager.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/DeviceListManager.kt
index 37a5ee18e1..680539d057 100755
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/DeviceListManager.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/DeviceListManager.kt
@@ -108,7 +108,7 @@ internal class DeviceListManager @Inject constructor(private val cryptoStore: IM
                     res = !notReadyToRetryHS.contains(userId.substringAfterLast(':'))
                 }
             } catch (e: Exception) {
-                Timber.e(e, "## canRetryKeysDownload() failed")
+                Timber.e(e, "## CRYPTO | canRetryKeysDownload() failed")
             }
         }
 
@@ -137,7 +137,7 @@ internal class DeviceListManager @Inject constructor(private val cryptoStore: IM
 
             for (userId in userIds) {
                 if (!deviceTrackingStatuses.containsKey(userId) || TRACKING_STATUS_NOT_TRACKED == deviceTrackingStatuses[userId]) {
-                    Timber.v("## startTrackingDeviceList() : Now tracking device list for $userId")
+                    Timber.v("## CRYPTO | startTrackingDeviceList() : Now tracking device list for $userId")
                     deviceTrackingStatuses[userId] = TRACKING_STATUS_PENDING_DOWNLOAD
                     isUpdated = true
                 }
@@ -161,7 +161,7 @@ internal class DeviceListManager @Inject constructor(private val cryptoStore: IM
 
         for (userId in changed) {
             if (deviceTrackingStatuses.containsKey(userId)) {
-                Timber.v("## invalidateUserDeviceList() : Marking device list outdated for $userId")
+                Timber.v("## CRYPTO | invalidateUserDeviceList() : Marking device list outdated for $userId")
                 deviceTrackingStatuses[userId] = TRACKING_STATUS_PENDING_DOWNLOAD
                 isUpdated = true
             }
@@ -169,7 +169,7 @@ internal class DeviceListManager @Inject constructor(private val cryptoStore: IM
 
         for (userId in left) {
             if (deviceTrackingStatuses.containsKey(userId)) {
-                Timber.v("## invalidateUserDeviceList() : No longer tracking device list for $userId")
+                Timber.v("## CRYPTO | invalidateUserDeviceList() : No longer tracking device list for $userId")
                 deviceTrackingStatuses[userId] = TRACKING_STATUS_NOT_TRACKED
                 isUpdated = true
             }
@@ -259,7 +259,7 @@ internal class DeviceListManager @Inject constructor(private val cryptoStore: IM
      * @param forceDownload Always download the keys even if cached.
      */
     suspend fun downloadKeys(userIds: List<String>?, forceDownload: Boolean): MXUsersDevicesMap<CryptoDeviceInfo> {
-        Timber.v("## downloadKeys() : forceDownload $forceDownload : $userIds")
+        Timber.v("## CRYPTO | downloadKeys() : forceDownload $forceDownload : $userIds")
         // Map from userId -> deviceId -> MXDeviceInfo
         val stored = MXUsersDevicesMap<CryptoDeviceInfo>()
 
@@ -288,13 +288,13 @@ internal class DeviceListManager @Inject constructor(private val cryptoStore: IM
             }
         }
         return if (downloadUsers.isEmpty()) {
-            Timber.v("## downloadKeys() : no new user device")
+            Timber.v("## CRYPTO | downloadKeys() : no new user device")
             stored
         } else {
-            Timber.v("## downloadKeys() : starts")
+            Timber.v("## CRYPTO | downloadKeys() : starts")
             val t0 = System.currentTimeMillis()
             val result = doKeyDownloadForUsers(downloadUsers)
-            Timber.v("## downloadKeys() : doKeyDownloadForUsers succeeds after ${System.currentTimeMillis() - t0} ms")
+            Timber.v("## CRYPTO | downloadKeys() : doKeyDownloadForUsers succeeds after ${System.currentTimeMillis() - t0} ms")
             result.also {
                 it.addEntriesFromMap(stored)
             }
@@ -307,7 +307,7 @@ internal class DeviceListManager @Inject constructor(private val cryptoStore: IM
      * @param downloadUsers the user ids list
      */
     private suspend fun doKeyDownloadForUsers(downloadUsers: List<String>): MXUsersDevicesMap<CryptoDeviceInfo> {
-        Timber.v("## doKeyDownloadForUsers() : doKeyDownloadForUsers $downloadUsers")
+        Timber.v("## CRYPTO | doKeyDownloadForUsers() : doKeyDownloadForUsers $downloadUsers")
         // get the user ids which did not already trigger a keys download
         val filteredUsers = downloadUsers.filter { MatrixPatterns.isUserId(it) }
         if (filteredUsers.isEmpty()) {
@@ -318,16 +318,16 @@ internal class DeviceListManager @Inject constructor(private val cryptoStore: IM
         val response = try {
             downloadKeysForUsersTask.execute(params)
         } catch (throwable: Throwable) {
-            Timber.e(throwable, "##doKeyDownloadForUsers(): error")
+            Timber.e(throwable, "## CRYPTO | doKeyDownloadForUsers(): error")
             onKeysDownloadFailed(filteredUsers)
             throw throwable
         }
-        Timber.v("## doKeyDownloadForUsers() : Got keys for " + filteredUsers.size + " users")
+        Timber.v("## CRYPTO | doKeyDownloadForUsers() : Got keys for " + filteredUsers.size + " users")
         for (userId in filteredUsers) {
             // al devices =
             val models = response.deviceKeys?.get(userId)?.mapValues { entry -> CryptoInfoMapper.map(entry.value) }
 
-            Timber.v("## doKeyDownloadForUsers() : Got keys for $userId : $models")
+            Timber.v("## CRYPTO | doKeyDownloadForUsers() : Got keys for $userId : $models")
             if (!models.isNullOrEmpty()) {
                 val workingCopy = models.toMutableMap()
                 for ((deviceId, deviceInfo) in models) {
@@ -361,13 +361,13 @@ internal class DeviceListManager @Inject constructor(private val cryptoStore: IM
 
             // Handle cross signing keys update
             val masterKey = response.masterKeys?.get(userId)?.toCryptoModel().also {
-                Timber.v("## CrossSigning : Got keys for $userId : MSK ${it?.unpaddedBase64PublicKey}")
+                Timber.v("## CRYPTO | CrossSigning : Got keys for $userId : MSK ${it?.unpaddedBase64PublicKey}")
             }
             val selfSigningKey = response.selfSigningKeys?.get(userId)?.toCryptoModel()?.also {
-                Timber.v("## CrossSigning : Got keys for $userId : SSK ${it.unpaddedBase64PublicKey}")
+                Timber.v("## CRYPTO | CrossSigning : Got keys for $userId : SSK ${it.unpaddedBase64PublicKey}")
             }
             val userSigningKey = response.userSigningKeys?.get(userId)?.toCryptoModel()?.also {
-                Timber.v("## CrossSigning : Got keys for $userId : USK ${it.unpaddedBase64PublicKey}")
+                Timber.v("## CRYPTO | CrossSigning : Got keys for $userId : USK ${it.unpaddedBase64PublicKey}")
             }
             cryptoStore.storeUserCrossSigningKeys(
                     userId,
@@ -395,28 +395,28 @@ internal class DeviceListManager @Inject constructor(private val cryptoStore: IM
      */
     private fun validateDeviceKeys(deviceKeys: CryptoDeviceInfo?, userId: String, deviceId: String, previouslyStoredDeviceKeys: CryptoDeviceInfo?): Boolean {
         if (null == deviceKeys) {
-            Timber.e("## validateDeviceKeys() : deviceKeys is null from $userId:$deviceId")
+            Timber.e("## CRYPTO | validateDeviceKeys() : deviceKeys is null from $userId:$deviceId")
             return false
         }
 
         if (null == deviceKeys.keys) {
-            Timber.e("## validateDeviceKeys() : deviceKeys.keys is null from $userId:$deviceId")
+            Timber.e("## CRYPTO | validateDeviceKeys() : deviceKeys.keys is null from $userId:$deviceId")
             return false
         }
 
         if (null == deviceKeys.signatures) {
-            Timber.e("## validateDeviceKeys() : deviceKeys.signatures is null from $userId:$deviceId")
+            Timber.e("## CRYPTO | validateDeviceKeys() : deviceKeys.signatures is null from $userId:$deviceId")
             return false
         }
 
         // Check that the user_id and device_id in the received deviceKeys are correct
         if (deviceKeys.userId != userId) {
-            Timber.e("## validateDeviceKeys() : Mismatched user_id ${deviceKeys.userId} from $userId:$deviceId")
+            Timber.e("## CRYPTO | validateDeviceKeys() : Mismatched user_id ${deviceKeys.userId} from $userId:$deviceId")
             return false
         }
 
         if (deviceKeys.deviceId != deviceId) {
-            Timber.e("## validateDeviceKeys() : Mismatched device_id ${deviceKeys.deviceId} from $userId:$deviceId")
+            Timber.e("## CRYPTO | validateDeviceKeys() : Mismatched device_id ${deviceKeys.deviceId} from $userId:$deviceId")
             return false
         }
 
@@ -424,21 +424,21 @@ internal class DeviceListManager @Inject constructor(private val cryptoStore: IM
         val signKey = deviceKeys.keys[signKeyId]
 
         if (null == signKey) {
-            Timber.e("## validateDeviceKeys() : Device $userId:${deviceKeys.deviceId} has no ed25519 key")
+            Timber.e("## CRYPTO | validateDeviceKeys() : Device $userId:${deviceKeys.deviceId} has no ed25519 key")
             return false
         }
 
         val signatureMap = deviceKeys.signatures[userId]
 
         if (null == signatureMap) {
-            Timber.e("## validateDeviceKeys() : Device $userId:${deviceKeys.deviceId} has no map for $userId")
+            Timber.e("## CRYPTO | validateDeviceKeys() : Device $userId:${deviceKeys.deviceId} has no map for $userId")
             return false
         }
 
         val signature = signatureMap[signKeyId]
 
         if (null == signature) {
-            Timber.e("## validateDeviceKeys() : Device $userId:${deviceKeys.deviceId} is not signed")
+            Timber.e("## CRYPTO | validateDeviceKeys() : Device $userId:${deviceKeys.deviceId} is not signed")
             return false
         }
 
@@ -453,7 +453,7 @@ internal class DeviceListManager @Inject constructor(private val cryptoStore: IM
         }
 
         if (!isVerified) {
-            Timber.e("## validateDeviceKeys() : Unable to verify signature on device " + userId + ":"
+            Timber.e("## CRYPTO | validateDeviceKeys() : Unable to verify signature on device " + userId + ":"
                     + deviceKeys.deviceId + " with error " + errorMessage)
             return false
         }
@@ -464,12 +464,12 @@ internal class DeviceListManager @Inject constructor(private val cryptoStore: IM
                 // best off sticking with the original keys.
                 //
                 // Should we warn the user about it somehow?
-                Timber.e("## validateDeviceKeys() : WARNING:Ed25519 key for device " + userId + ":"
+                Timber.e("## CRYPTO | validateDeviceKeys() : WARNING:Ed25519 key for device " + userId + ":"
                         + deviceKeys.deviceId + " has changed : "
                         + previouslyStoredDeviceKeys.fingerprint() + " -> " + signKey)
 
-                Timber.e("## validateDeviceKeys() : $previouslyStoredDeviceKeys -> $deviceKeys")
-                Timber.e("## validateDeviceKeys() : ${previouslyStoredDeviceKeys.keys} -> ${deviceKeys.keys}")
+                Timber.e("## CRYPTO | validateDeviceKeys() : $previouslyStoredDeviceKeys -> $deviceKeys")
+                Timber.e("## CRYPTO | validateDeviceKeys() : ${previouslyStoredDeviceKeys.keys} -> ${deviceKeys.keys}")
 
                 return false
             }
@@ -501,10 +501,10 @@ internal class DeviceListManager @Inject constructor(private val cryptoStore: IM
             doKeyDownloadForUsers(users)
         }.fold(
                 {
-                    Timber.v("## refreshOutdatedDeviceLists() : done")
+                    Timber.v("## CRYPTO | refreshOutdatedDeviceLists() : done")
                 },
                 {
-                    Timber.e(it, "## refreshOutdatedDeviceLists() : ERROR updating device keys for users $users")
+                    Timber.e(it, "## CRYPTO | refreshOutdatedDeviceLists() : ERROR updating device keys for users $users")
                 }
         )
     }
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/IncomingGossipingRequestManager.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/IncomingGossipingRequestManager.kt
index da596960dd..38f81ba47d 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/IncomingGossipingRequestManager.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/IncomingGossipingRequestManager.kt
@@ -32,7 +32,10 @@ import im.vector.matrix.android.internal.crypto.model.rest.GossipingToDeviceObje
 import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore
 import im.vector.matrix.android.internal.di.SessionId
 import im.vector.matrix.android.internal.session.SessionScope
+import im.vector.matrix.android.internal.util.MatrixCoroutineDispatchers
 import im.vector.matrix.android.internal.worker.WorkerParamsFactory
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.launch
 import timber.log.Timber
 import javax.inject.Inject
 
@@ -43,7 +46,10 @@ internal class IncomingGossipingRequestManager @Inject constructor(
         private val cryptoStore: IMXCryptoStore,
         private val cryptoConfig: MXCryptoConfig,
         private val gossipingWorkManager: GossipingWorkManager,
-        private val roomDecryptorProvider: RoomDecryptorProvider) {
+        private val roomEncryptorsStore: RoomEncryptorsStore,
+        private val roomDecryptorProvider: RoomDecryptorProvider,
+        private val coroutineDispatchers: MatrixCoroutineDispatchers,
+        private val cryptoCoroutineScope: CoroutineScope) {
 
     // list of IncomingRoomKeyRequests/IncomingRoomKeyRequestCancellations
     // we received in the current sync.
@@ -90,7 +96,7 @@ internal class IncomingGossipingRequestManager @Inject constructor(
      * @param event the announcement event.
      */
     fun onGossipingRequestEvent(event: Event) {
-        Timber.v("## GOSSIP onGossipingRequestEvent type ${event.type} from user ${event.senderId}")
+        Timber.v("## CRYPTO | GOSSIP onGossipingRequestEvent type ${event.type} from user ${event.senderId}")
         val roomKeyShare = event.getClearContent().toModel<GossipingDefaultContent>()
         val ageLocalTs = event.unsignedData?.age?.let { System.currentTimeMillis() - it }
         when (roomKeyShare?.action) {
@@ -155,7 +161,7 @@ internal class IncomingGossipingRequestManager @Inject constructor(
         }
 
         receivedRequestCancellations?.forEach { request ->
-            Timber.v("## GOSSIP processReceivedGossipingRequests() : m.room_key_request cancellation $request")
+            Timber.v("## CRYPTO | GOSSIP processReceivedGossipingRequests() : m.room_key_request cancellation $request")
             // we should probably only notify the app of cancellations we told it
             // about, but we don't currently have a record of that, so we just pass
             // everything through.
@@ -178,17 +184,42 @@ internal class IncomingGossipingRequestManager @Inject constructor(
     }
 
     private fun processIncomingRoomKeyRequest(request: IncomingRoomKeyRequest) {
-        val userId = request.userId
-        val deviceId = request.deviceId
-        val body = request.requestBody
-        val roomId = body!!.roomId
-        val alg = body.algorithm
+        val userId = request.userId ?: return
+        val deviceId = request.deviceId ?: return
+        val body = request.requestBody ?: return
+        val roomId = body.roomId ?: return
+        val alg = body.algorithm ?: return
 
-        Timber.v("## GOSSIP processIncomingRoomKeyRequest from $userId:$deviceId for $roomId / ${body.sessionId} id ${request.requestId}")
-        if (userId == null || credentials.userId != userId) {
-            // TODO: determine if we sent this device the keys already: in
-            Timber.w("## GOSSIP processReceivedGossipingRequests() : Ignoring room key request from other user for now")
-            cryptoStore.updateGossipingRequestState(request, GossipingRequestState.REJECTED)
+        Timber.v("## CRYPTO | GOSSIP processIncomingRoomKeyRequest from $userId:$deviceId for $roomId / ${body.sessionId} id ${request.requestId}")
+        if (credentials.userId != userId) {
+            Timber.w("## CRYPTO | GOSSIP processReceivedGossipingRequests() : room key request from other user")
+            val senderKey = body.senderKey ?: return Unit
+                    .also { Timber.w("missing senderKey") }
+                    .also { cryptoStore.updateGossipingRequestState(request, GossipingRequestState.REJECTED) }
+            val sessionId = body.sessionId ?: return Unit
+                    .also { Timber.w("missing sessionId") }
+                    .also { cryptoStore.updateGossipingRequestState(request, GossipingRequestState.REJECTED) }
+
+            if (alg != MXCRYPTO_ALGORITHM_MEGOLM) {
+                return Unit
+                        .also { Timber.w("Only megolm is accepted here") }
+                        .also { cryptoStore.updateGossipingRequestState(request, GossipingRequestState.REJECTED) }
+            }
+
+            val roomEncryptor = roomEncryptorsStore.get(roomId) ?: return Unit
+                    .also { Timber.w("no room Encryptor") }
+                    .also { cryptoStore.updateGossipingRequestState(request, GossipingRequestState.REJECTED) }
+
+            cryptoCoroutineScope.launch(coroutineDispatchers.crypto) {
+                val isSuccess = roomEncryptor.reshareKey(sessionId, userId, deviceId, senderKey)
+
+                if (isSuccess) {
+                    cryptoStore.updateGossipingRequestState(request, GossipingRequestState.ACCEPTED)
+                } else {
+                    cryptoStore.updateGossipingRequestState(request, GossipingRequestState.UNABLE_TO_PROCESS)
+                }
+            }
+            cryptoStore.updateGossipingRequestState(request, GossipingRequestState.RE_REQUESTED)
             return
         }
         // TODO: should we queue up requests we don't yet have keys for, in case they turn up later?
@@ -196,18 +227,18 @@ internal class IncomingGossipingRequestManager @Inject constructor(
         // the keys for the requested events, and can drop the requests.
         val decryptor = roomDecryptorProvider.getRoomDecryptor(roomId, alg)
         if (null == decryptor) {
-            Timber.w("## GOSSIP processReceivedGossipingRequests() : room key request for unknown $alg in room $roomId")
+            Timber.w("## CRYPTO | GOSSIP processReceivedGossipingRequests() : room key request for unknown $alg in room $roomId")
             cryptoStore.updateGossipingRequestState(request, GossipingRequestState.REJECTED)
             return
         }
         if (!decryptor.hasKeysForKeyRequest(request)) {
-            Timber.w("## GOSSIP processReceivedGossipingRequests() : room key request for unknown session ${body.sessionId!!}")
+            Timber.w("## CRYPTO | GOSSIP processReceivedGossipingRequests() : room key request for unknown session ${body.sessionId!!}")
             cryptoStore.updateGossipingRequestState(request, GossipingRequestState.REJECTED)
             return
         }
 
         if (credentials.deviceId == deviceId && credentials.userId == userId) {
-            Timber.v("## GOSSIP processReceivedGossipingRequests() : oneself device - ignored")
+            Timber.v("## CRYPTO | GOSSIP processReceivedGossipingRequests() : oneself device - ignored")
             cryptoStore.updateGossipingRequestState(request, GossipingRequestState.REJECTED)
             return
         }
@@ -219,16 +250,16 @@ internal class IncomingGossipingRequestManager @Inject constructor(
             cryptoStore.updateGossipingRequestState(request, GossipingRequestState.REJECTED)
         }
         // if the device is verified already, share the keys
-        val device = cryptoStore.getUserDevice(userId, deviceId!!)
+        val device = cryptoStore.getUserDevice(userId, deviceId)
         if (device != null) {
             if (device.isVerified) {
-                Timber.v("## GOSSIP processReceivedGossipingRequests() : device is already verified: sharing keys")
+                Timber.v("## CRYPTO | GOSSIP processReceivedGossipingRequests() : device is already verified: sharing keys")
                 request.share?.run()
                 return
             }
 
             if (device.isBlocked) {
-                Timber.v("## GOSSIP processReceivedGossipingRequests() : device is blocked -> ignored")
+                Timber.v("## CRYPTO | GOSSIP processReceivedGossipingRequests() : device is blocked -> ignored")
                 cryptoStore.updateGossipingRequestState(request, GossipingRequestState.REJECTED)
                 return
             }
@@ -236,7 +267,7 @@ internal class IncomingGossipingRequestManager @Inject constructor(
 
         // As per config we automatically discard untrusted devices request
         if (cryptoConfig.discardRoomKeyRequestsFromUntrustedDevices) {
-            Timber.v("## processReceivedGossipingRequests() : discardRoomKeyRequestsFromUntrustedDevices")
+            Timber.v("## CRYPTO | processReceivedGossipingRequests() : discardRoomKeyRequestsFromUntrustedDevices")
             // At this point the device is unknown, we don't want to bother user with that
             cryptoStore.updateGossipingRequestState(request, GossipingRequestState.REJECTED)
             return
@@ -249,30 +280,30 @@ internal class IncomingGossipingRequestManager @Inject constructor(
     private fun processIncomingSecretShareRequest(request: IncomingSecretShareRequest) {
         val secretName = request.secretName ?: return Unit.also {
             cryptoStore.updateGossipingRequestState(request, GossipingRequestState.REJECTED)
-            Timber.v("## GOSSIP processIncomingSecretShareRequest() : Missing secret name")
+            Timber.v("## CRYPTO | GOSSIP processIncomingSecretShareRequest() : Missing secret name")
         }
 
         val userId = request.userId
         if (userId == null || credentials.userId != userId) {
-            Timber.e("## GOSSIP processIncomingSecretShareRequest() : Ignoring secret share request from other users")
+            Timber.e("## CRYPTO | GOSSIP processIncomingSecretShareRequest() : Ignoring secret share request from other users")
             cryptoStore.updateGossipingRequestState(request, GossipingRequestState.REJECTED)
             return
         }
 
         val deviceId = request.deviceId
                 ?: return Unit.also {
-                    Timber.e("## GOSSIP processIncomingSecretShareRequest() : Malformed request, no ")
+                    Timber.e("## CRYPTO | GOSSIP processIncomingSecretShareRequest() : Malformed request, no ")
                     cryptoStore.updateGossipingRequestState(request, GossipingRequestState.REJECTED)
                 }
 
         val device = cryptoStore.getUserDevice(userId, deviceId)
                 ?: return Unit.also {
-                    Timber.e("## GOSSIP processIncomingSecretShareRequest() : Received secret share request from unknown device ${request.deviceId}")
+                    Timber.e("## CRYPTO | GOSSIP processIncomingSecretShareRequest() : Received secret share request from unknown device ${request.deviceId}")
                     cryptoStore.updateGossipingRequestState(request, GossipingRequestState.REJECTED)
                 }
 
         if (!device.isVerified || device.isBlocked) {
-            Timber.v("## GOSSIP processIncomingSecretShareRequest() : Ignoring secret share request from untrusted/blocked session $device")
+            Timber.v("## CRYPTO | GOSSIP processIncomingSecretShareRequest() : Ignoring secret share request from untrusted/blocked session $device")
             cryptoStore.updateGossipingRequestState(request, GossipingRequestState.REJECTED)
             return
         }
@@ -289,7 +320,7 @@ internal class IncomingGossipingRequestManager @Inject constructor(
                     }
             else                       -> null
         }?.let { secretValue ->
-            Timber.i("## GOSSIP processIncomingSecretShareRequest() : Sharing secret $secretName with $device locally trusted")
+            Timber.i("## CRYPTO | GOSSIP processIncomingSecretShareRequest() : Sharing secret $secretName with $device locally trusted")
             if (isDeviceLocallyVerified == true && hasBeenVerifiedLessThanFiveMinutesFromNow(deviceId)) {
                 val params = SendGossipWorker.Params(
                         sessionId = sessionId,
@@ -301,13 +332,13 @@ internal class IncomingGossipingRequestManager @Inject constructor(
                 val workRequest = gossipingWorkManager.createWork<SendGossipWorker>(WorkerParamsFactory.toData(params), true)
                 gossipingWorkManager.postWork(workRequest)
             } else {
-                Timber.v("## GOSSIP processIncomingSecretShareRequest() : Can't share secret $secretName with $device, verification too old")
+                Timber.v("## CRYPTO | GOSSIP processIncomingSecretShareRequest() : Can't share secret $secretName with $device, verification too old")
                 cryptoStore.updateGossipingRequestState(request, GossipingRequestState.REJECTED)
             }
             return
         }
 
-        Timber.v("## GOSSIP processIncomingSecretShareRequest() : $secretName unknown at SDK level, asking to app layer")
+        Timber.v("## CRYPTO | GOSSIP processIncomingSecretShareRequest() : $secretName unknown at SDK level, asking to app layer")
 
         request.ignore = Runnable {
             cryptoStore.updateGossipingRequestState(request, GossipingRequestState.REJECTED)
@@ -341,7 +372,7 @@ internal class IncomingGossipingRequestManager @Inject constructor(
                 try {
                     listener.onRoomKeyRequest(request)
                 } catch (e: Exception) {
-                    Timber.e(e, "## onRoomKeyRequest() failed")
+                    Timber.e(e, "## CRYPTO | onRoomKeyRequest() failed")
                 }
             }
         }
@@ -358,7 +389,7 @@ internal class IncomingGossipingRequestManager @Inject constructor(
                         return
                     }
                 } catch (e: Exception) {
-                    Timber.e(e, "## GOSSIP onRoomKeyRequest() failed")
+                    Timber.e(e, "## CRYPTO | GOSSIP onRoomKeyRequest() failed")
                 }
             }
         }
@@ -377,7 +408,7 @@ internal class IncomingGossipingRequestManager @Inject constructor(
                 try {
                     listener.onRoomKeyRequestCancellation(request)
                 } catch (e: Exception) {
-                    Timber.e(e, "## GOSSIP onRoomKeyRequestCancellation() failed")
+                    Timber.e(e, "## CRYPTO | GOSSIP onRoomKeyRequestCancellation() failed")
                 }
             }
         }
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/MXOlmDevice.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/MXOlmDevice.kt
index 86f0768a7d..9e116d8223 100755
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/MXOlmDevice.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/MXOlmDevice.kt
@@ -21,7 +21,7 @@ import im.vector.matrix.android.api.session.crypto.MXCryptoError
 import im.vector.matrix.android.api.util.JSON_DICT_PARAMETERIZED_TYPE
 import im.vector.matrix.android.api.util.JsonDict
 import im.vector.matrix.android.internal.crypto.algorithms.olm.OlmDecryptionResult
-import im.vector.matrix.android.internal.crypto.model.OlmInboundGroupSessionWrapper
+import im.vector.matrix.android.internal.crypto.model.OlmInboundGroupSessionWrapper2
 import im.vector.matrix.android.internal.crypto.model.OlmSessionWrapper
 import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore
 import im.vector.matrix.android.internal.di.MoshiProvider
@@ -342,6 +342,8 @@ internal class MXOlmDevice @Inject constructor(
             } catch (e: Exception) {
                 Timber.e(e, "## encryptMessage() : failed")
             }
+        } else {
+            Timber.e("## encryptMessage() : Failed to encrypt unknown session $sessionId")
         }
 
         return res
@@ -486,7 +488,7 @@ internal class MXOlmDevice @Inject constructor(
                                forwardingCurve25519KeyChain: List<String>,
                                keysClaimed: Map<String, String>,
                                exportFormat: Boolean): Boolean {
-        val session = OlmInboundGroupSessionWrapper(sessionKey, exportFormat)
+        val session = OlmInboundGroupSessionWrapper2(sessionKey, exportFormat)
         runCatching { getInboundGroupSession(sessionId, senderKey, roomId) }
                 .fold(
                         {
@@ -541,18 +543,18 @@ internal class MXOlmDevice @Inject constructor(
      * @param megolmSessionsData the megolm sessions data
      * @return the successfully imported sessions.
      */
-    fun importInboundGroupSessions(megolmSessionsData: List<MegolmSessionData>): List<OlmInboundGroupSessionWrapper> {
-        val sessions = ArrayList<OlmInboundGroupSessionWrapper>(megolmSessionsData.size)
+    fun importInboundGroupSessions(megolmSessionsData: List<MegolmSessionData>): List<OlmInboundGroupSessionWrapper2> {
+        val sessions = ArrayList<OlmInboundGroupSessionWrapper2>(megolmSessionsData.size)
 
         for (megolmSessionData in megolmSessionsData) {
             val sessionId = megolmSessionData.sessionId
             val senderKey = megolmSessionData.senderKey
             val roomId = megolmSessionData.roomId
 
-            var session: OlmInboundGroupSessionWrapper? = null
+            var session: OlmInboundGroupSessionWrapper2? = null
 
             try {
-                session = OlmInboundGroupSessionWrapper(megolmSessionData)
+                session = OlmInboundGroupSessionWrapper2(megolmSessionData)
             } catch (e: Exception) {
                 Timber.e(e, "## importInboundGroupSession() : Update for megolm session $senderKey/$sessionId")
             }
@@ -625,6 +627,7 @@ internal class MXOlmDevice @Inject constructor(
      * @param senderKey the base64-encoded curve25519 key of the sender.
      * @return the decrypting result. Nil if the sessionId is unknown.
      */
+    @Throws(MXCryptoError::class)
     fun decryptGroupMessage(body: String,
                             roomId: String,
                             timeline: String?,
@@ -662,8 +665,7 @@ internal class MXOlmDevice @Inject constructor(
                 adapter.fromJson(payloadString)
             } catch (e: Exception) {
                 Timber.e("## decryptGroupMessage() : fails to parse the payload")
-                throw
-                MXCryptoError.Base(MXCryptoError.ErrorType.BAD_DECRYPTED_FORMAT, MXCryptoError.BAD_DECRYPTED_FORMAT_TEXT_REASON)
+                throw MXCryptoError.Base(MXCryptoError.ErrorType.BAD_DECRYPTED_FORMAT, MXCryptoError.BAD_DECRYPTED_FORMAT_TEXT_REASON)
             }
 
             return OlmDecryptionResult(
@@ -739,7 +741,7 @@ internal class MXOlmDevice @Inject constructor(
      * @param senderKey the base64-encoded curve25519 key of the sender.
      * @return the inbound group session.
      */
-    fun getInboundGroupSession(sessionId: String?, senderKey: String?, roomId: String?): OlmInboundGroupSessionWrapper {
+    fun getInboundGroupSession(sessionId: String?, senderKey: String?, roomId: String?): OlmInboundGroupSessionWrapper2 {
         if (sessionId.isNullOrBlank() || senderKey.isNullOrBlank()) {
             throw MXCryptoError.Base(MXCryptoError.ErrorType.MISSING_SENDER_KEY, MXCryptoError.ERROR_MISSING_PROPERTY_REASON)
         }
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/OutgoingGossipingRequestManager.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/OutgoingGossipingRequestManager.kt
index c06f10b106..eb1c07cb92 100755
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/OutgoingGossipingRequestManager.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/OutgoingGossipingRequestManager.kt
@@ -55,7 +55,7 @@ internal class OutgoingGossipingRequestManager @Inject constructor(
             cryptoStore.getOrAddOutgoingRoomKeyRequest(requestBody, recipients)?.let {
                 // Don't resend if it's already done, you need to cancel first (reRequest)
                 if (it.state == OutgoingGossipingRequestState.SENDING || it.state == OutgoingGossipingRequestState.SENT) {
-                    Timber.v("## GOSSIP sendOutgoingRoomKeyRequest() : we already request for that session: $it")
+                    Timber.v("## CRYPTO - GOSSIP sendOutgoingRoomKeyRequest() : we already request for that session: $it")
                     return@launch
                 }
 
@@ -72,7 +72,7 @@ internal class OutgoingGossipingRequestManager @Inject constructor(
             cryptoStore.getOrAddOutgoingSecretShareRequest(secretName, recipients)?.let {
                 // TODO check if there is already one that is being sent?
                 if (it.state == OutgoingGossipingRequestState.SENDING || it.state == OutgoingGossipingRequestState.SENT) {
-                    Timber.v("## GOSSIP sendSecretShareRequest() : we already request for that session: $it")
+                    Timber.v("## CRYPTO - GOSSIP sendSecretShareRequest() : we already request for that session: $it")
                     return@launch
                 }
 
@@ -113,7 +113,7 @@ internal class OutgoingGossipingRequestManager @Inject constructor(
         val req = cryptoStore.getOutgoingRoomKeyRequest(requestBody)
                 ?: // no request was made for this key
                 return Unit.also {
-                    Timber.v("## GOSSIP cancelRoomKeyRequest() Unknown request")
+                    Timber.v("## CRYPTO - GOSSIP cancelRoomKeyRequest() Unknown request $requestBody")
                 }
 
         sendOutgoingRoomKeyRequestCancellation(req, andResend)
@@ -125,7 +125,7 @@ internal class OutgoingGossipingRequestManager @Inject constructor(
      * @param request the request
      */
     private fun sendOutgoingGossipingRequest(request: OutgoingGossipingRequest) {
-        Timber.v("## GOSSIP sendOutgoingRoomKeyRequest() : Requesting keys $request")
+        Timber.v("## CRYPTO - GOSSIP sendOutgoingRoomKeyRequest() : Requesting keys $request")
 
         val params = SendGossipRequestWorker.Params(
                 sessionId = sessionId,
@@ -143,7 +143,7 @@ internal class OutgoingGossipingRequestManager @Inject constructor(
      * @param request the request
      */
     private fun sendOutgoingRoomKeyRequestCancellation(request: OutgoingRoomKeyRequest, resend: Boolean = false) {
-        Timber.v("$request")
+        Timber.v("## CRYPTO - sendOutgoingRoomKeyRequestCancellation $request")
         val params = CancelGossipRequestWorker.Params.fromRequest(sessionId, request)
         cryptoStore.updateOutgoingGossipingRequestState(request.requestId, OutgoingGossipingRequestState.CANCELLING)
 
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/RoomEncryptorsStore.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/RoomEncryptorsStore.kt
new file mode 100644
index 0000000000..52a324d68d
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/RoomEncryptorsStore.kt
@@ -0,0 +1,40 @@
+/*
+ * 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.matrix.android.internal.crypto
+
+import im.vector.matrix.android.internal.crypto.algorithms.IMXEncrypting
+import im.vector.matrix.android.internal.session.SessionScope
+import javax.inject.Inject
+
+@SessionScope
+internal class RoomEncryptorsStore @Inject constructor() {
+
+    // MXEncrypting instance for each room.
+    private val roomEncryptors = mutableMapOf<String, IMXEncrypting>()
+
+    fun put(roomId: String, alg: IMXEncrypting) {
+        synchronized(roomEncryptors) {
+            roomEncryptors.put(roomId, alg)
+        }
+    }
+
+    fun get(roomId: String): IMXEncrypting? {
+        return synchronized(roomEncryptors) {
+            roomEncryptors[roomId]
+        }
+    }
+}
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/actions/EnsureOlmSessionsForDevicesAction.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/actions/EnsureOlmSessionsForDevicesAction.kt
index e1cac0d75f..e630d14eab 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/actions/EnsureOlmSessionsForDevicesAction.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/actions/EnsureOlmSessionsForDevicesAction.kt
@@ -25,10 +25,11 @@ import im.vector.matrix.android.internal.crypto.tasks.ClaimOneTimeKeysForUsersDe
 import timber.log.Timber
 import javax.inject.Inject
 
-internal class EnsureOlmSessionsForDevicesAction @Inject constructor(private val olmDevice: MXOlmDevice,
-                                                                     private val oneTimeKeysForUsersDeviceTask: ClaimOneTimeKeysForUsersDeviceTask) {
+internal class EnsureOlmSessionsForDevicesAction @Inject constructor(
+        private val olmDevice: MXOlmDevice,
+        private val oneTimeKeysForUsersDeviceTask: ClaimOneTimeKeysForUsersDeviceTask) {
 
-    suspend fun handle(devicesByUser: Map<String, List<CryptoDeviceInfo>>): MXUsersDevicesMap<MXOlmSessionResult> {
+    suspend fun handle(devicesByUser: Map<String, List<CryptoDeviceInfo>>, force: Boolean = false): MXUsersDevicesMap<MXOlmSessionResult> {
         val devicesWithoutSession = ArrayList<CryptoDeviceInfo>()
 
         val results = MXUsersDevicesMap<MXOlmSessionResult>()
@@ -40,7 +41,7 @@ internal class EnsureOlmSessionsForDevicesAction @Inject constructor(private val
 
                 val sessionId = olmDevice.getSessionId(key!!)
 
-                if (sessionId.isNullOrEmpty()) {
+                if (sessionId.isNullOrEmpty() || force) {
                     devicesWithoutSession.add(deviceInfo)
                 }
 
@@ -68,11 +69,11 @@ internal class EnsureOlmSessionsForDevicesAction @Inject constructor(private val
         //
         // That should eventually resolve itself, but it's poor form.
 
-        Timber.v("## claimOneTimeKeysForUsersDevices() : $usersDevicesToClaim")
+        Timber.v("## CRYPTO | claimOneTimeKeysForUsersDevices() : $usersDevicesToClaim")
 
         val claimParams = ClaimOneTimeKeysForUsersDeviceTask.Params(usersDevicesToClaim)
         val oneTimeKeys = oneTimeKeysForUsersDeviceTask.execute(claimParams)
-        Timber.v("## claimOneTimeKeysForUsersDevices() : keysClaimResponse.oneTimeKeys: $oneTimeKeys")
+        Timber.v("## CRYPTO | claimOneTimeKeysForUsersDevices() : keysClaimResponse.oneTimeKeys: $oneTimeKeys")
         for ((userId, deviceInfos) in devicesByUser) {
             for (deviceInfo in deviceInfos) {
                 var oneTimeKey: MXKey? = null
@@ -80,7 +81,7 @@ internal class EnsureOlmSessionsForDevicesAction @Inject constructor(private val
                 if (null != deviceIds) {
                     for (deviceId in deviceIds) {
                         val olmSessionResult = results.getObject(userId, deviceId)
-                        if (olmSessionResult!!.sessionId != null) {
+                        if (olmSessionResult!!.sessionId != null && !force) {
                             // We already have a result for this device
                             continue
                         }
@@ -89,7 +90,7 @@ internal class EnsureOlmSessionsForDevicesAction @Inject constructor(private val
                             oneTimeKey = key
                         }
                         if (oneTimeKey == null) {
-                            Timber.v("## ensureOlmSessionsForDevices() : No one-time keys " + oneTimeKeyAlgorithm
+                            Timber.v("## CRYPTO | ensureOlmSessionsForDevices() : No one-time keys " + oneTimeKeyAlgorithm
                                     + " for device " + userId + " : " + deviceId)
                             continue
                         }
@@ -125,14 +126,14 @@ internal class EnsureOlmSessionsForDevicesAction @Inject constructor(private val
                 sessionId = olmDevice.createOutboundSession(deviceInfo.identityKey()!!, oneTimeKey.value)
 
                 if (!sessionId.isNullOrEmpty()) {
-                    Timber.v("## verifyKeyAndStartSession() : Started new sessionid " + sessionId
+                    Timber.v("## CRYPTO | verifyKeyAndStartSession() : Started new sessionid " + sessionId
                             + " for device " + deviceInfo + "(theirOneTimeKey: " + oneTimeKey.value + ")")
                 } else {
                     // Possibly a bad key
-                    Timber.e("## verifyKeyAndStartSession() : Error starting session with device $userId:$deviceId")
+                    Timber.e("## CRYPTO | verifyKeyAndStartSession() : Error starting session with device $userId:$deviceId")
                 }
             } else {
-                Timber.e("## verifyKeyAndStartSession() : Unable to verify signature on one-time key for device " + userId
+                Timber.e("## CRYPTO | verifyKeyAndStartSession() : Unable to verify signature on one-time key for device " + userId
                         + ":" + deviceId + " Error " + errorMessage)
             }
         }
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/actions/MessageEncrypter.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/actions/MessageEncrypter.kt
index fae205e581..c1cdbe59f9 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/actions/MessageEncrypter.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/actions/MessageEncrypter.kt
@@ -16,19 +16,24 @@
 
 package im.vector.matrix.android.internal.crypto.actions
 
-import im.vector.matrix.android.api.auth.data.Credentials
+import im.vector.matrix.android.api.session.events.model.Content
 import im.vector.matrix.android.internal.crypto.MXCRYPTO_ALGORITHM_OLM
 import im.vector.matrix.android.internal.crypto.MXOlmDevice
 import im.vector.matrix.android.internal.crypto.model.CryptoDeviceInfo
 import im.vector.matrix.android.internal.crypto.model.rest.EncryptedMessage
+import im.vector.matrix.android.internal.di.DeviceId
+import im.vector.matrix.android.internal.di.UserId
 import im.vector.matrix.android.internal.util.JsonCanonicalizer
 import im.vector.matrix.android.internal.util.convertToUTF8
 import timber.log.Timber
 import javax.inject.Inject
 
-internal class MessageEncrypter @Inject constructor(private val credentials: Credentials,
-                                                    private val olmDevice: MXOlmDevice) {
-
+internal class MessageEncrypter @Inject constructor(
+        @UserId
+        private val userId: String,
+        @DeviceId
+        private val deviceId: String?,
+        private val olmDevice: MXOlmDevice) {
     /**
      * Encrypt an event payload for a list of devices.
      * This method must be called from the getCryptoHandler() thread.
@@ -37,13 +42,13 @@ internal class MessageEncrypter @Inject constructor(private val credentials: Cre
      * @param deviceInfos   list of device infos to encrypt for.
      * @return the content for an m.room.encrypted event.
      */
-    fun encryptMessage(payloadFields: Map<String, Any>, deviceInfos: List<CryptoDeviceInfo>): EncryptedMessage {
+    fun encryptMessage(payloadFields: Content, deviceInfos: List<CryptoDeviceInfo>): EncryptedMessage {
         val deviceInfoParticipantKey = deviceInfos.associateBy { it.identityKey()!! }
 
         val payloadJson = payloadFields.toMutableMap()
 
-        payloadJson["sender"] = credentials.userId
-        payloadJson["sender_device"] = credentials.deviceId!!
+        payloadJson["sender"] = userId
+        payloadJson["sender_device"] = deviceId!!
 
         // Include the Ed25519 key so that the recipient knows what
         // device this message came from.
@@ -53,11 +58,9 @@ internal class MessageEncrypter @Inject constructor(private val credentials: Cre
         // homeserver signed by the ed25519 key this proves that
         // the curve25519 key and the ed25519 key are owned by
         // the same device.
-        val keysMap = HashMap<String, String>()
-        keysMap["ed25519"] = olmDevice.deviceEd25519Key!!
-        payloadJson["keys"] = keysMap
+        payloadJson["keys"] = mapOf("ed25519" to olmDevice.deviceEd25519Key!!)
 
-        val ciphertext = HashMap<String, Any>()
+        val ciphertext = mutableMapOf<String, Any>()
 
         for ((deviceKey, deviceInfo) in deviceInfoParticipantKey) {
             val sessionId = olmDevice.getSessionId(deviceKey)
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/actions/SetDeviceVerificationAction.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/actions/SetDeviceVerificationAction.kt
index d6538f041d..d9fa8d5955 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/actions/SetDeviceVerificationAction.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/actions/SetDeviceVerificationAction.kt
@@ -48,7 +48,7 @@ internal class SetDeviceVerificationAction @Inject constructor(
 
         if (device.trustLevel != trustLevel) {
             device.trustLevel = trustLevel
-            cryptoStore.storeUserDevice(userId, device)
+            cryptoStore.setDeviceTrust(userId, deviceId, trustLevel.crossSigningVerified, trustLevel.locallyVerified)
         }
     }
 }
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/IMXDecrypting.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/IMXDecrypting.kt
index e9176ad6d9..0babb73842 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/IMXDecrypting.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/IMXDecrypting.kt
@@ -17,6 +17,7 @@
 
 package im.vector.matrix.android.internal.crypto.algorithms
 
+import im.vector.matrix.android.api.session.crypto.MXCryptoError
 import im.vector.matrix.android.api.session.events.model.Event
 import im.vector.matrix.android.internal.crypto.IncomingRoomKeyRequest
 import im.vector.matrix.android.internal.crypto.IncomingSecretShareRequest
@@ -35,6 +36,7 @@ internal interface IMXDecrypting {
      * @param timeline the id of the timeline where the event is decrypted. It is used to prevent replay attack.
      * @return the decryption information, or an error
      */
+    @Throws(MXCryptoError::class)
     fun decryptEvent(event: Event, timeline: String): MXEventDecryptionResult
 
     /**
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/IMXEncrypting.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/IMXEncrypting.kt
index 555ce9dfd4..ddf605def4 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/IMXEncrypting.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/IMXEncrypting.kt
@@ -33,4 +33,34 @@ internal interface IMXEncrypting {
      * @return the encrypted content
      */
     suspend fun encryptEventContent(eventContent: Content, eventType: String, userIds: List<String>): Content
+
+    /**
+     * In Megolm, each recipient maintains a record of the ratchet value which allows
+     * them to decrypt any messages sent in the session after the corresponding point
+     * in the conversation. If this value is compromised, an attacker can similarly
+     * decrypt past messages which were encrypted by a key derived from the
+     * compromised or subsequent ratchet values. This gives 'partial' forward
+     * secrecy.
+     *
+     * To mitigate this issue, the application should offer the user the option to
+     * discard historical conversations, by winding forward any stored ratchet values,
+     * or discarding sessions altogether.
+     */
+    fun discardSessionKey()
+
+    /**
+     * Re-shares a session key with devices if the key has already been
+     * sent to them.
+     *
+     * @param sessionId The id of the outbound session to share.
+     * @param userId The id of the user who owns the target device.
+     * @param deviceId The id of the target device.
+     * @param senderKey The key of the originating device for the session.
+     *
+     * @return true in case of success
+     */
+    suspend fun reshareKey(sessionId: String,
+                           userId: String,
+                           deviceId: String,
+                           senderKey: String): Boolean
 }
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/megolm/MXMegolmDecryption.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/megolm/MXMegolmDecryption.kt
index 1d7a2765fa..59ffa5f874 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/megolm/MXMegolmDecryption.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/megolm/MXMegolmDecryption.kt
@@ -63,6 +63,7 @@ internal class MXMegolmDecryption(private val userId: String,
      */
     private var pendingEvents: MutableMap<String /* senderKey|sessionId */, MutableMap<String /* timelineId */, MutableList<Event>>> = HashMap()
 
+    @Throws(MXCryptoError::class)
     override fun decryptEvent(event: Event, timeline: String): MXEventDecryptionResult {
         // If cross signing is enabled, we don't send request until the keys are trusted
         // There could be a race effect here when xsigning is enabled, we should ensure that keys was downloaded once
@@ -70,7 +71,9 @@ internal class MXMegolmDecryption(private val userId: String,
         return decryptEvent(event, timeline, requestOnFail)
     }
 
+    @Throws(MXCryptoError::class)
     private fun decryptEvent(event: Event, timeline: String, requestKeysOnFail: Boolean): MXEventDecryptionResult {
+        Timber.v("## CRYPTO | decryptEvent ${event.eventId} , requestKeysOnFail:$requestKeysOnFail")
         if (event.roomId.isNullOrBlank()) {
             throw MXCryptoError.Base(MXCryptoError.ErrorType.MISSING_FIELDS, MXCryptoError.MISSING_FIELDS_REASON)
         }
@@ -188,7 +191,7 @@ internal class MXMegolmDecryption(private val userId: String,
         val events = timeline.getOrPut(timelineId) { ArrayList() }
 
         if (event !in events) {
-            Timber.v("## addEventToPendingList() : add Event ${event.eventId} in room id ${event.roomId}")
+            Timber.v("## CRYPTO | addEventToPendingList() : add Event ${event.eventId} in room id ${event.roomId}")
             events.add(event)
         }
     }
@@ -199,6 +202,7 @@ internal class MXMegolmDecryption(private val userId: String,
      * @param event the key event.
      */
     override fun onRoomKeyEvent(event: Event, defaultKeysBackupService: DefaultKeysBackupService) {
+        Timber.v("## CRYPTO | onRoomKeyEvent()")
         var exportFormat = false
         val roomKeyContent = event.getClearContent().toModel<RoomKeyContent>() ?: return
 
@@ -207,11 +211,11 @@ internal class MXMegolmDecryption(private val userId: String,
         val forwardingCurve25519KeyChain: MutableList<String> = ArrayList()
 
         if (roomKeyContent.roomId.isNullOrEmpty() || roomKeyContent.sessionId.isNullOrEmpty() || roomKeyContent.sessionKey.isNullOrEmpty()) {
-            Timber.e("## onRoomKeyEvent() :  Key event is missing fields")
+            Timber.e("## CRYPTO | onRoomKeyEvent() :  Key event is missing fields")
             return
         }
         if (event.getClearType() == EventType.FORWARDED_ROOM_KEY) {
-            Timber.v("## onRoomKeyEvent(), forward adding key : roomId ${roomKeyContent.roomId}" +
+            Timber.v("## CRYPTO | onRoomKeyEvent(), forward adding key : roomId ${roomKeyContent.roomId}" +
                     " sessionId ${roomKeyContent.sessionId} sessionKey ${roomKeyContent.sessionKey}")
             val forwardedRoomKeyContent = event.getClearContent().toModel<ForwardedRoomKeyContent>()
                     ?: return
@@ -221,7 +225,7 @@ internal class MXMegolmDecryption(private val userId: String,
             }
 
             if (senderKey == null) {
-                Timber.e("## onRoomKeyEvent() : event is missing sender_key field")
+                Timber.e("## CRYPTO | onRoomKeyEvent() : event is missing sender_key field")
                 return
             }
 
@@ -230,18 +234,18 @@ internal class MXMegolmDecryption(private val userId: String,
             exportFormat = true
             senderKey = forwardedRoomKeyContent.senderKey
             if (null == senderKey) {
-                Timber.e("## onRoomKeyEvent() : forwarded_room_key event is missing sender_key field")
+                Timber.e("## CRYPTO | onRoomKeyEvent() : forwarded_room_key event is missing sender_key field")
                 return
             }
 
             if (null == forwardedRoomKeyContent.senderClaimedEd25519Key) {
-                Timber.e("## forwarded_room_key_event is missing sender_claimed_ed25519_key field")
+                Timber.e("## CRYPTO | forwarded_room_key_event is missing sender_claimed_ed25519_key field")
                 return
             }
 
             keysClaimed["ed25519"] = forwardedRoomKeyContent.senderClaimedEd25519Key
         } else {
-            Timber.v("## onRoomKeyEvent(), Adding key : roomId " + roomKeyContent.roomId + " sessionId " + roomKeyContent.sessionId
+            Timber.v("## CRYPTO | onRoomKeyEvent(), Adding key : roomId " + roomKeyContent.roomId + " sessionId " + roomKeyContent.sessionId
                     + " sessionKey " + roomKeyContent.sessionKey) // from " + event);
 
             if (null == senderKey) {
@@ -253,6 +257,7 @@ internal class MXMegolmDecryption(private val userId: String,
             keysClaimed = event.getKeysClaimed().toMutableMap()
         }
 
+        Timber.e("## CRYPTO | onRoomKeyEvent addInboundGroupSession ${roomKeyContent.sessionId}")
         val added = olmDevice.addInboundGroupSession(roomKeyContent.sessionId,
                 roomKeyContent.sessionKey,
                 roomKeyContent.roomId,
@@ -284,7 +289,7 @@ internal class MXMegolmDecryption(private val userId: String,
      * @param sessionId the session id
      */
     override fun onNewSession(senderKey: String, sessionId: String) {
-        Timber.v("ON NEW SESSION $sessionId - $senderKey")
+        Timber.v(" CRYPTO | ON NEW SESSION $sessionId - $senderKey")
         newSessionListener?.onNewSession(null, senderKey, sessionId)
     }
 
@@ -318,7 +323,7 @@ internal class MXMegolmDecryption(private val userId: String,
                                 // were no one-time keys.
                                 return@mapCatching
                             }
-                            Timber.v("## shareKeysWithDevice() : sharing keys for session" +
+                            Timber.v("## CRYPTO | shareKeysWithDevice() : sharing keys for session" +
                                     " ${body.senderKey}|${body.sessionId} with device $userId:$deviceId")
 
                             val payloadJson = mutableMapOf<String, Any>("type" to EventType.FORWARDED_ROOM_KEY)
@@ -337,7 +342,7 @@ internal class MXMegolmDecryption(private val userId: String,
                             val encodedPayload = messageEncrypter.encryptMessage(payloadJson, listOf(deviceInfo))
                             val sendToDeviceMap = MXUsersDevicesMap<Any>()
                             sendToDeviceMap.setObject(userId, deviceId, encodedPayload)
-                            Timber.v("## shareKeysWithDevice() : sending to $userId:$deviceId")
+                            Timber.v("## CRYPTO | shareKeysWithDevice() : sending to $userId:$deviceId")
                             val sendToDeviceParams = SendToDeviceTask.Params(EventType.ENCRYPTED, sendToDeviceMap)
                             sendToDeviceTask.execute(sendToDeviceParams)
                         }
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/megolm/MXMegolmEncryption.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/megolm/MXMegolmEncryption.kt
index a2d21c4f89..3800e3c4f2 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/megolm/MXMegolmEncryption.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/megolm/MXMegolmEncryption.kt
@@ -40,7 +40,7 @@ import timber.log.Timber
 
 internal class MXMegolmEncryption(
         // The id of the room we will be sending to.
-        private var roomId: String,
+        private val roomId: String,
         private val olmDevice: MXOlmDevice,
         private val defaultKeysBackupService: DefaultKeysBackupService,
         private val cryptoStore: IMXCryptoStore,
@@ -66,17 +66,25 @@ internal class MXMegolmEncryption(
     override suspend fun encryptEventContent(eventContent: Content,
                                              eventType: String,
                                              userIds: List<String>): Content {
+        val ts = System.currentTimeMillis()
+        Timber.v("## CRYPTO | encryptEventContent : getDevicesInRoom")
         val devices = getDevicesInRoom(userIds)
+        Timber.v("## CRYPTO | encryptEventContent ${System.currentTimeMillis() - ts}: getDevicesInRoom ${devices.map}")
         val outboundSession = ensureOutboundSession(devices)
         return encryptContent(outboundSession, eventType, eventContent)
     }
 
+    override fun discardSessionKey() {
+        outboundSession = null
+    }
+
     /**
      * Prepare a new session.
      *
      * @return the session description
      */
     private fun prepareNewSessionInRoom(): MXOutboundSessionInfo {
+        Timber.v("## CRYPTO | prepareNewSessionInRoom() ")
         val sessionId = olmDevice.createOutboundGroupSession()
 
         val keysClaimedMap = HashMap<String, String>()
@@ -96,6 +104,7 @@ internal class MXMegolmEncryption(
      * @param devicesInRoom the devices list
      */
     private suspend fun ensureOutboundSession(devicesInRoom: MXUsersDevicesMap<CryptoDeviceInfo>): MXOutboundSessionInfo {
+        Timber.v("## CRYPTO | ensureOutboundSession start")
         var session = outboundSession
         if (session == null
                 // Need to make a brand new session?
@@ -132,7 +141,7 @@ internal class MXMegolmEncryption(
                                  devicesByUsers: Map<String, List<CryptoDeviceInfo>>) {
         // nothing to send, the task is done
         if (devicesByUsers.isEmpty()) {
-            Timber.v("## shareKey() : nothing more to do")
+            Timber.v("## CRYPTO | shareKey() : nothing more to do")
             return
         }
         // reduce the map size to avoid request timeout when there are too many devices (Users size  * devices per user)
@@ -145,7 +154,7 @@ internal class MXMegolmEncryption(
                 break
             }
         }
-        Timber.v("## shareKey() ; userId ${subMap.keys}")
+        Timber.v("## CRYPTO | shareKey() ; sessionId<${session.sessionId}> userId ${subMap.keys}")
         shareUserDevicesKey(session, subMap)
         val remainingDevices = devicesByUsers - subMap.keys
         shareKey(session, remainingDevices)
@@ -174,10 +183,10 @@ internal class MXMegolmEncryption(
         payload["content"] = submap
 
         var t0 = System.currentTimeMillis()
-        Timber.v("## shareUserDevicesKey() : starts")
+        Timber.v("## CRYPTO | shareUserDevicesKey() : starts")
 
         val results = ensureOlmSessionsForDevicesAction.handle(devicesByUser)
-        Timber.v("## shareUserDevicesKey() : ensureOlmSessionsForDevices succeeds after "
+        Timber.v("## CRYPTO | shareUserDevicesKey() : ensureOlmSessionsForDevices succeeds after "
                 + (System.currentTimeMillis() - t0) + " ms")
         val contentMap = MXUsersDevicesMap<Any>()
         var haveTargets = false
@@ -200,17 +209,17 @@ internal class MXMegolmEncryption(
                     // so just skip it.
                     continue
                 }
-                Timber.v("## shareUserDevicesKey() : Sharing keys with device $userId:$deviceID")
+                Timber.v("## CRYPTO | shareUserDevicesKey() : Sharing keys with device $userId:$deviceID")
                 contentMap.setObject(userId, deviceID, messageEncrypter.encryptMessage(payload, listOf(sessionResult.deviceInfo)))
                 haveTargets = true
             }
         }
         if (haveTargets) {
             t0 = System.currentTimeMillis()
-            Timber.v("## shareUserDevicesKey() : has target")
+            Timber.v("## CRYPTO | shareUserDevicesKey() : has target")
             val sendToDeviceParams = SendToDeviceTask.Params(EventType.ENCRYPTED, contentMap)
             sendToDeviceTask.execute(sendToDeviceParams)
-            Timber.v("## shareUserDevicesKey() : sendToDevice succeeds after "
+            Timber.v("## CRYPTO | shareUserDevicesKey() : sendToDevice succeeds after "
                     + (System.currentTimeMillis() - t0) + " ms")
 
             // Add the devices we have shared with to session.sharedWithDevices.
@@ -224,7 +233,7 @@ internal class MXMegolmEncryption(
                 }
             }
         } else {
-            Timber.v("## shareUserDevicesKey() : no need to sharekey")
+            Timber.v("## CRYPTO | shareUserDevicesKey() : no need to sharekey")
         }
     }
 
@@ -305,4 +314,49 @@ internal class MXMegolmEncryption(
             throw MXCryptoError.UnknownDevice(unknownDevices)
         }
     }
+
+    override suspend fun reshareKey(sessionId: String,
+                                    userId: String,
+                                    deviceId: String,
+                                    senderKey: String): Boolean {
+        Timber.d("[MXMegolmEncryption] reshareKey: $sessionId to $userId:$deviceId")
+        val deviceInfo = cryptoStore.getUserDevice(userId, deviceId) ?: return false
+                .also { Timber.w("Device not found") }
+
+        // Get the chain index of the key we previously sent this device
+        val chainIndex = outboundSession?.sharedWithDevices?.getObject(userId, deviceId)?.toLong() ?: return false
+                .also { Timber.w("[MXMegolmEncryption] reshareKey : ERROR : Never share megolm with this device") }
+
+        val devicesByUser = mapOf(userId to listOf(deviceInfo))
+        val usersDeviceMap = ensureOlmSessionsForDevicesAction.handle(devicesByUser)
+        val olmSessionResult = usersDeviceMap.getObject(userId, deviceId)
+        olmSessionResult?.sessionId
+                ?: // no session with this device, probably because there were no one-time keys.
+                // ensureOlmSessionsForDevicesAction has already done the logging, so just skip it.
+                return false
+
+        Timber.d("[MXMegolmEncryption] reshareKey: sharing keys for session $senderKey|$sessionId:$chainIndex with device $userId:$deviceId")
+
+        val payloadJson = mutableMapOf<String, Any>("type" to EventType.FORWARDED_ROOM_KEY)
+
+        runCatching { olmDevice.getInboundGroupSession(sessionId, senderKey, roomId) }
+                .fold(
+                        {
+                            // TODO
+                            payloadJson["content"] = it.exportKeys(chainIndex) ?: ""
+                        },
+                        {
+                            // TODO
+                        }
+
+                )
+
+        val encodedPayload = messageEncrypter.encryptMessage(payloadJson, listOf(deviceInfo))
+        val sendToDeviceMap = MXUsersDevicesMap<Any>()
+        sendToDeviceMap.setObject(userId, deviceId, encodedPayload)
+        Timber.v("## CRYPTO | CRYPTO | shareKeysWithDevice() : sending to $userId:$deviceId")
+        val sendToDeviceParams = SendToDeviceTask.Params(EventType.ENCRYPTED, sendToDeviceMap)
+        sendToDeviceTask.execute(sendToDeviceParams)
+        return true
+    }
 }
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/olm/MXOlmDecryption.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/olm/MXOlmDecryption.kt
index 0a8ef3993b..8ef527fa05 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/olm/MXOlmDecryption.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/olm/MXOlmDecryption.kt
@@ -38,6 +38,7 @@ internal class MXOlmDecryption(
         private val userId: String)
     : IMXDecrypting {
 
+    @Throws(MXCryptoError::class)
     override fun decryptEvent(event: Event, timeline: String): MXEventDecryptionResult {
         val olmEventContent = event.content.toModel<OlmEventContent>() ?: run {
             Timber.e("## decryptEvent() : bad event format")
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/olm/MXOlmEncryption.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/olm/MXOlmEncryption.kt
index 899e884e0d..a9b84a8e48 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/olm/MXOlmEncryption.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/olm/MXOlmEncryption.kt
@@ -29,7 +29,7 @@ import im.vector.matrix.android.internal.crypto.model.CryptoDeviceInfo
 import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore
 
 internal class MXOlmEncryption(
-        private var roomId: String,
+        private val roomId: String,
         private val olmDevice: MXOlmDevice,
         private val cryptoStore: IMXCryptoStore,
         private val messageEncrypter: MessageEncrypter,
@@ -78,4 +78,13 @@ internal class MXOlmEncryption(
         deviceListManager.downloadKeys(users, false)
         ensureOlmSessionsForUsersAction.handle(users)
     }
+
+    override fun discardSessionKey() {
+        // No need for olm
+    }
+
+    override suspend fun reshareKey(sessionId: String, userId: String, deviceId: String, senderKey: String): Boolean {
+        // No need for olm
+        return false
+    }
 }
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/crosssigning/ComputeTrustTask.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/crosssigning/ComputeTrustTask.kt
index 841de92130..121479ad66 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/crosssigning/ComputeTrustTask.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/crosssigning/ComputeTrustTask.kt
@@ -19,6 +19,7 @@ import im.vector.matrix.android.api.crypto.RoomEncryptionTrustLevel
 import im.vector.matrix.android.api.extensions.orFalse
 import im.vector.matrix.android.api.session.crypto.crosssigning.MXCrossSigningInfo
 import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore
+import im.vector.matrix.android.internal.di.UserId
 import im.vector.matrix.android.internal.task.Task
 import im.vector.matrix.android.internal.util.MatrixCoroutineDispatchers
 import kotlinx.coroutines.withContext
@@ -26,17 +27,28 @@ import javax.inject.Inject
 
 internal interface ComputeTrustTask : Task<ComputeTrustTask.Params, RoomEncryptionTrustLevel> {
     data class Params(
-            val userIds: List<String>
+            val activeMemberUserIds: List<String>,
+            val isDirectRoom: Boolean
     )
 }
 
 internal class DefaultComputeTrustTask @Inject constructor(
         private val cryptoStore: IMXCryptoStore,
+        @UserId private val userId: String,
         private val coroutineDispatchers: MatrixCoroutineDispatchers
 ) : ComputeTrustTask {
 
     override suspend fun execute(params: ComputeTrustTask.Params): RoomEncryptionTrustLevel = withContext(coroutineDispatchers.crypto) {
-        val allTrustedUserIds = params.userIds
+        // The set of “all users” depends on the type of room:
+        // For regular / topic rooms, all users including yourself, are considered when decorating a room
+        // For 1:1 and group DM rooms, all other users (i.e. excluding yourself) are considered when decorating a room
+        val listToCheck = if (params.isDirectRoom) {
+            params.activeMemberUserIds.filter { it != userId }
+        } else {
+            params.activeMemberUserIds
+        }
+
+        val allTrustedUserIds = listToCheck
                 .filter { userId -> getUserCrossSigningKeys(userId)?.isTrusted() == true }
 
         if (allTrustedUserIds.isEmpty()) {
@@ -60,7 +72,7 @@ internal class DefaultComputeTrustTask @Inject constructor(
                         if (hasWarning) {
                             RoomEncryptionTrustLevel.Warning
                         } else {
-                            if (params.userIds.size == allTrustedUserIds.size) {
+                            if (listToCheck.size == allTrustedUserIds.size) {
                                 // all users are trusted and all devices are verified
                                 RoomEncryptionTrustLevel.Trusted
                             } else {
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/crosssigning/DefaultCrossSigningService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/crosssigning/DefaultCrossSigningService.kt
index 54392ad44c..2fee8130fb 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/crosssigning/DefaultCrossSigningService.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/crosssigning/DefaultCrossSigningService.kt
@@ -17,22 +17,17 @@
 package im.vector.matrix.android.internal.crypto.crosssigning
 
 import androidx.lifecycle.LiveData
-import dagger.Lazy
 import im.vector.matrix.android.api.MatrixCallback
 import im.vector.matrix.android.api.session.crypto.crosssigning.CrossSigningService
 import im.vector.matrix.android.api.session.crypto.crosssigning.MXCrossSigningInfo
 import im.vector.matrix.android.api.util.Optional
 import im.vector.matrix.android.internal.crypto.DeviceListManager
-import im.vector.matrix.android.internal.crypto.MXOlmDevice
-import im.vector.matrix.android.internal.crypto.MyDeviceInfoHolder
-import im.vector.matrix.android.internal.crypto.model.CryptoCrossSigningKey
-import im.vector.matrix.android.internal.crypto.model.KeyUsage
 import im.vector.matrix.android.internal.crypto.model.rest.UploadSignatureQueryBuilder
 import im.vector.matrix.android.internal.crypto.model.rest.UserPasswordAuth
 import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore
 import im.vector.matrix.android.internal.crypto.store.PrivateKeysInfo
+import im.vector.matrix.android.internal.crypto.tasks.InitializeCrossSigningTask
 import im.vector.matrix.android.internal.crypto.tasks.UploadSignaturesTask
-import im.vector.matrix.android.internal.crypto.tasks.UploadSigningKeysTask
 import im.vector.matrix.android.internal.di.UserId
 import im.vector.matrix.android.internal.session.SessionScope
 import im.vector.matrix.android.internal.task.TaskExecutor
@@ -53,12 +48,9 @@ import javax.inject.Inject
 internal class DefaultCrossSigningService @Inject constructor(
         @UserId private val userId: String,
         private val cryptoStore: IMXCryptoStore,
-        private val myDeviceInfoHolder: Lazy<MyDeviceInfoHolder>,
-        private val olmDevice: MXOlmDevice,
         private val deviceListManager: DeviceListManager,
-        private val uploadSigningKeysTask: UploadSigningKeysTask,
+        private val initializeCrossSigningTask: InitializeCrossSigningTask,
         private val uploadSignaturesTask: UploadSignaturesTask,
-        private val computeTrustTask: ComputeTrustTask,
         private val taskExecutor: TaskExecutor,
         private val coroutineDispatchers: MatrixCoroutineDispatchers,
         private val cryptoCoroutineScope: CoroutineScope,
@@ -151,153 +143,31 @@ internal class DefaultCrossSigningService @Inject constructor(
     override fun initializeCrossSigning(authParams: UserPasswordAuth?, callback: MatrixCallback<Unit>?) {
         Timber.d("## CrossSigning  initializeCrossSigning")
 
-        // =================
-        // MASTER KEY
-        // =================
-        val masterPkOlm = OlmPkSigning()
-        val masterKeyPrivateKey = OlmPkSigning.generateSeed()
-        val masterPublicKey = masterPkOlm.initWithSeed(masterKeyPrivateKey)
-
-        Timber.v("## CrossSigning - masterPublicKey:$masterPublicKey")
-
-        // =================
-        // USER KEY
-        // =================
-        val userSigningPkOlm = OlmPkSigning()
-        val uskPrivateKey = OlmPkSigning.generateSeed()
-        val uskPublicKey = userSigningPkOlm.initWithSeed(uskPrivateKey)
-
-        Timber.v("## CrossSigning - uskPublicKey:$uskPublicKey")
-
-        // Sign userSigningKey with master
-        val signedUSK = CryptoCrossSigningKey.Builder(userId, KeyUsage.USER_SIGNING)
-                .key(uskPublicKey)
-                .build()
-                .canonicalSignable()
-                .let { masterPkOlm.sign(it) }
-
-        // =================
-        // SELF SIGNING KEY
-        // =================
-        val selfSigningPkOlm = OlmPkSigning()
-        val sskPrivateKey = OlmPkSigning.generateSeed()
-        val sskPublicKey = selfSigningPkOlm.initWithSeed(sskPrivateKey)
-
-        Timber.v("## CrossSigning - sskPublicKey:$sskPublicKey")
-
-        // Sign userSigningKey with master
-        val signedSSK = JsonCanonicalizer.getCanonicalJson(Map::class.java, CryptoCrossSigningKey.Builder(userId, KeyUsage.SELF_SIGNING)
-                .key(sskPublicKey)
-                .build().signalableJSONDictionary()).let { masterPkOlm.sign(it) }
-
-        // I need to upload the keys
-        val mskCrossSigningKeyInfo = CryptoCrossSigningKey.Builder(userId, KeyUsage.MASTER)
-                .key(masterPublicKey)
-                .build()
-        val params = UploadSigningKeysTask.Params(
-                masterKey = mskCrossSigningKeyInfo,
-                userKey = CryptoCrossSigningKey.Builder(userId, KeyUsage.USER_SIGNING)
-                        .key(uskPublicKey)
-                        .signature(userId, masterPublicKey, signedUSK)
-                        .build(),
-                selfSignedKey = CryptoCrossSigningKey.Builder(userId, KeyUsage.SELF_SIGNING)
-                        .key(sskPublicKey)
-                        .signature(userId, masterPublicKey, signedSSK)
-                        .build(),
-                userPasswordAuth = authParams
+        val params = InitializeCrossSigningTask.Params(
+                authParams = authParams
         )
-
-        this.masterPkSigning = masterPkOlm
-        this.userPkSigning = userSigningPkOlm
-        this.selfSigningPkSigning = selfSigningPkOlm
-
-        val crossSigningInfo = MXCrossSigningInfo(userId, listOf(params.masterKey, params.userKey, params.selfSignedKey))
-        cryptoStore.setMyCrossSigningInfo(crossSigningInfo)
-        setUserKeysAsTrusted(userId, true)
-        cryptoStore.storePrivateKeysInfo(masterKeyPrivateKey?.toBase64NoPadding(), uskPrivateKey?.toBase64NoPadding(), sskPrivateKey?.toBase64NoPadding())
-
-        uploadSigningKeysTask.configureWith(params) {
-            this.executionThread = TaskThread.CRYPTO
-            this.callback = object : MatrixCallback<Unit> {
-                override fun onSuccess(data: Unit) {
-                    Timber.i("## CrossSigning - Keys successfully uploaded")
-
-                    //  Sign the current device with SSK
-                    val uploadSignatureQueryBuilder = UploadSignatureQueryBuilder()
-
-                    val myDevice = myDeviceInfoHolder.get().myDevice
-                    val canonicalJson = JsonCanonicalizer.getCanonicalJson(Map::class.java, myDevice.signalableJSONDictionary())
-                    val signedDevice = selfSigningPkOlm.sign(canonicalJson)
-                    val updateSignatures = (myDevice.signatures?.toMutableMap() ?: HashMap())
-                            .also {
-                                it[userId] = (it[userId]
-                                        ?: HashMap()) + mapOf("ed25519:$sskPublicKey" to signedDevice)
-                            }
-                    myDevice.copy(signatures = updateSignatures).let {
-                        uploadSignatureQueryBuilder.withDeviceInfo(it)
-                    }
-
-                    // sign MSK with device key (migration) and upload signatures
-                    val message = JsonCanonicalizer.getCanonicalJson(Map::class.java, mskCrossSigningKeyInfo.signalableJSONDictionary())
-                    olmDevice.signMessage(message)?.let { sign ->
-                        val mskUpdatedSignatures = (mskCrossSigningKeyInfo.signatures?.toMutableMap()
-                                ?: HashMap()).also {
-                            it[userId] = (it[userId]
-                                    ?: HashMap()) + mapOf("ed25519:${myDevice.deviceId}" to sign)
-                        }
-                        mskCrossSigningKeyInfo.copy(
-                                signatures = mskUpdatedSignatures
-                        ).let {
-                            uploadSignatureQueryBuilder.withSigningKeyInfo(it)
-                        }
-                    }
-
-                    resetTrustOnKeyChange()
-                    uploadSignaturesTask.configureWith(UploadSignaturesTask.Params(uploadSignatureQueryBuilder.build())) {
-                        // this.retryCount = 3
-                        this.executionThread = TaskThread.CRYPTO
-                        this.callback = object : MatrixCallback<Unit> {
-                            override fun onSuccess(data: Unit) {
-                                Timber.i("## CrossSigning - signatures successfully uploaded")
-                                callback?.onSuccess(Unit)
-                            }
-
-                            override fun onFailure(failure: Throwable) {
-                                // Clear
-                                Timber.e(failure, "## CrossSigning - Failed to upload signatures")
-                                clearSigningKeys()
-                            }
-                        }
-                    }.executeBy(taskExecutor)
+        initializeCrossSigningTask.configureWith(params) {
+            this.callbackThread = TaskThread.CRYPTO
+            this.callback = object : MatrixCallback<InitializeCrossSigningTask.Result> {
+                override fun onFailure(failure: Throwable) {
+                    callback?.onFailure(failure)
                 }
 
-                override fun onFailure(failure: Throwable) {
-                    Timber.e(failure, "## CrossSigning - Failed to upload signing keys")
-                    clearSigningKeys()
-                    callback?.onFailure(failure)
+                override fun onSuccess(data: InitializeCrossSigningTask.Result) {
+                    val crossSigningInfo = MXCrossSigningInfo(userId, listOf(data.masterKeyInfo, data.userKeyInfo, data.selfSignedKeyInfo))
+                    cryptoStore.setMyCrossSigningInfo(crossSigningInfo)
+                    setUserKeysAsTrusted(userId, true)
+                    cryptoStore.storePrivateKeysInfo(data.masterKeyPK, data.userKeyPK, data.selfSigningKeyPK)
+                    masterPkSigning = OlmPkSigning().apply { initWithSeed(data.masterKeyPK.fromBase64()) }
+                    userPkSigning = OlmPkSigning().apply { initWithSeed(data.userKeyPK.fromBase64()) }
+                    selfSigningPkSigning = OlmPkSigning().apply { initWithSeed(data.selfSigningKeyPK.fromBase64()) }
+
+                    callback?.onSuccess(Unit)
                 }
             }
         }.executeBy(taskExecutor)
     }
 
-    private fun clearSigningKeys() {
-        masterPkSigning?.releaseSigning()
-        userPkSigning?.releaseSigning()
-        selfSigningPkSigning?.releaseSigning()
-
-        masterPkSigning = null
-        userPkSigning = null
-        selfSigningPkSigning = null
-
-        cryptoStore.setMyCrossSigningInfo(null)
-        cryptoStore.storePrivateKeysInfo(null, null, null)
-    }
-
-    private fun resetTrustOnKeyChange() {
-        Timber.i("## CrossSigning - Clear all other user trust")
-        cryptoStore.clearOtherUserTrust()
-    }
-
     override fun onSecretSSKGossip(sskPrivateKey: String) {
         Timber.i("## CrossSigning - onSecretSSKGossip")
         val mxCrossSigningInfo = getMyCrossSigningKeys() ?: return Unit.also {
@@ -600,6 +470,10 @@ internal class DefaultCrossSigningService @Inject constructor(
         return cryptoStore.getCrossSigningPrivateKeys()
     }
 
+    override fun getLiveCrossSigningPrivateKeys(): LiveData<Optional<PrivateKeysInfo>> {
+        return cryptoStore.getLiveCrossSigningPrivateKeys()
+    }
+
     override fun canCrossSign(): Boolean {
         return checkSelfTrust().isVerified() && cryptoStore.getCrossSigningPrivateKeys()?.selfSigned != null
                 && cryptoStore.getCrossSigningPrivateKeys()?.user != null
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/crosssigning/SessionToCryptoRoomMembersUpdate.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/crosssigning/SessionToCryptoRoomMembersUpdate.kt
index 04f63f945a..2f1cb77a21 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/crosssigning/SessionToCryptoRoomMembersUpdate.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/crosssigning/SessionToCryptoRoomMembersUpdate.kt
@@ -17,6 +17,7 @@ package im.vector.matrix.android.internal.crypto.crosssigning
 
 data class SessionToCryptoRoomMembersUpdate(
         val roomId: String,
+        val isDirect: Boolean,
         val userIds: List<String>
 )
 
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/crosssigning/ShieldTrustUpdater.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/crosssigning/ShieldTrustUpdater.kt
index c4c49a5940..f1e387beb3 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/crosssigning/ShieldTrustUpdater.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/crosssigning/ShieldTrustUpdater.kt
@@ -15,18 +15,20 @@
  */
 package im.vector.matrix.android.internal.crypto.crosssigning
 
+import im.vector.matrix.android.api.extensions.orFalse
 import im.vector.matrix.android.internal.database.model.RoomMemberSummaryEntity
 import im.vector.matrix.android.internal.database.model.RoomMemberSummaryEntityFields
+import im.vector.matrix.android.internal.database.model.RoomSummaryEntity
 import im.vector.matrix.android.internal.database.query.where
 import im.vector.matrix.android.internal.di.SessionDatabase
 import im.vector.matrix.android.internal.session.room.RoomSummaryUpdater
+import im.vector.matrix.android.internal.session.room.membership.RoomMemberHelper
 import im.vector.matrix.android.internal.task.TaskExecutor
-import im.vector.matrix.android.internal.util.MatrixCoroutineDispatchers
 import im.vector.matrix.android.internal.util.createBackgroundHandler
 import io.realm.Realm
 import io.realm.RealmConfiguration
+import kotlinx.coroutines.android.asCoroutineDispatcher
 import kotlinx.coroutines.launch
-import kotlinx.coroutines.withContext
 import org.greenrobot.eventbus.EventBus
 import org.greenrobot.eventbus.Subscribe
 import timber.log.Timber
@@ -38,13 +40,13 @@ internal class ShieldTrustUpdater @Inject constructor(
         private val eventBus: EventBus,
         private val computeTrustTask: ComputeTrustTask,
         private val taskExecutor: TaskExecutor,
-        private val coroutineDispatchers: MatrixCoroutineDispatchers,
         @SessionDatabase private val sessionRealmConfiguration: RealmConfiguration,
         private val roomSummaryUpdater: RoomSummaryUpdater
 ) {
 
     companion object {
         private val BACKGROUND_HANDLER = createBackgroundHandler("SHIELD_CRYPTO_DB_THREAD")
+        private val BACKGROUND_HANDLER_DISPATCHER = BACKGROUND_HANDLER.asCoroutineDispatcher()
     }
 
     private val backgroundSessionRealm = AtomicReference<Realm>()
@@ -76,14 +78,11 @@ internal class ShieldTrustUpdater @Inject constructor(
         if (!isStarted.get()) {
             return
         }
-        taskExecutor.executorScope.launch(coroutineDispatchers.crypto) {
-            val updatedTrust = computeTrustTask.execute(ComputeTrustTask.Params(update.userIds))
+        taskExecutor.executorScope.launch(BACKGROUND_HANDLER_DISPATCHER) {
+            val updatedTrust = computeTrustTask.execute(ComputeTrustTask.Params(update.userIds, update.isDirect))
             // We need to send that back to session base
-
-            BACKGROUND_HANDLER.post {
-                backgroundSessionRealm.get()?.executeTransaction { realm ->
-                    roomSummaryUpdater.updateShieldTrust(realm, update.roomId, updatedTrust)
-                }
+            backgroundSessionRealm.get()?.executeTransaction { realm ->
+                roomSummaryUpdater.updateShieldTrust(realm, update.roomId, updatedTrust)
             }
         }
     }
@@ -93,45 +92,31 @@ internal class ShieldTrustUpdater @Inject constructor(
         if (!isStarted.get()) {
             return
         }
-
         onCryptoDevicesChange(update.userIds)
     }
 
     private fun onCryptoDevicesChange(users: List<String>) {
-        BACKGROUND_HANDLER.post {
-            val impactedRoomsId = backgroundSessionRealm.get()?.where(RoomMemberSummaryEntity::class.java)
-                    ?.`in`(RoomMemberSummaryEntityFields.USER_ID, users.toTypedArray())
-                    ?.findAll()
-                    ?.map { it.roomId }
-                    ?.distinct()
+        taskExecutor.executorScope.launch(BACKGROUND_HANDLER_DISPATCHER) {
+            val realm = backgroundSessionRealm.get() ?: return@launch
+            val distinctRoomIds = realm.where(RoomMemberSummaryEntity::class.java)
+                    .`in`(RoomMemberSummaryEntityFields.USER_ID, users.toTypedArray())
+                    .distinct(RoomMemberSummaryEntityFields.ROOM_ID)
+                    .findAll()
+                    .map { it.roomId }
 
-            val map = HashMap<String, List<String>>()
-            impactedRoomsId?.forEach { roomId ->
-                backgroundSessionRealm.get()?.let { realm ->
-                    RoomMemberSummaryEntity.where(realm, roomId)
-                            .findAll()
-                            .let { results ->
-                                map[roomId] = results.map { it.userId }
-                            }
-                }
-            }
-
-            map.forEach { entry ->
-                val roomId = entry.key
-                val userList = entry.value
-                taskExecutor.executorScope.launch {
-                    withContext(coroutineDispatchers.crypto) {
-                        try {
-                            // Can throw if the crypto database has been closed in between, in this case log and ignore?
-                            val updatedTrust = computeTrustTask.execute(ComputeTrustTask.Params(userList))
-                            BACKGROUND_HANDLER.post {
-                                backgroundSessionRealm.get()?.executeTransaction { realm ->
-                                    roomSummaryUpdater.updateShieldTrust(realm, roomId, updatedTrust)
-                                }
-                            }
-                        } catch (failure: Throwable) {
-                            Timber.e(failure)
+            distinctRoomIds.forEach { roomId ->
+                val roomSummary = RoomSummaryEntity.where(realm, roomId).findFirst()
+                if (roomSummary?.isEncrypted.orFalse()) {
+                    val allActiveRoomMembers = RoomMemberHelper(realm, roomId).getActiveRoomMemberIds()
+                    try {
+                        val updatedTrust = computeTrustTask.execute(
+                                ComputeTrustTask.Params(allActiveRoomMembers, roomSummary?.isDirect == true)
+                        )
+                        realm.executeTransaction {
+                            roomSummaryUpdater.updateShieldTrust(it, roomId, updatedTrust)
                         }
+                    } catch (failure: Throwable) {
+                        Timber.e(failure)
                     }
                 }
             }
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/keysbackup/DefaultKeysBackupService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/keysbackup/DefaultKeysBackupService.kt
index 75e37d27f6..38dae20a83 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/keysbackup/DefaultKeysBackupService.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/keysbackup/DefaultKeysBackupService.kt
@@ -66,7 +66,7 @@ import im.vector.matrix.android.internal.crypto.keysbackup.tasks.UpdateKeysBacku
 import im.vector.matrix.android.internal.crypto.keysbackup.util.computeRecoveryKey
 import im.vector.matrix.android.internal.crypto.keysbackup.util.extractCurveKeyFromRecoveryKey
 import im.vector.matrix.android.internal.crypto.model.ImportRoomKeysResult
-import im.vector.matrix.android.internal.crypto.model.OlmInboundGroupSessionWrapper
+import im.vector.matrix.android.internal.crypto.model.OlmInboundGroupSessionWrapper2
 import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore
 import im.vector.matrix.android.internal.crypto.store.SavedKeyBackupKeyInfo
 import im.vector.matrix.android.internal.crypto.store.db.model.KeysBackupDataEntity
@@ -728,7 +728,8 @@ internal class DefaultKeysBackupService @Inject constructor(
                     if (backUp) {
                         maybeBackupKeys()
                     }
-
+                    // Save for next time and for gossiping
+                    saveBackupRecoveryKey(recoveryKey, keysVersionResult.version)
                     result
                 }
             }.foldToCallback(callback)
@@ -1100,6 +1101,16 @@ internal class DefaultKeysBackupService @Inject constructor(
         return true
     }
 
+    override fun isValidRecoveryKeyForCurrentVersion(recoveryKey: String, callback: MatrixCallback<Boolean>) {
+        val safeKeysBackupVersion = keysBackupVersion ?: return Unit.also { callback.onSuccess(false) }
+
+        cryptoCoroutineScope.launch(coroutineDispatchers.main) {
+            isValidRecoveryKeyForKeysBackupVersion(recoveryKey, safeKeysBackupVersion).let {
+                callback.onSuccess(it)
+            }
+        }
+    }
+
     /**
      * Enable backing up of keys.
      * This method will update the state and will start sending keys in nominal case
@@ -1307,7 +1318,7 @@ internal class DefaultKeysBackupService @Inject constructor(
 
     @VisibleForTesting
     @WorkerThread
-    fun encryptGroupSession(olmInboundGroupSessionWrapper: OlmInboundGroupSessionWrapper): KeyBackupData {
+    fun encryptGroupSession(olmInboundGroupSessionWrapper: OlmInboundGroupSessionWrapper2): KeyBackupData {
         // Gather information for each key
         val device = cryptoStore.deviceWithIdentityKey(olmInboundGroupSessionWrapper.senderKey!!)
 
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/keysbackup/model/rest/CreateKeysBackupVersionBody.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/keysbackup/model/rest/CreateKeysBackupVersionBody.kt
index 3b267280e5..f0c0ada207 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/keysbackup/model/rest/CreateKeysBackupVersionBody.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/keysbackup/model/rest/CreateKeysBackupVersionBody.kt
@@ -29,7 +29,8 @@ data class CreateKeysBackupVersionBody(
         override val algorithm: String? = null,
 
         /**
-         * algorithm-dependent data, for "m.megolm_backup.v1.curve25519-aes-sha2" see [im.vector.matrix.android.internal.crypto.keysbackup.MegolmBackupAuthData]
+         * algorithm-dependent data, for "m.megolm_backup.v1.curve25519-aes-sha2"
+         * see [im.vector.matrix.android.internal.crypto.keysbackup.MegolmBackupAuthData]
          */
         @Json(name = "auth_data")
         override val authData: JsonDict? = null
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/keysbackup/model/rest/KeysVersionResult.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/keysbackup/model/rest/KeysVersionResult.kt
index 0addd1491e..ba5cb2a379 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/keysbackup/model/rest/KeysVersionResult.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/keysbackup/model/rest/KeysVersionResult.kt
@@ -29,7 +29,8 @@ data class KeysVersionResult(
         override val algorithm: String? = null,
 
         /**
-         * algorithm-dependent data, for "m.megolm_backup.v1.curve25519-aes-sha2" see [im.vector.matrix.android.internal.crypto.keysbackup.MegolmBackupAuthData]
+         * algorithm-dependent data, for "m.megolm_backup.v1.curve25519-aes-sha2"
+         * see [im.vector.matrix.android.internal.crypto.keysbackup.MegolmBackupAuthData]
          */
         @Json(name = "auth_data")
         override val authData: JsonDict? = null,
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/keysbackup/model/rest/UpdateKeysBackupVersionBody.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/keysbackup/model/rest/UpdateKeysBackupVersionBody.kt
index 9d88af20ef..bb12911e42 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/keysbackup/model/rest/UpdateKeysBackupVersionBody.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/keysbackup/model/rest/UpdateKeysBackupVersionBody.kt
@@ -29,7 +29,8 @@ data class UpdateKeysBackupVersionBody(
         override val algorithm: String? = null,
 
         /**
-         * algorithm-dependent data, for "m.megolm_backup.v1.curve25519-aes-sha2" see [im.vector.matrix.android.internal.crypto.keysbackup.MegolmBackupAuthData]
+         * algorithm-dependent data, for "m.megolm_backup.v1.curve25519-aes-sha2"
+         * see [im.vector.matrix.android.internal.crypto.keysbackup.MegolmBackupAuthData]
          */
         @Json(name = "auth_data")
         override val authData: JsonDict? = null,
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/CryptoDeviceInfo.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/CryptoDeviceInfo.kt
index b124f7590e..fc6e2cc436 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/CryptoDeviceInfo.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/CryptoDeviceInfo.kt
@@ -29,7 +29,8 @@ data class CryptoDeviceInfo(
         override val signatures: Map<String, Map<String, String>>? = null,
         val unsigned: JsonDict? = null,
         var trustLevel: DeviceTrustLevel? = null,
-        var isBlocked: Boolean = false
+        var isBlocked: Boolean = false,
+        val firstTimeSeenLocalTs: Long? = null
 ) : CryptoInfo {
 
     val isVerified: Boolean
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/CryptoInfoMapper.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/CryptoInfoMapper.kt
index 4459d508ff..f3ddfb8faa 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/CryptoInfoMapper.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/CryptoInfoMapper.kt
@@ -61,20 +61,4 @@ internal object CryptoInfoMapper {
                 signatures = keyInfo.signatures
         )
     }
-
-    fun RestDeviceInfo.toCryptoModel(): CryptoDeviceInfo {
-        return map(this)
-    }
-
-    fun CryptoDeviceInfo.toRest(): RestDeviceInfo {
-        return map(this)
-    }
-
-//    fun RestKeyInfo.toCryptoModel(): CryptoCrossSigningKey {
-//        return map(this)
-//    }
-
-    fun CryptoCrossSigningKey.toRest(): RestKeyInfo {
-        return map(this)
-    }
 }
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/OlmInboundGroupSessionWrapper2.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/OlmInboundGroupSessionWrapper2.kt
new file mode 100755
index 0000000000..c51e707aeb
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/OlmInboundGroupSessionWrapper2.kt
@@ -0,0 +1,157 @@
+/*
+ * 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.matrix.android.internal.crypto.model
+
+import im.vector.matrix.android.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM
+import im.vector.matrix.android.internal.crypto.MegolmSessionData
+import org.matrix.olm.OlmInboundGroupSession
+import timber.log.Timber
+import java.io.Serializable
+
+/**
+ * This class adds more context to a OlmInboundGroupSession object.
+ * This allows additional checks. The class implements Serializable so that the context can be stored.
+ */
+class OlmInboundGroupSessionWrapper2 : Serializable {
+
+    // The associated olm inbound group session.
+    var olmInboundGroupSession: OlmInboundGroupSession? = null
+
+    // The room in which this session is used.
+    var roomId: String? = null
+
+    // The base64-encoded curve25519 key of the sender.
+    var senderKey: String? = null
+
+    // Other keys the sender claims.
+    var keysClaimed: Map<String, String>? = null
+
+    // Devices which forwarded this session to us (normally empty).
+    var forwardingCurve25519KeyChain: List<String>? = ArrayList()
+
+    /**
+     * @return the first known message index
+     */
+    val firstKnownIndex: Long?
+        get() {
+            if (null != olmInboundGroupSession) {
+                try {
+                    return olmInboundGroupSession!!.firstKnownIndex
+                } catch (e: Exception) {
+                    Timber.e(e, "## getFirstKnownIndex() : getFirstKnownIndex failed")
+                }
+            }
+
+            return null
+        }
+
+    /**
+     * Constructor
+     *
+     * @param sessionKey the session key
+     * @param isImported true if it is an imported session key
+     */
+    constructor(sessionKey: String, isImported: Boolean) {
+        try {
+            if (!isImported) {
+                olmInboundGroupSession = OlmInboundGroupSession(sessionKey)
+            } else {
+                olmInboundGroupSession = OlmInboundGroupSession.importSession(sessionKey)
+            }
+        } catch (e: Exception) {
+            Timber.e(e, "Cannot create")
+        }
+    }
+
+    constructor() {
+        // empty
+    }
+    /**
+     * Create a new instance from the provided keys map.
+     *
+     * @param megolmSessionData the megolm session data
+     * @throws Exception if the data are invalid
+     */
+    @Throws(Exception::class)
+    constructor(megolmSessionData: MegolmSessionData) {
+        try {
+            olmInboundGroupSession = OlmInboundGroupSession.importSession(megolmSessionData.sessionKey!!)
+
+            if (olmInboundGroupSession!!.sessionIdentifier() != megolmSessionData.sessionId) {
+                throw Exception("Mismatched group session Id")
+            }
+
+            senderKey = megolmSessionData.senderKey
+            keysClaimed = megolmSessionData.senderClaimedKeys
+            roomId = megolmSessionData.roomId
+        } catch (e: Exception) {
+            throw Exception(e.message)
+        }
+    }
+
+    /**
+     * Export the inbound group session keys
+     * @param index the index to export. If null, the first known index will be used
+     *
+     * @return the inbound group session as MegolmSessionData if the operation succeeds
+     */
+    fun exportKeys(index: Long? = null): MegolmSessionData? {
+        return try {
+            if (null == forwardingCurve25519KeyChain) {
+                forwardingCurve25519KeyChain = ArrayList()
+            }
+
+            if (keysClaimed == null) {
+                return null
+            }
+
+            val wantedIndex = index ?: olmInboundGroupSession!!.firstKnownIndex
+
+            MegolmSessionData(
+                    senderClaimedEd25519Key = keysClaimed?.get("ed25519"),
+                    forwardingCurve25519KeyChain = ArrayList(forwardingCurve25519KeyChain!!),
+                    senderKey = senderKey,
+                    senderClaimedKeys = keysClaimed,
+                    roomId = roomId,
+                    sessionId = olmInboundGroupSession!!.sessionIdentifier(),
+                    sessionKey = olmInboundGroupSession!!.export(wantedIndex),
+                    algorithm = MXCRYPTO_ALGORITHM_MEGOLM
+            )
+        } catch (e: Exception) {
+            Timber.e(e, "## export() : senderKey $senderKey failed")
+            null
+        }
+    }
+
+    /**
+     * Export the session for a message index.
+     *
+     * @param messageIndex the message index
+     * @return the exported data
+     */
+    fun exportSession(messageIndex: Long): String? {
+        if (null != olmInboundGroupSession) {
+            try {
+                return olmInboundGroupSession!!.export(messageIndex)
+            } catch (e: Exception) {
+                Timber.e(e, "## exportSession() : export failed")
+            }
+        }
+
+        return null
+    }
+}
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/DummyContent.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/DummyContent.kt
new file mode 100644
index 0000000000..b52354768d
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/DummyContent.kt
@@ -0,0 +1,22 @@
+/*
+ * 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.matrix.android.internal.crypto.model.rest
+
+/**
+ * Class representing the dummy content
+ * Ref: https://matrix.org/docs/spec/client_server/latest#id82
+ */
+typealias DummyContent = Unit
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/ForwardedRoomKeyContent.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/ForwardedRoomKeyContent.kt
index cf8652352c..ea5fb26d83 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/ForwardedRoomKeyContent.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/ForwardedRoomKeyContent.kt
@@ -20,28 +20,53 @@ import com.squareup.moshi.JsonClass
 
 /**
  * Class representing the forward room key request body content
+ * Ref: https://matrix.org/docs/spec/client_server/latest#m-forwarded-room-key
  */
 @JsonClass(generateAdapter = true)
 data class ForwardedRoomKeyContent(
-
+        /**
+         * Required. The encryption algorithm the key in this event is to be used with.
+         */
         @Json(name = "algorithm")
         val algorithm: String? = null,
 
+        /**
+         * Required. The room where the key is used.
+         */
         @Json(name = "room_id")
         val roomId: String? = null,
 
+        /**
+         * Required. The Curve25519 key of the device which initiated the session originally.
+         */
         @Json(name = "sender_key")
         val senderKey: String? = null,
 
+        /**
+         * Required. The ID of the session that the key is for.
+         */
         @Json(name = "session_id")
         val sessionId: String? = null,
 
+        /**
+         * Required. The key to be exchanged.
+         */
         @Json(name = "session_key")
         val sessionKey: String? = null,
 
+        /**
+         * Required. Chain of Curve25519 keys. It starts out empty, but each time the key is forwarded to another device,
+         * the previous sender in the chain is added to the end of the list. For example, if the key is forwarded
+         * from A to B to C, this field is empty between A and B, and contains A's Curve25519 key between B and C.
+         */
         @Json(name = "forwarding_curve25519_key_chain")
         val forwardingCurve25519KeyChain: List<String>? = null,
 
+        /**
+         * Required. The Ed25519 key of the device which initiated the session originally. It is 'claimed' because the
+         * receiving device has no way to tell that the original room_key actually came from a device which owns the
+         * private part of this key unless they have done device verification.
+         */
         @Json(name = "sender_claimed_ed25519_key")
         val senderClaimedEd25519Key: String? = null
 )
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/UserPasswordAuth.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/UserPasswordAuth.kt
index 45ad43a0ef..5e672d4f59 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/UserPasswordAuth.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/UserPasswordAuth.kt
@@ -21,7 +21,7 @@ import com.squareup.moshi.JsonClass
 import im.vector.matrix.android.internal.auth.data.LoginFlowTypes
 
 /**
- * This class provides the authentication data to delete a device
+ * This class provides the authentication data by using user and password
  */
 @JsonClass(generateAdapter = true)
 data class UserPasswordAuth(
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/secrets/DefaultSharedSecretStorageService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/secrets/DefaultSharedSecretStorageService.kt
index 62bc4774c6..7db3d6ead3 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/secrets/DefaultSharedSecretStorageService.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/secrets/DefaultSharedSecretStorageService.kt
@@ -65,14 +65,16 @@ internal class DefaultSharedSecretStorageService @Inject constructor(
 ) : SharedSecretStorageService {
 
     override fun generateKey(keyId: String,
+                             key: SsssKeySpec?,
                              keyName: String,
                              keySigner: KeySigner?,
                              callback: MatrixCallback<SsssKeyCreationInfo>) {
         cryptoCoroutineScope.launch(coroutineDispatchers.main) {
-            val key = try {
-                ByteArray(32).also {
-                    SecureRandom().nextBytes(it)
-                }
+            val bytes = try {
+                (key as? RawBytesKeySpec)?.privateKey
+                        ?: ByteArray(32).also {
+                            SecureRandom().nextBytes(it)
+                        }
             } catch (failure: Throwable) {
                 callback.onFailure(failure)
                 return@launch
@@ -102,8 +104,8 @@ internal class DefaultSharedSecretStorageService @Inject constructor(
                             callback.onSuccess(SsssKeyCreationInfo(
                                     keyId = keyId,
                                     content = storageKeyContent,
-                                    recoveryKey = computeRecoveryKey(key),
-                                    keySpec = RawBytesKeySpec(key)
+                                    recoveryKey = computeRecoveryKey(bytes),
+                                    keySpec = RawBytesKeySpec(bytes)
                             ))
                         }
                     }
@@ -417,7 +419,7 @@ internal class DefaultSharedSecretStorageService @Inject constructor(
                 ?: return IntegrityResult.Error(SharedSecretStorageError.UnknownKey(keyId ?: ""))
 
         if (keyInfo.content.algorithm != SSSS_ALGORITHM_AES_HMAC_SHA2
-                || keyInfo.content.algorithm != SSSS_ALGORITHM_CURVE25519_AES_SHA2) {
+                && keyInfo.content.algorithm != SSSS_ALGORITHM_CURVE25519_AES_SHA2) {
             // Unsupported algorithm
             return IntegrityResult.Error(
                     SharedSecretStorageError.UnsupportedAlgorithm(keyInfo.content.algorithm ?: "")
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/IMXCryptoStore.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/IMXCryptoStore.kt
index a8f65e9219..69f0985391 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/IMXCryptoStore.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/IMXCryptoStore.kt
@@ -30,8 +30,9 @@ import im.vector.matrix.android.internal.crypto.OutgoingRoomKeyRequest
 import im.vector.matrix.android.internal.crypto.OutgoingSecretRequest
 import im.vector.matrix.android.internal.crypto.model.CryptoCrossSigningKey
 import im.vector.matrix.android.internal.crypto.model.CryptoDeviceInfo
-import im.vector.matrix.android.internal.crypto.model.OlmInboundGroupSessionWrapper
+import im.vector.matrix.android.internal.crypto.model.OlmInboundGroupSessionWrapper2
 import im.vector.matrix.android.internal.crypto.model.OlmSessionWrapper
+import im.vector.matrix.android.internal.crypto.model.rest.DeviceInfo
 import im.vector.matrix.android.internal.crypto.model.rest.RoomKeyRequestBody
 import im.vector.matrix.android.internal.crypto.store.db.model.KeysBackupDataEntity
 import org.matrix.olm.OlmAccount
@@ -58,7 +59,7 @@ internal interface IMXCryptoStore {
      *
      * @return the list of all known group sessions, to export them.
      */
-    fun getInboundGroupSessions(): List<OlmInboundGroupSessionWrapper>
+    fun getInboundGroupSessions(): List<OlmInboundGroupSessionWrapper2>
 
     /**
      * @return true to unilaterally blacklist all unverified devices.
@@ -163,14 +164,6 @@ internal interface IMXCryptoStore {
      */
     fun saveOlmAccount()
 
-    /**
-     * Store a device for a user.
-     *
-     * @param userId the user's id.
-     * @param device the device to store.
-     */
-    fun storeUserDevice(userId: String?, deviceInfo: CryptoDeviceInfo?)
-
     /**
      * Retrieve a device for a user.
      *
@@ -196,7 +189,8 @@ internal interface IMXCryptoStore {
      */
     fun storeUserDevices(userId: String, devices: Map<String, CryptoDeviceInfo>?)
 
-    fun storeUserCrossSigningKeys(userId: String, masterKey: CryptoCrossSigningKey?,
+    fun storeUserCrossSigningKeys(userId: String,
+                                  masterKey: CryptoCrossSigningKey?,
                                   selfSigningKey: CryptoCrossSigningKey?,
                                   userSigningKey: CryptoCrossSigningKey?)
 
@@ -217,6 +211,9 @@ internal interface IMXCryptoStore {
     // TODO temp
     fun getLiveDeviceList(): LiveData<List<CryptoDeviceInfo>>
 
+    fun getMyDevicesInfo() : List<DeviceInfo>
+    fun getLiveMyDevicesInfo() : LiveData<List<DeviceInfo>>
+    fun saveMyDevicesInfo(info: List<DeviceInfo>)
     /**
      * Store the crypto algorithm for a room.
      *
@@ -262,7 +259,7 @@ internal interface IMXCryptoStore {
      * @param deviceKey the public key of the other device.
      * @return The Base64 end-to-end session, or null if not found
      */
-    fun getDeviceSession(sessionId: String?, deviceKey: String?): OlmSessionWrapper?
+    fun getDeviceSession(sessionId: String, deviceKey: String): OlmSessionWrapper?
 
     /**
      * Retrieve the last used sessionId, regarding `lastReceivedMessageTs`, or null if no session exist
@@ -277,7 +274,7 @@ internal interface IMXCryptoStore {
      *
      * @param sessions the inbound group sessions to store.
      */
-    fun storeInboundGroupSessions(sessions: List<OlmInboundGroupSessionWrapper>)
+    fun storeInboundGroupSessions(sessions: List<OlmInboundGroupSessionWrapper2>)
 
     /**
      * Retrieve an inbound group session.
@@ -286,7 +283,7 @@ internal interface IMXCryptoStore {
      * @param senderKey the base64-encoded curve25519 key of the sender.
      * @return an inbound group session.
      */
-    fun getInboundGroupSession(sessionId: String, senderKey: String): OlmInboundGroupSessionWrapper?
+    fun getInboundGroupSession(sessionId: String, senderKey: String): OlmInboundGroupSessionWrapper2?
 
     /**
      * Remove an inbound group session
@@ -310,7 +307,7 @@ internal interface IMXCryptoStore {
      *
      * @param sessions the sessions
      */
-    fun markBackupDoneForInboundGroupSessions(olmInboundGroupSessionWrappers: List<OlmInboundGroupSessionWrapper>)
+    fun markBackupDoneForInboundGroupSessions(olmInboundGroupSessionWrappers: List<OlmInboundGroupSessionWrapper2>)
 
     /**
      * Retrieve inbound group sessions that are not yet backed up.
@@ -318,7 +315,7 @@ internal interface IMXCryptoStore {
      * @param limit the maximum number of sessions to return.
      * @return an array of non backed up inbound group sessions.
      */
-    fun inboundGroupSessionsToBackup(limit: Int): List<OlmInboundGroupSessionWrapper>
+    fun inboundGroupSessionsToBackup(limit: Int): List<OlmInboundGroupSessionWrapper2>
 
     /**
      * Number of stored inbound group sessions.
@@ -404,12 +401,13 @@ internal interface IMXCryptoStore {
     fun storeUSKPrivateKey(usk: String?)
 
     fun getCrossSigningPrivateKeys(): PrivateKeysInfo?
+    fun getLiveCrossSigningPrivateKeys(): LiveData<Optional<PrivateKeysInfo>>
 
     fun saveBackupRecoveryKey(recoveryKey: String?, version: String?)
     fun getKeyBackupRecoveryKeyInfo() : SavedKeyBackupKeyInfo?
 
     fun setUserKeysAsTrusted(userId: String, trusted: Boolean = true)
-    fun setDeviceTrust(userId: String, deviceId: String, crossSignedVerified: Boolean, locallyVerified: Boolean)
+    fun setDeviceTrust(userId: String, deviceId: String, crossSignedVerified: Boolean, locallyVerified: Boolean?)
 
     fun clearOtherUserTrust()
 
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/db/Helper.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/db/Helper.kt
index 642c466e42..ab4f4df354 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/db/Helper.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/db/Helper.kt
@@ -62,6 +62,7 @@ fun doRealmTransaction(realmConfiguration: RealmConfiguration, action: (Realm) -
         realm.executeTransaction { action.invoke(it) }
     }
 }
+
 fun doRealmTransactionAsync(realmConfiguration: RealmConfiguration, action: (Realm) -> Unit) {
     Realm.getInstance(realmConfiguration).use { realm ->
         realm.executeTransactionAsync { action.invoke(it) }
@@ -79,31 +80,26 @@ fun serializeForRealm(o: Any?): String? {
     val baos = ByteArrayOutputStream()
     val gzis = CompatUtil.createGzipOutputStream(baos)
     val out = ObjectOutputStream(gzis)
-
-    out.writeObject(o)
-    out.close()
-
+    out.use {
+        it.writeObject(o)
+    }
     return Base64.encodeToString(baos.toByteArray(), Base64.DEFAULT)
 }
 
 /**
  * Do the opposite of serializeForRealm.
  */
+@Suppress("UNCHECKED_CAST")
 fun <T> deserializeFromRealm(string: String?): T? {
     if (string == null) {
         return null
     }
-
     val decodedB64 = Base64.decode(string.toByteArray(), Base64.DEFAULT)
 
     val bais = ByteArrayInputStream(decodedB64)
     val gzis = GZIPInputStream(bais)
     val ois = ObjectInputStream(gzis)
-
-    @Suppress("UNCHECKED_CAST")
-    val result = ois.readObject() as T
-
-    ois.close()
-
-    return result
+    return ois.use {
+        it.readObject() as T
+    }
 }
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/db/RealmCryptoStore.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/db/RealmCryptoStore.kt
index bd51cf8539..17f049512c 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/db/RealmCryptoStore.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/db/RealmCryptoStore.kt
@@ -36,16 +36,17 @@ import im.vector.matrix.android.internal.crypto.OutgoingGossipingRequestState
 import im.vector.matrix.android.internal.crypto.OutgoingRoomKeyRequest
 import im.vector.matrix.android.internal.crypto.OutgoingSecretRequest
 import im.vector.matrix.android.internal.crypto.algorithms.olm.OlmDecryptionResult
-import im.vector.matrix.android.internal.crypto.crosssigning.DeviceTrustLevel
 import im.vector.matrix.android.internal.crypto.model.CryptoCrossSigningKey
 import im.vector.matrix.android.internal.crypto.model.CryptoDeviceInfo
-import im.vector.matrix.android.internal.crypto.model.OlmInboundGroupSessionWrapper
+import im.vector.matrix.android.internal.crypto.model.OlmInboundGroupSessionWrapper2
 import im.vector.matrix.android.internal.crypto.model.OlmSessionWrapper
+import im.vector.matrix.android.internal.crypto.model.rest.DeviceInfo
 import im.vector.matrix.android.internal.crypto.model.rest.RoomKeyRequestBody
 import im.vector.matrix.android.internal.crypto.model.toEntity
 import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore
 import im.vector.matrix.android.internal.crypto.store.PrivateKeysInfo
 import im.vector.matrix.android.internal.crypto.store.SavedKeyBackupKeyInfo
+import im.vector.matrix.android.internal.crypto.store.db.mapper.CrossSigningKeysMapper
 import im.vector.matrix.android.internal.crypto.store.db.model.CrossSigningInfoEntity
 import im.vector.matrix.android.internal.crypto.store.db.model.CrossSigningInfoEntityFields
 import im.vector.matrix.android.internal.crypto.store.db.model.CryptoMapper
@@ -57,8 +58,8 @@ import im.vector.matrix.android.internal.crypto.store.db.model.DeviceInfoEntityF
 import im.vector.matrix.android.internal.crypto.store.db.model.GossipingEventEntity
 import im.vector.matrix.android.internal.crypto.store.db.model.IncomingGossipingRequestEntity
 import im.vector.matrix.android.internal.crypto.store.db.model.IncomingGossipingRequestEntityFields
-import im.vector.matrix.android.internal.crypto.store.db.model.KeyInfoEntity
 import im.vector.matrix.android.internal.crypto.store.db.model.KeysBackupDataEntity
+import im.vector.matrix.android.internal.crypto.store.db.model.MyDeviceLastSeenInfoEntity
 import im.vector.matrix.android.internal.crypto.store.db.model.OlmInboundGroupSessionEntity
 import im.vector.matrix.android.internal.crypto.store.db.model.OlmInboundGroupSessionEntityFields
 import im.vector.matrix.android.internal.crypto.store.db.model.OlmSessionEntity
@@ -79,7 +80,6 @@ import im.vector.matrix.android.internal.di.MoshiProvider
 import im.vector.matrix.android.internal.session.SessionScope
 import io.realm.Realm
 import io.realm.RealmConfiguration
-import io.realm.RealmList
 import io.realm.Sort
 import io.realm.kotlin.where
 import org.matrix.olm.OlmAccount
@@ -91,6 +91,7 @@ import kotlin.collections.set
 @SessionScope
 internal class RealmCryptoStore @Inject constructor(
         @CryptoDatabase private val realmConfiguration: RealmConfiguration,
+        private val crossSigningKeysMapper: CrossSigningKeysMapper,
         private val credentials: Credentials) : IMXCryptoStore {
 
     /* ==========================================================================================
@@ -107,7 +108,7 @@ internal class RealmCryptoStore @Inject constructor(
     private val olmSessionsToRelease = HashMap<String, OlmSessionWrapper>()
 
     // Cache for InboundGroupSession, to release them properly
-    private val inboundGroupSessionToRelease = HashMap<String, OlmInboundGroupSessionWrapper>()
+    private val inboundGroupSessionToRelease = HashMap<String, OlmInboundGroupSessionWrapper2>()
 
     private val newSessionListeners = ArrayList<NewSessionListener>()
 
@@ -200,9 +201,9 @@ internal class RealmCryptoStore @Inject constructor(
     }
 
     override fun getDeviceId(): String {
-        return doRealmQueryAndCopy(realmConfiguration) {
-            it.where<CryptoMetadataEntity>().findFirst()
-        }?.deviceId ?: ""
+        return doWithRealm(realmConfiguration) {
+            it.where<CryptoMetadataEntity>().findFirst()?.deviceId
+        } ?: ""
     }
 
     override fun saveOlmAccount() {
@@ -232,48 +233,26 @@ internal class RealmCryptoStore @Inject constructor(
         return olmAccount!!
     }
 
-    override fun storeUserDevice(userId: String?, deviceInfo: CryptoDeviceInfo?) {
-        if (userId == null || deviceInfo == null) {
-            return
-        }
-
-        doRealmTransaction(realmConfiguration) { realm ->
-            val user = UserEntity.getOrCreate(realm, userId)
-
-            // Create device info
-            val deviceInfoEntity = CryptoMapper.mapToEntity(deviceInfo)
-            realm.insertOrUpdate(deviceInfoEntity)
-//            val deviceInfoEntity = DeviceInfoEntity.getOrCreate(it, userId, deviceInfo.deviceId).apply {
-//                deviceId = deviceInfo.deviceId
-//                identityKey = deviceInfo.identityKey()
-//                putDeviceInfo(deviceInfo)
-//            }
-
-            if (!user.devices.contains(deviceInfoEntity)) {
-                user.devices.add(deviceInfoEntity)
-            }
-        }
-    }
-
     override fun getUserDevice(userId: String, deviceId: String): CryptoDeviceInfo? {
-        return doRealmQueryAndCopy(realmConfiguration) {
+        return doWithRealm(realmConfiguration) {
             it.where<DeviceInfoEntity>()
                     .equalTo(DeviceInfoEntityFields.PRIMARY_KEY, DeviceInfoEntity.createPrimaryKey(userId, deviceId))
                     .findFirst()
-        }?.let {
-            CryptoMapper.mapToModel(it)
+                    ?.let { deviceInfo ->
+                        CryptoMapper.mapToModel(deviceInfo)
+                    }
         }
     }
 
     override fun deviceWithIdentityKey(identityKey: String): CryptoDeviceInfo? {
-        return doRealmQueryAndCopy(realmConfiguration) {
+        return doWithRealm(realmConfiguration) {
             it.where<DeviceInfoEntity>()
                     .equalTo(DeviceInfoEntityFields.IDENTITY_KEY, identityKey)
                     .findFirst()
+                    ?.let { deviceInfo ->
+                        CryptoMapper.mapToModel(deviceInfo)
+                    }
         }
-                ?.let {
-                    CryptoMapper.mapToModel(it)
-                }
     }
 
     override fun storeUserDevices(userId: String, devices: Map<String, CryptoDeviceInfo>?) {
@@ -285,10 +264,16 @@ internal class RealmCryptoStore @Inject constructor(
                 UserEntity.getOrCreate(realm, userId)
                         .let { u ->
                             // Add the devices
+                            val currentKnownDevices = u.devices.toList()
+                            val new = devices.map { entry -> entry.value.toEntity() }
+                            new.forEach { entity ->
+                                // Maintain first time seen
+                                val existing = currentKnownDevices.firstOrNull { it.deviceId == entity.deviceId && it.identityKey == entity.identityKey }
+                                entity.firstTimeSeenLocalTs = existing?.firstTimeSeenLocalTs ?: System.currentTimeMillis()
+                                realm.insertOrUpdate(entity)
+                            }
                             // Ensure all other devices are deleted
                             u.devices.deleteAllFromRealm()
-                            val new = devices.map { entry -> entry.value.toEntity() }
-                            new.forEach { realm.insertOrUpdate(it) }
                             u.devices.addAll(new)
                         }
             }
@@ -309,36 +294,19 @@ internal class RealmCryptoStore @Inject constructor(
                         } else {
                             CrossSigningInfoEntity.getOrCreate(realm, userId).let { signingInfo ->
                                 // What should we do if we detect a change of the keys?
-
                                 val existingMaster = signingInfo.getMasterKey()
                                 if (existingMaster != null && existingMaster.publicKeyBase64 == masterKey.unpaddedBase64PublicKey) {
-                                    // update signatures?
-                                    existingMaster.putSignatures(masterKey.signatures)
-                                    existingMaster.usages = masterKey.usages?.toTypedArray()?.let { RealmList(*it) }
-                                            ?: RealmList()
+                                    crossSigningKeysMapper.update(existingMaster, masterKey)
                                 } else {
-                                    val keyEntity = realm.createObject(KeyInfoEntity::class.java).apply {
-                                        this.publicKeyBase64 = masterKey.unpaddedBase64PublicKey
-                                        this.usages = masterKey.usages?.toTypedArray()?.let { RealmList(*it) }
-                                                ?: RealmList()
-                                        this.putSignatures(masterKey.signatures)
-                                    }
+                                    val keyEntity = crossSigningKeysMapper.map(masterKey)
                                     signingInfo.setMasterKey(keyEntity)
                                 }
 
                                 val existingSelfSigned = signingInfo.getSelfSignedKey()
                                 if (existingSelfSigned != null && existingSelfSigned.publicKeyBase64 == selfSigningKey.unpaddedBase64PublicKey) {
-                                    // update signatures?
-                                    existingSelfSigned.putSignatures(selfSigningKey.signatures)
-                                    existingSelfSigned.usages = selfSigningKey.usages?.toTypedArray()?.let { RealmList(*it) }
-                                            ?: RealmList()
+                                    crossSigningKeysMapper.update(existingSelfSigned, selfSigningKey)
                                 } else {
-                                    val keyEntity = realm.createObject(KeyInfoEntity::class.java).apply {
-                                        this.publicKeyBase64 = selfSigningKey.unpaddedBase64PublicKey
-                                        this.usages = selfSigningKey.usages?.toTypedArray()?.let { RealmList(*it) }
-                                                ?: RealmList()
-                                        this.putSignatures(selfSigningKey.signatures)
-                                    }
+                                    val keyEntity = crossSigningKeysMapper.map(selfSigningKey)
                                     signingInfo.setSelfSignedKey(keyEntity)
                                 }
 
@@ -346,21 +314,12 @@ internal class RealmCryptoStore @Inject constructor(
                                 if (userSigningKey != null) {
                                     val existingUSK = signingInfo.getUserSigningKey()
                                     if (existingUSK != null && existingUSK.publicKeyBase64 == userSigningKey.unpaddedBase64PublicKey) {
-                                        // update signatures?
-                                        existingUSK.putSignatures(userSigningKey.signatures)
-                                        existingUSK.usages = userSigningKey.usages?.toTypedArray()?.let { RealmList(*it) }
-                                                ?: RealmList()
+                                        crossSigningKeysMapper.update(existingUSK, userSigningKey)
                                     } else {
-                                        val keyEntity = realm.createObject(KeyInfoEntity::class.java).apply {
-                                            this.publicKeyBase64 = userSigningKey.unpaddedBase64PublicKey
-                                            this.usages = userSigningKey.usages?.toTypedArray()?.let { RealmList(*it) }
-                                                    ?: RealmList()
-                                            this.putSignatures(userSigningKey.signatures)
-                                        }
+                                        val keyEntity = crossSigningKeysMapper.map(userSigningKey)
                                         signingInfo.setUserSignedKey(keyEntity)
                                     }
                                 }
-
                                 userEntity.crossSigningInfoEntity = signingInfo
                             }
                         }
@@ -369,14 +328,35 @@ internal class RealmCryptoStore @Inject constructor(
     }
 
     override fun getCrossSigningPrivateKeys(): PrivateKeysInfo? {
-        return doRealmQueryAndCopy(realmConfiguration) { realm ->
-            realm.where<CryptoMetadataEntity>().findFirst()
-        }?.let {
-            PrivateKeysInfo(
-                    master = it.xSignMasterPrivateKey,
-                    selfSigned = it.xSignSelfSignedPrivateKey,
-                    user = it.xSignUserPrivateKey
-            )
+        return doWithRealm(realmConfiguration) { realm ->
+            realm.where<CryptoMetadataEntity>()
+                    .findFirst()
+                    ?.let {
+                        PrivateKeysInfo(
+                                master = it.xSignMasterPrivateKey,
+                                selfSigned = it.xSignSelfSignedPrivateKey,
+                                user = it.xSignUserPrivateKey
+                        )
+                    }
+        }
+    }
+
+    override fun getLiveCrossSigningPrivateKeys(): LiveData<Optional<PrivateKeysInfo>> {
+        val liveData = monarchy.findAllMappedWithChanges(
+                { realm: Realm ->
+                    realm
+                            .where<CryptoMetadataEntity>()
+                },
+                {
+                    PrivateKeysInfo(
+                            master = it.xSignMasterPrivateKey,
+                            selfSigned = it.xSignSelfSignedPrivateKey,
+                            user = it.xSignUserPrivateKey
+                    )
+                }
+        )
+        return Transformations.map(liveData) {
+            it.firstOrNull().toOptional()
         }
     }
 
@@ -400,16 +380,18 @@ internal class RealmCryptoStore @Inject constructor(
     }
 
     override fun getKeyBackupRecoveryKeyInfo(): SavedKeyBackupKeyInfo? {
-        return doRealmQueryAndCopy(realmConfiguration) { realm ->
-            realm.where<CryptoMetadataEntity>().findFirst()
-        }?.let {
-            val key = it.keyBackupRecoveryKey
-            val version = it.keyBackupRecoveryKeyVersion
-            if (!key.isNullOrBlank() && !version.isNullOrBlank()) {
-                SavedKeyBackupKeyInfo(recoveryKey = key, version = version)
-            } else {
-                null
-            }
+        return doWithRealm(realmConfiguration) { realm ->
+            realm.where<CryptoMetadataEntity>()
+                    .findFirst()
+                    ?.let {
+                        val key = it.keyBackupRecoveryKey
+                        val version = it.keyBackupRecoveryKeyVersion
+                        if (!key.isNullOrBlank() && !version.isNullOrBlank()) {
+                            SavedKeyBackupKeyInfo(recoveryKey = key, version = version)
+                        } else {
+                            null
+                        }
+                    }
         }
     }
 
@@ -430,24 +412,30 @@ internal class RealmCryptoStore @Inject constructor(
     }
 
     override fun getUserDevices(userId: String): Map<String, CryptoDeviceInfo>? {
-        return doRealmQueryAndCopy(realmConfiguration) {
+        return doWithRealm(realmConfiguration) {
             it.where<UserEntity>()
                     .equalTo(UserEntityFields.USER_ID, userId)
                     .findFirst()
+                    ?.devices
+                    ?.map { deviceInfo ->
+                        CryptoMapper.mapToModel(deviceInfo)
+                    }
+                    ?.associateBy { cryptoDevice ->
+                        cryptoDevice.deviceId
+                    }
         }
-                ?.devices
-                ?.map { CryptoMapper.mapToModel(it) }
-                ?.associateBy { it.deviceId }
     }
 
     override fun getUserDeviceList(userId: String): List<CryptoDeviceInfo>? {
-        return doRealmQueryAndCopy(realmConfiguration) {
+        return doWithRealm(realmConfiguration) {
             it.where<UserEntity>()
                     .equalTo(UserEntityFields.USER_ID, userId)
                     .findFirst()
+                    ?.devices
+                    ?.map { deviceInfo ->
+                        CryptoMapper.mapToModel(deviceInfo)
+                    }
         }
-                ?.devices
-                ?.map { CryptoMapper.mapToModel(it) }
     }
 
     override fun getLiveDeviceList(userId: String): LiveData<List<CryptoDeviceInfo>> {
@@ -496,6 +484,52 @@ internal class RealmCryptoStore @Inject constructor(
         }
     }
 
+    override fun getMyDevicesInfo(): List<DeviceInfo> {
+        return monarchy.fetchAllCopiedSync {
+            it.where<MyDeviceLastSeenInfoEntity>()
+        }.map {
+            DeviceInfo(
+                    deviceId = it.deviceId,
+                    lastSeenIp = it.lastSeenIp,
+                    lastSeenTs = it.lastSeenTs,
+                    displayName = it.displayName
+            )
+        }
+    }
+
+    override fun getLiveMyDevicesInfo(): LiveData<List<DeviceInfo>> {
+        return monarchy.findAllMappedWithChanges(
+                { realm: Realm ->
+                    realm.where<MyDeviceLastSeenInfoEntity>()
+                },
+                { entity ->
+                    DeviceInfo(
+                            deviceId = entity.deviceId,
+                            lastSeenIp = entity.lastSeenIp,
+                            lastSeenTs = entity.lastSeenTs,
+                            displayName = entity.displayName
+                    )
+                }
+        )
+    }
+
+    override fun saveMyDevicesInfo(info: List<DeviceInfo>) {
+        val entities = info.map {
+            MyDeviceLastSeenInfoEntity(
+                    lastSeenTs = it.lastSeenTs,
+                    lastSeenIp = it.lastSeenIp,
+                    displayName = it.displayName,
+                    deviceId = it.deviceId
+            )
+        }
+        monarchy.writeAsync { realm ->
+            realm.where<MyDeviceLastSeenInfoEntity>().findAll().deleteAllFromRealm()
+            entities.forEach {
+                realm.insertOrUpdate(it)
+            }
+        }
+    }
+
     override fun storeRoomAlgorithm(roomId: String, algorithm: String) {
         doRealmTransaction(realmConfiguration) {
             CryptoRoomEntity.getOrCreate(it, roomId).algorithm = algorithm
@@ -503,17 +537,16 @@ internal class RealmCryptoStore @Inject constructor(
     }
 
     override fun getRoomAlgorithm(roomId: String): String? {
-        return doRealmQueryAndCopy(realmConfiguration) {
-            CryptoRoomEntity.getById(it, roomId)
+        return doWithRealm(realmConfiguration) {
+            CryptoRoomEntity.getById(it, roomId)?.algorithm
         }
-                ?.algorithm
     }
 
     override fun shouldEncryptForInvitedMembers(roomId: String): Boolean {
-        return doRealmQueryAndCopy(realmConfiguration) {
-            CryptoRoomEntity.getById(it, roomId)
+        return doWithRealm(realmConfiguration) {
+            CryptoRoomEntity.getById(it, roomId)?.shouldEncryptForInvitedMembers
         }
-                ?.shouldEncryptForInvitedMembers ?: false
+                ?: false
     }
 
     override fun setShouldEncryptForInvitedMembers(roomId: String, shouldEncryptForInvitedMembers: Boolean) {
@@ -555,11 +588,7 @@ internal class RealmCryptoStore @Inject constructor(
         }
     }
 
-    override fun getDeviceSession(sessionId: String?, deviceKey: String?): OlmSessionWrapper? {
-        if (sessionId == null || deviceKey == null) {
-            return null
-        }
-
+    override fun getDeviceSession(sessionId: String, deviceKey: String): OlmSessionWrapper? {
         val key = OlmSessionEntity.createPrimaryKey(sessionId, deviceKey)
 
         // If not in cache (or not found), try to read it from realm
@@ -581,28 +610,28 @@ internal class RealmCryptoStore @Inject constructor(
     }
 
     override fun getLastUsedSessionId(deviceKey: String): String? {
-        return doRealmQueryAndCopy(realmConfiguration) {
+        return doWithRealm(realmConfiguration) {
             it.where<OlmSessionEntity>()
                     .equalTo(OlmSessionEntityFields.DEVICE_KEY, deviceKey)
                     .sort(OlmSessionEntityFields.LAST_RECEIVED_MESSAGE_TS, Sort.DESCENDING)
                     .findFirst()
+                    ?.sessionId
         }
-                ?.sessionId
     }
 
     override fun getDeviceSessionIds(deviceKey: String): MutableSet<String> {
-        return doRealmQueryAndCopyList(realmConfiguration) {
+        return doWithRealm(realmConfiguration) {
             it.where<OlmSessionEntity>()
                     .equalTo(OlmSessionEntityFields.DEVICE_KEY, deviceKey)
                     .findAll()
+                    .mapNotNull { sessionEntity ->
+                        sessionEntity.sessionId
+                    }
         }
-                .mapNotNull {
-                    it.sessionId
-                }
                 .toMutableSet()
     }
 
-    override fun storeInboundGroupSessions(sessions: List<OlmInboundGroupSessionWrapper>) {
+    override fun storeInboundGroupSessions(sessions: List<OlmInboundGroupSessionWrapper2>) {
         if (sessions.isEmpty()) {
             return
         }
@@ -640,17 +669,17 @@ internal class RealmCryptoStore @Inject constructor(
         }
     }
 
-    override fun getInboundGroupSession(sessionId: String, senderKey: String): OlmInboundGroupSessionWrapper? {
+    override fun getInboundGroupSession(sessionId: String, senderKey: String): OlmInboundGroupSessionWrapper2? {
         val key = OlmInboundGroupSessionEntity.createPrimaryKey(sessionId, senderKey)
 
         // If not in cache (or not found), try to read it from realm
         if (inboundGroupSessionToRelease[key] == null) {
-            doRealmQueryAndCopy(realmConfiguration) {
+            doWithRealm(realmConfiguration) {
                 it.where<OlmInboundGroupSessionEntity>()
                         .equalTo(OlmInboundGroupSessionEntityFields.PRIMARY_KEY, key)
                         .findFirst()
+                        ?.getInboundGroupSession()
             }
-                    ?.getInboundGroupSession()
                     ?.let {
                         inboundGroupSessionToRelease[key] = it
                     }
@@ -660,17 +689,17 @@ internal class RealmCryptoStore @Inject constructor(
     }
 
     /**
-     * Note: the result will be only use to export all the keys and not to use the OlmInboundGroupSessionWrapper,
+     * Note: the result will be only use to export all the keys and not to use the OlmInboundGroupSessionWrapper2,
      * so there is no need to use or update `inboundGroupSessionToRelease` for native memory management
      */
-    override fun getInboundGroupSessions(): MutableList<OlmInboundGroupSessionWrapper> {
-        return doRealmQueryAndCopyList(realmConfiguration) {
+    override fun getInboundGroupSessions(): MutableList<OlmInboundGroupSessionWrapper2> {
+        return doWithRealm(realmConfiguration) {
             it.where<OlmInboundGroupSessionEntity>()
                     .findAll()
+                    .mapNotNull { inboundGroupSessionEntity ->
+                        inboundGroupSessionEntity.getInboundGroupSession()
+                    }
         }
-                .mapNotNull {
-                    it.getInboundGroupSession()
-                }
                 .toMutableList()
     }
 
@@ -735,7 +764,7 @@ internal class RealmCryptoStore @Inject constructor(
         }
     }
 
-    override fun markBackupDoneForInboundGroupSessions(olmInboundGroupSessionWrappers: List<OlmInboundGroupSessionWrapper>) {
+    override fun markBackupDoneForInboundGroupSessions(olmInboundGroupSessionWrappers: List<OlmInboundGroupSessionWrapper2>) {
         if (olmInboundGroupSessionWrappers.isEmpty()) {
             return
         }
@@ -758,14 +787,15 @@ internal class RealmCryptoStore @Inject constructor(
         }
     }
 
-    override fun inboundGroupSessionsToBackup(limit: Int): List<OlmInboundGroupSessionWrapper> {
-        return doRealmQueryAndCopyList(realmConfiguration) {
+    override fun inboundGroupSessionsToBackup(limit: Int): List<OlmInboundGroupSessionWrapper2> {
+        return doWithRealm(realmConfiguration) {
             it.where<OlmInboundGroupSessionEntity>()
                     .equalTo(OlmInboundGroupSessionEntityFields.BACKED_UP, false)
                     .limit(limit.toLong())
                     .findAll()
-        }.mapNotNull { inboundGroupSession ->
-            inboundGroupSession.getInboundGroupSession()
+                    .mapNotNull { inboundGroupSession ->
+                        inboundGroupSession.getInboundGroupSession()
+                    }
         }
     }
 
@@ -789,10 +819,9 @@ internal class RealmCryptoStore @Inject constructor(
     }
 
     override fun getGlobalBlacklistUnverifiedDevices(): Boolean {
-        return doRealmQueryAndCopy(realmConfiguration) {
-            it.where<CryptoMetadataEntity>().findFirst()
-        }?.globalBlacklistUnverifiedDevices
-                ?: false
+        return doWithRealm(realmConfiguration) {
+            it.where<CryptoMetadataEntity>().findFirst()?.globalBlacklistUnverifiedDevices
+        } ?: false
     }
 
     override fun setRoomsListBlacklistUnverifiedDevices(roomIds: List<String>) {
@@ -815,28 +844,28 @@ internal class RealmCryptoStore @Inject constructor(
     }
 
     override fun getRoomsListBlacklistUnverifiedDevices(): MutableList<String> {
-        return doRealmQueryAndCopyList(realmConfiguration) {
+        return doWithRealm(realmConfiguration) {
             it.where<CryptoRoomEntity>()
                     .equalTo(CryptoRoomEntityFields.BLACKLIST_UNVERIFIED_DEVICES, true)
                     .findAll()
+                    .mapNotNull { cryptoRoom ->
+                        cryptoRoom.roomId
+                    }
         }
-                .mapNotNull {
-                    it.roomId
-                }
                 .toMutableList()
     }
 
     override fun getDeviceTrackingStatuses(): MutableMap<String, Int> {
-        return doRealmQueryAndCopyList(realmConfiguration) {
+        return doWithRealm(realmConfiguration) {
             it.where<UserEntity>()
                     .findAll()
+                    .associateBy { user ->
+                        user.userId!!
+                    }
+                    .mapValues { entry ->
+                        entry.value.deviceTrackingStatus
+                    }
         }
-                .associateBy {
-                    it.userId!!
-                }
-                .mapValues {
-                    it.value.deviceTrackingStatus
-                }
                 .toMutableMap()
     }
 
@@ -851,12 +880,12 @@ internal class RealmCryptoStore @Inject constructor(
     }
 
     override fun getDeviceTrackingStatus(userId: String, defaultValue: Int): Int {
-        return doRealmQueryAndCopy(realmConfiguration) {
+        return doWithRealm(realmConfiguration) {
             it.where<UserEntity>()
                     .equalTo(UserEntityFields.USER_ID, userId)
                     .findFirst()
+                    ?.deviceTrackingStatus
         }
-                ?.deviceTrackingStatus
                 ?: defaultValue
     }
 
@@ -1093,63 +1122,65 @@ internal class RealmCryptoStore @Inject constructor(
     }
 
     override fun getIncomingRoomKeyRequest(userId: String, deviceId: String, requestId: String): IncomingRoomKeyRequest? {
-        return doRealmQueryAndCopyList(realmConfiguration) { realm ->
+        return doWithRealm(realmConfiguration) { realm ->
             realm.where<IncomingGossipingRequestEntity>()
                     .equalTo(IncomingGossipingRequestEntityFields.TYPE_STR, GossipRequestType.KEY.name)
                     .equalTo(IncomingGossipingRequestEntityFields.OTHER_DEVICE_ID, deviceId)
                     .equalTo(IncomingGossipingRequestEntityFields.OTHER_USER_ID, userId)
                     .findAll()
-        }.mapNotNull { entity ->
-            entity.toIncomingGossipingRequest() as? IncomingRoomKeyRequest
-        }.firstOrNull()
+                    .mapNotNull { entity ->
+                        entity.toIncomingGossipingRequest() as? IncomingRoomKeyRequest
+                    }
+                    .firstOrNull()
+        }
     }
 
     override fun getPendingIncomingRoomKeyRequests(): List<IncomingRoomKeyRequest> {
-        return doRealmQueryAndCopyList(realmConfiguration) {
+        return doWithRealm(realmConfiguration) {
             it.where<IncomingGossipingRequestEntity>()
                     .equalTo(IncomingGossipingRequestEntityFields.TYPE_STR, GossipRequestType.KEY.name)
                     .equalTo(IncomingGossipingRequestEntityFields.REQUEST_STATE_STR, GossipingRequestState.PENDING.name)
                     .findAll()
+                    .map { entity ->
+                        IncomingRoomKeyRequest(
+                                userId = entity.otherUserId,
+                                deviceId = entity.otherDeviceId,
+                                requestId = entity.requestId,
+                                requestBody = entity.getRequestedKeyInfo(),
+                                localCreationTimestamp = entity.localCreationTimestamp
+                        )
+                    }
         }
-                .map { entity ->
-                    IncomingRoomKeyRequest(
-                            userId = entity.otherUserId,
-                            deviceId = entity.otherDeviceId,
-                            requestId = entity.requestId,
-                            requestBody = entity.getRequestedKeyInfo(),
-                            localCreationTimestamp = entity.localCreationTimestamp
-                    )
-                }
     }
 
     override fun getPendingIncomingGossipingRequests(): List<IncomingShareRequestCommon> {
-        return doRealmQueryAndCopyList(realmConfiguration) {
+        return doWithRealm(realmConfiguration) {
             it.where<IncomingGossipingRequestEntity>()
                     .equalTo(IncomingGossipingRequestEntityFields.REQUEST_STATE_STR, GossipingRequestState.PENDING.name)
                     .findAll()
-        }
-                .mapNotNull { entity ->
-                    when (entity.type) {
-                        GossipRequestType.KEY    -> {
-                            IncomingRoomKeyRequest(
-                                    userId = entity.otherUserId,
-                                    deviceId = entity.otherDeviceId,
-                                    requestId = entity.requestId,
-                                    requestBody = entity.getRequestedKeyInfo(),
-                                    localCreationTimestamp = entity.localCreationTimestamp
-                            )
-                        }
-                        GossipRequestType.SECRET -> {
-                            IncomingSecretShareRequest(
-                                    userId = entity.otherUserId,
-                                    deviceId = entity.otherDeviceId,
-                                    requestId = entity.requestId,
-                                    secretName = entity.getRequestedSecretName(),
-                                    localCreationTimestamp = entity.localCreationTimestamp
-                            )
+                    .mapNotNull { entity ->
+                        when (entity.type) {
+                            GossipRequestType.KEY    -> {
+                                IncomingRoomKeyRequest(
+                                        userId = entity.otherUserId,
+                                        deviceId = entity.otherDeviceId,
+                                        requestId = entity.requestId,
+                                        requestBody = entity.getRequestedKeyInfo(),
+                                        localCreationTimestamp = entity.localCreationTimestamp
+                                )
+                            }
+                            GossipRequestType.SECRET -> {
+                                IncomingSecretShareRequest(
+                                        userId = entity.otherUserId,
+                                        deviceId = entity.otherDeviceId,
+                                        requestId = entity.requestId,
+                                        secretName = entity.getRequestedSecretName(),
+                                        localCreationTimestamp = entity.localCreationTimestamp
+                                )
+                            }
                         }
                     }
-                }
+        }
     }
 
     override fun storeIncomingGossipingRequest(request: IncomingShareRequestCommon, ageLocalTS: Long?) {
@@ -1187,9 +1218,9 @@ internal class RealmCryptoStore @Inject constructor(
      * Cross Signing
      * ========================================================================================== */
     override fun getMyCrossSigningInfo(): MXCrossSigningInfo? {
-        return doRealmQueryAndCopy(realmConfiguration) {
-            it.where<CryptoMetadataEntity>().findFirst()
-        }?.userId?.let {
+        return doWithRealm(realmConfiguration) {
+            it.where<CryptoMetadataEntity>().findFirst()?.userId
+        }?.let {
             getCrossSigningInfo(it)
         }
     }
@@ -1222,7 +1253,7 @@ internal class RealmCryptoStore @Inject constructor(
         }
     }
 
-    override fun setDeviceTrust(userId: String, deviceId: String, crossSignedVerified: Boolean, locallyVerified: Boolean) {
+    override fun setDeviceTrust(userId: String, deviceId: String, crossSignedVerified: Boolean, locallyVerified: Boolean?) {
         doRealmTransaction(realmConfiguration) { realm ->
             realm.where(DeviceInfoEntity::class.java)
                     .equalTo(DeviceInfoEntityFields.PRIMARY_KEY, DeviceInfoEntity.createPrimaryKey(userId, deviceId))
@@ -1235,7 +1266,7 @@ internal class RealmCryptoStore @Inject constructor(
                                 deviceInfoEntity.trustLevelEntity = it
                             }
                         } else {
-                            trustEntity.locallyVerified = locallyVerified
+                            locallyVerified?.let { trustEntity.locallyVerified = it  }
                             trustEntity.crossSignedVerified = crossSignedVerified
                         }
                     }
@@ -1308,33 +1339,24 @@ internal class RealmCryptoStore @Inject constructor(
     }
 
     override fun getCrossSigningInfo(userId: String): MXCrossSigningInfo? {
-        return doRealmQueryAndCopy(realmConfiguration) { realm ->
-            realm.where(CrossSigningInfoEntity::class.java)
+        return doWithRealm(realmConfiguration) { realm ->
+            val crossSigningInfo = realm.where(CrossSigningInfoEntity::class.java)
                     .equalTo(CrossSigningInfoEntityFields.USER_ID, userId)
                     .findFirst()
-        }?.let { xsignInfo ->
-            mapCrossSigningInfoEntity(xsignInfo)
+            if (crossSigningInfo == null) {
+                null
+            } else {
+                mapCrossSigningInfoEntity(crossSigningInfo)
+            }
         }
     }
 
     private fun mapCrossSigningInfoEntity(xsignInfo: CrossSigningInfoEntity): MXCrossSigningInfo {
+        val userId = xsignInfo.userId ?: ""
         return MXCrossSigningInfo(
-                userId = xsignInfo.userId ?: "",
+                userId = userId,
                 crossSigningKeys = xsignInfo.crossSigningKeys.mapNotNull {
-                    val pubKey = it.publicKeyBase64 ?: return@mapNotNull null
-                    CryptoCrossSigningKey(
-                            userId = xsignInfo.userId ?: "",
-                            keys = mapOf("ed25519:$pubKey" to pubKey),
-                            usages = it.usages.map { it },
-                            signatures = it.getSignatures(),
-                            trustLevel = it.trustLevelEntity?.let {
-                                DeviceTrustLevel(
-                                        crossSigningVerified = it.crossSignedVerified ?: false,
-                                        locallyVerified = it.locallyVerified ?: false
-                                )
-                            }
-
-                    )
+                    crossSigningKeysMapper.map(userId, it)
                 }
         )
     }
@@ -1345,26 +1367,7 @@ internal class RealmCryptoStore @Inject constructor(
                     realm.where<CrossSigningInfoEntity>()
                             .equalTo(UserEntityFields.USER_ID, userId)
                 },
-                { entity ->
-                    MXCrossSigningInfo(
-                            userId = userId,
-                            crossSigningKeys = entity.crossSigningKeys.mapNotNull {
-                                val pubKey = it.publicKeyBase64 ?: return@mapNotNull null
-                                CryptoCrossSigningKey(
-                                        userId = userId,
-                                        keys = mapOf("ed25519:$pubKey" to pubKey),
-                                        usages = it.usages.map { it },
-                                        signatures = it.getSignatures(),
-                                        trustLevel = it.trustLevelEntity?.let {
-                                            DeviceTrustLevel(
-                                                    crossSigningVerified = it.crossSignedVerified ?: false,
-                                                    locallyVerified = it.locallyVerified ?: false
-                                            )
-                                        }
-                                )
-                            }
-                    )
-                }
+                { mapCrossSigningInfoEntity(it) }
         )
         return Transformations.map(liveData) {
             it.firstOrNull().toOptional()
@@ -1395,31 +1398,21 @@ internal class RealmCryptoStore @Inject constructor(
     }
 
     private fun addOrUpdateCrossSigningInfo(realm: Realm, userId: String, info: MXCrossSigningInfo?): CrossSigningInfoEntity? {
-        var existing = CrossSigningInfoEntity.get(realm, userId)
         if (info == null) {
             // Delete known if needed
-            existing?.deleteFromRealm()
+            CrossSigningInfoEntity.get(realm, userId)?.deleteFromRealm()
+            return null
             // TODO notify, we might need to untrust things?
         } else {
             // Just override existing, caller should check and untrust id needed
-            existing = CrossSigningInfoEntity.getOrCreate(realm, userId)
-            // existing.crossSigningKeys.forEach { it.deleteFromRealm() }
-            val xkeys = RealmList<KeyInfoEntity>()
-            info.crossSigningKeys.forEach { cryptoCrossSigningKey ->
-                xkeys.add(
-                        realm.createObject(KeyInfoEntity::class.java).also { keyInfoEntity ->
-                            keyInfoEntity.publicKeyBase64 = cryptoCrossSigningKey.unpaddedBase64PublicKey
-                            keyInfoEntity.usages = cryptoCrossSigningKey.usages?.let { RealmList(*it.toTypedArray()) }
-                                    ?: RealmList()
-                            keyInfoEntity.putSignatures(cryptoCrossSigningKey.signatures)
-                            // TODO how to handle better, check if same keys?
-                            // reset trust
-                            keyInfoEntity.trustLevelEntity = null
-                        }
-                )
-            }
-            existing.crossSigningKeys = xkeys
+            val existing = CrossSigningInfoEntity.getOrCreate(realm, userId)
+            existing.crossSigningKeys.forEach { it.deleteFromRealm() }
+            existing.crossSigningKeys.addAll(
+                    info.crossSigningKeys.map {
+                        crossSigningKeysMapper.map(it)
+                    }
+            )
+            return existing
         }
-        return existing
     }
 }
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/db/RealmCryptoStoreMigration.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/db/RealmCryptoStoreMigration.kt
index d5972b5686..885abb776d 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/db/RealmCryptoStoreMigration.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/db/RealmCryptoStoreMigration.kt
@@ -18,14 +18,20 @@ package im.vector.matrix.android.internal.crypto.store.db
 
 import com.squareup.moshi.Moshi
 import com.squareup.moshi.Types
+import im.vector.matrix.android.api.extensions.tryThis
 import im.vector.matrix.android.api.util.JsonDict
 import im.vector.matrix.android.internal.crypto.model.MXDeviceInfo
+import im.vector.matrix.android.internal.crypto.model.OlmInboundGroupSessionWrapper
+import im.vector.matrix.android.internal.crypto.model.OlmInboundGroupSessionWrapper2
+import im.vector.matrix.android.internal.crypto.store.db.mapper.CrossSigningKeysMapper
 import im.vector.matrix.android.internal.crypto.store.db.model.CrossSigningInfoEntityFields
 import im.vector.matrix.android.internal.crypto.store.db.model.CryptoMetadataEntityFields
 import im.vector.matrix.android.internal.crypto.store.db.model.DeviceInfoEntityFields
 import im.vector.matrix.android.internal.crypto.store.db.model.GossipingEventEntityFields
 import im.vector.matrix.android.internal.crypto.store.db.model.IncomingGossipingRequestEntityFields
 import im.vector.matrix.android.internal.crypto.store.db.model.KeyInfoEntityFields
+import im.vector.matrix.android.internal.crypto.store.db.model.MyDeviceLastSeenInfoEntityFields
+import im.vector.matrix.android.internal.crypto.store.db.model.OlmInboundGroupSessionEntityFields
 import im.vector.matrix.android.internal.crypto.store.db.model.OutgoingGossipingRequestEntityFields
 import im.vector.matrix.android.internal.crypto.store.db.model.TrustLevelEntityFields
 import im.vector.matrix.android.internal.crypto.store.db.model.UserEntityFields
@@ -33,11 +39,14 @@ import im.vector.matrix.android.internal.di.SerializeNulls
 import io.realm.DynamicRealm
 import io.realm.RealmMigration
 import timber.log.Timber
+import javax.inject.Inject
 
-internal object RealmCryptoStoreMigration : RealmMigration {
+internal class RealmCryptoStoreMigration @Inject constructor(private val crossSigningKeysMapper: CrossSigningKeysMapper) : RealmMigration {
 
     // Version 1L added Cross Signing info persistence
-    const val CRYPTO_STORE_SCHEMA_VERSION = 3L
+    companion object {
+        const val CRYPTO_STORE_SCHEMA_VERSION = 6L
+    }
 
     override fun migrate(realm: DynamicRealm, oldVersion: Long, newVersion: Long) {
         Timber.v("Migrating Realm Crypto from $oldVersion to $newVersion")
@@ -45,6 +54,9 @@ internal object RealmCryptoStoreMigration : RealmMigration {
         if (oldVersion <= 0) migrateTo1(realm)
         if (oldVersion <= 1) migrateTo2(realm)
         if (oldVersion <= 2) migrateTo3(realm)
+        if (oldVersion <= 3) migrateTo4(realm)
+        if (oldVersion <= 4) migrateTo5(realm)
+        if (oldVersion <= 5) migrateTo6(realm)
     }
 
     private fun migrateTo1(realm: DynamicRealm) {
@@ -193,4 +205,73 @@ internal object RealmCryptoStoreMigration : RealmMigration {
                 ?.addField(CryptoMetadataEntityFields.KEY_BACKUP_RECOVERY_KEY, String::class.java)
                 ?.addField(CryptoMetadataEntityFields.KEY_BACKUP_RECOVERY_KEY_VERSION, String::class.java)
     }
+
+    private fun migrateTo4(realm: DynamicRealm) {
+        Timber.d("Updating KeyInfoEntity table")
+        val keyInfoEntities = realm.where("KeyInfoEntity").findAll()
+        try {
+            keyInfoEntities.forEach {
+                val stringSignatures = it.getString(KeyInfoEntityFields.SIGNATURES)
+                val objectSignatures: Map<String, Map<String, String>>? = deserializeFromRealm(stringSignatures)
+                val jsonSignatures = crossSigningKeysMapper.serializeSignatures(objectSignatures)
+                it.setString(KeyInfoEntityFields.SIGNATURES, jsonSignatures)
+            }
+        } catch (failure: Throwable) {
+        }
+
+        // Migrate frozen classes
+        val inboundGroupSessions = realm.where("OlmInboundGroupSessionEntity").findAll()
+        inboundGroupSessions.forEach { dynamicObject ->
+            dynamicObject.getString(OlmInboundGroupSessionEntityFields.OLM_INBOUND_GROUP_SESSION_DATA)?.let { serializedObject ->
+                try {
+                    deserializeFromRealm<OlmInboundGroupSessionWrapper?>(serializedObject)?.let { oldFormat ->
+                        val newFormat = oldFormat.exportKeys()?.let {
+                            OlmInboundGroupSessionWrapper2(it)
+                        }
+                        dynamicObject.setString(OlmInboundGroupSessionEntityFields.OLM_INBOUND_GROUP_SESSION_DATA, serializeForRealm(newFormat))
+                    }
+                } catch (failure: Throwable) {
+                    Timber.e(failure, "## OlmInboundGroupSessionEntity migration failed")
+                }
+            }
+        }
+    }
+
+    private fun migrateTo5(realm: DynamicRealm) {
+        realm.schema.create("MyDeviceLastSeenInfoEntity")
+                .addField(MyDeviceLastSeenInfoEntityFields.DEVICE_ID, String::class.java)
+                .addPrimaryKey(MyDeviceLastSeenInfoEntityFields.DEVICE_ID)
+                .addField(MyDeviceLastSeenInfoEntityFields.DISPLAY_NAME, String::class.java)
+                .addField(MyDeviceLastSeenInfoEntityFields.LAST_SEEN_IP, String::class.java)
+                .addField(MyDeviceLastSeenInfoEntityFields.LAST_SEEN_TS, Long::class.java)
+                .setNullable(MyDeviceLastSeenInfoEntityFields.LAST_SEEN_TS, true)
+
+        val now = System.currentTimeMillis()
+        realm.schema.get("DeviceInfoEntity")
+                ?.addField(DeviceInfoEntityFields.FIRST_TIME_SEEN_LOCAL_TS, Long::class.java)
+                ?.setNullable(DeviceInfoEntityFields.FIRST_TIME_SEEN_LOCAL_TS, true)
+                ?.transform { deviceInfoEntity ->
+                    tryThis {
+                        deviceInfoEntity.setLong(DeviceInfoEntityFields.FIRST_TIME_SEEN_LOCAL_TS, now)
+                    }
+                }
+    }
+
+    // Fixes duplicate devices in UserEntity#devices
+    private fun migrateTo6(realm: DynamicRealm) {
+        val userEntities = realm.where("UserEntity").findAll()
+        userEntities.forEach {
+            try {
+                val deviceList = it.getList(UserEntityFields.DEVICES.`$`)
+                        ?: return@forEach
+                val distinct = deviceList.distinctBy { it.getString(DeviceInfoEntityFields.DEVICE_ID) }
+                if (distinct.size != deviceList.size) {
+                    deviceList.clear()
+                    deviceList.addAll(distinct)
+                }
+            } catch (failure: Throwable) {
+                Timber.w(failure, "Crypto Data base migration error for migrateTo6")
+            }
+        }
+    }
 }
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/db/RealmCryptoStoreModule.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/db/RealmCryptoStoreModule.kt
index 3da91c6268..a8eb1db612 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/db/RealmCryptoStoreModule.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/db/RealmCryptoStoreModule.kt
@@ -24,6 +24,7 @@ import im.vector.matrix.android.internal.crypto.store.db.model.GossipingEventEnt
 import im.vector.matrix.android.internal.crypto.store.db.model.IncomingGossipingRequestEntity
 import im.vector.matrix.android.internal.crypto.store.db.model.KeyInfoEntity
 import im.vector.matrix.android.internal.crypto.store.db.model.KeysBackupDataEntity
+import im.vector.matrix.android.internal.crypto.store.db.model.MyDeviceLastSeenInfoEntity
 import im.vector.matrix.android.internal.crypto.store.db.model.OlmInboundGroupSessionEntity
 import im.vector.matrix.android.internal.crypto.store.db.model.OlmSessionEntity
 import im.vector.matrix.android.internal.crypto.store.db.model.OutgoingGossipingRequestEntity
@@ -48,6 +49,7 @@ import io.realm.annotations.RealmModule
             TrustLevelEntity::class,
             GossipingEventEntity::class,
             IncomingGossipingRequestEntity::class,
-            OutgoingGossipingRequestEntity::class
+            OutgoingGossipingRequestEntity::class,
+            MyDeviceLastSeenInfoEntity::class
         ])
 internal class RealmCryptoStoreModule
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/db/mapper/CrossSigningKeysMapper.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/db/mapper/CrossSigningKeysMapper.kt
new file mode 100644
index 0000000000..0e2c9c7eb7
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/db/mapper/CrossSigningKeysMapper.kt
@@ -0,0 +1,85 @@
+/*
+ * 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.matrix.android.internal.crypto.store.db.mapper
+
+import com.squareup.moshi.Moshi
+import com.squareup.moshi.Types
+import im.vector.matrix.android.internal.crypto.crosssigning.DeviceTrustLevel
+import im.vector.matrix.android.internal.crypto.model.CryptoCrossSigningKey
+import im.vector.matrix.android.internal.crypto.store.db.model.KeyInfoEntity
+import io.realm.RealmList
+import timber.log.Timber
+import javax.inject.Inject
+
+internal class CrossSigningKeysMapper @Inject constructor(moshi: Moshi) {
+
+    private val signaturesAdapter = moshi.adapter<Map<String, Map<String, String>>>(Types.newParameterizedType(
+            Map::class.java,
+            String::class.java,
+            Any::class.java
+    ))
+
+    fun update(keyInfo: KeyInfoEntity, cryptoCrossSigningKey: CryptoCrossSigningKey) {
+        // update signatures?
+        keyInfo.signatures = serializeSignatures(cryptoCrossSigningKey.signatures)
+        keyInfo.usages = cryptoCrossSigningKey.usages?.toTypedArray()?.let { RealmList(*it) }
+                ?: RealmList()
+    }
+
+    fun map(userId: String?, keyInfo: KeyInfoEntity?): CryptoCrossSigningKey? {
+        val pubKey = keyInfo?.publicKeyBase64 ?: return null
+        return CryptoCrossSigningKey(
+                userId = userId ?: "",
+                keys = mapOf("ed25519:$pubKey" to pubKey),
+                usages = keyInfo.usages.map { it },
+                signatures = deserializeSignatures(keyInfo.signatures),
+                trustLevel = keyInfo.trustLevelEntity?.let {
+                    DeviceTrustLevel(
+                            crossSigningVerified = it.crossSignedVerified ?: false,
+                            locallyVerified = it.locallyVerified ?: false
+                    )
+                }
+        )
+    }
+
+    fun map(keyInfo: CryptoCrossSigningKey): KeyInfoEntity {
+        return KeyInfoEntity().apply {
+            publicKeyBase64 = keyInfo.unpaddedBase64PublicKey
+            usages = keyInfo.usages?.let { RealmList(*it.toTypedArray()) } ?: RealmList()
+            signatures = serializeSignatures(keyInfo.signatures)
+            // TODO how to handle better, check if same keys?
+            // reset trust
+            trustLevelEntity = null
+        }
+    }
+
+    fun serializeSignatures(signatures: Map<String, Map<String, String>>?): String {
+        return signaturesAdapter.toJson(signatures)
+    }
+
+    fun deserializeSignatures(signatures: String?): Map<String, Map<String, String>>? {
+        if (signatures == null) {
+            return null
+        }
+        return try {
+            signaturesAdapter.fromJson(signatures)
+        } catch (failure: Throwable) {
+            Timber.e(failure)
+            null
+        }
+    }
+}
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/db/model/CryptoMapper.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/db/model/CryptoMapper.kt
index 5a4938d1fe..d222fe0eed 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/db/model/CryptoMapper.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/db/model/CryptoMapper.kt
@@ -104,7 +104,8 @@ object CryptoMapper {
                         Timber.e(failure)
                         null
                     }
-                }
+                },
+                firstTimeSeenLocalTs = deviceInfoEntity.firstTimeSeenLocalTs
         )
     }
 }
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/db/model/DeviceInfoEntity.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/db/model/DeviceInfoEntity.kt
index 98f931a455..7f16ad6357 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/db/model/DeviceInfoEntity.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/db/model/DeviceInfoEntity.kt
@@ -34,7 +34,12 @@ internal open class DeviceInfoEntity(@PrimaryKey var primaryKey: String = "",
                                      var keysMapJson: String? = null,
                                      var signatureMapJson: String? = null,
                                      var unsignedMapJson: String? = null,
-                                     var trustLevelEntity: TrustLevelEntity? = null
+                                     var trustLevelEntity: TrustLevelEntity? = null,
+                                     /**
+                                      * We use that to make distinction between old devices (there before mine)
+                                      * and new ones. Used for example to detect new unverified login
+                                      */
+                                     var firstTimeSeenLocalTs: Long? = null
 ) : RealmObject() {
 
 //    // Deserialize data
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/db/model/KeyInfoEntity.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/db/model/KeyInfoEntity.kt
index c40c752fbe..3ced818449 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/db/model/KeyInfoEntity.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/db/model/KeyInfoEntity.kt
@@ -16,8 +16,6 @@
 
 package im.vector.matrix.android.internal.crypto.store.db.model
 
-import im.vector.matrix.android.internal.crypto.store.db.deserializeFromRealm
-import im.vector.matrix.android.internal.crypto.store.db.serializeForRealm
 import io.realm.RealmList
 import io.realm.RealmObject
 
@@ -31,15 +29,4 @@ internal open class KeyInfoEntity(
          */
         var signatures: String? = null,
         var trustLevelEntity: TrustLevelEntity? = null
-) : RealmObject() {
-
-    // Deserialize data
-    fun getSignatures(): Map<String, Map<String, String>>? {
-        return deserializeFromRealm(signatures)
-    }
-
-    // Serialize data
-    fun putSignatures(deviceInfo: Map<String, Map<String, String>>?) {
-        signatures = serializeForRealm(deviceInfo)
-    }
-}
+) : RealmObject()
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/db/model/MyDeviceLastSeenInfoEntity.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/db/model/MyDeviceLastSeenInfoEntity.kt
new file mode 100644
index 0000000000..04d258ed5f
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/db/model/MyDeviceLastSeenInfoEntity.kt
@@ -0,0 +1,34 @@
+/*
+ * 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.matrix.android.internal.crypto.store.db.model
+
+import io.realm.RealmObject
+import io.realm.annotations.PrimaryKey
+
+internal open class MyDeviceLastSeenInfoEntity(
+        /**The device id*/
+        @PrimaryKey var deviceId: String? = null,
+        /** The device display name*/
+        var displayName: String? = null,
+        /** The last time this device has been seen. */
+        var lastSeenTs: Long? = null,
+        /** The last ip address*/
+        var lastSeenIp: String? = null
+) : RealmObject() {
+
+    companion object
+}
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/db/model/OlmInboundGroupSessionEntity.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/db/model/OlmInboundGroupSessionEntity.kt
index caa8cb9668..125fc94d1e 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/db/model/OlmInboundGroupSessionEntity.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/db/model/OlmInboundGroupSessionEntity.kt
@@ -16,11 +16,12 @@
 
 package im.vector.matrix.android.internal.crypto.store.db.model
 
-import im.vector.matrix.android.internal.crypto.model.OlmInboundGroupSessionWrapper
+import im.vector.matrix.android.internal.crypto.model.OlmInboundGroupSessionWrapper2
 import im.vector.matrix.android.internal.crypto.store.db.deserializeFromRealm
 import im.vector.matrix.android.internal.crypto.store.db.serializeForRealm
 import io.realm.RealmObject
 import io.realm.annotations.PrimaryKey
+import timber.log.Timber
 
 internal fun OlmInboundGroupSessionEntity.Companion.createPrimaryKey(sessionId: String?, senderKey: String?) = "$sessionId|$senderKey"
 
@@ -35,11 +36,16 @@ internal open class OlmInboundGroupSessionEntity(
         var backedUp: Boolean = false)
     : RealmObject() {
 
-    fun getInboundGroupSession(): OlmInboundGroupSessionWrapper? {
-        return deserializeFromRealm(olmInboundGroupSessionData)
+    fun getInboundGroupSession(): OlmInboundGroupSessionWrapper2? {
+        return try {
+            deserializeFromRealm<OlmInboundGroupSessionWrapper2?>(olmInboundGroupSessionData)
+        } catch (failure: Throwable) {
+            Timber.e(failure, "## Deserialization failure")
+            return null
+        }
     }
 
-    fun putInboundGroupSession(olmInboundGroupSessionWrapper: OlmInboundGroupSessionWrapper?) {
+    fun putInboundGroupSession(olmInboundGroupSessionWrapper: OlmInboundGroupSessionWrapper2?) {
         olmInboundGroupSessionData = serializeForRealm(olmInboundGroupSessionWrapper)
     }
 
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/tasks/DeleteDeviceTask.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/tasks/DeleteDeviceTask.kt
index fbbaa0e0f7..809ec0be44 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/tasks/DeleteDeviceTask.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/tasks/DeleteDeviceTask.kt
@@ -17,10 +17,9 @@
 package im.vector.matrix.android.internal.crypto.tasks
 
 import im.vector.matrix.android.api.failure.Failure
-import im.vector.matrix.android.internal.auth.registration.RegistrationFlowResponse
+import im.vector.matrix.android.api.failure.toRegistrationFlowResponse
 import im.vector.matrix.android.internal.crypto.api.CryptoApi
 import im.vector.matrix.android.internal.crypto.model.rest.DeleteDeviceParams
-import im.vector.matrix.android.internal.di.MoshiProvider
 import im.vector.matrix.android.internal.network.executeRequest
 import im.vector.matrix.android.internal.task.Task
 import org.greenrobot.eventbus.EventBus
@@ -43,25 +42,9 @@ internal class DefaultDeleteDeviceTask @Inject constructor(
                 apiCall = cryptoApi.deleteDevice(params.deviceId, DeleteDeviceParams())
             }
         } catch (throwable: Throwable) {
-            if (throwable is Failure.OtherServerError && throwable.httpCode == 401) {
-                // Parse to get a RegistrationFlowResponse
-                val registrationFlowResponse = try {
-                    MoshiProvider.providesMoshi()
-                            .adapter(RegistrationFlowResponse::class.java)
-                            .fromJson(throwable.errorBody)
-                } catch (e: Exception) {
-                    null
-                }
-                // check if the server response can be casted
-                if (registrationFlowResponse != null) {
-                    throw Failure.RegistrationFlowError(registrationFlowResponse)
-                } else {
-                    throw throwable
-                }
-            } else {
-                // Other error
-                throw throwable
-            }
+            throw throwable.toRegistrationFlowResponse()
+                    ?.let { Failure.RegistrationFlowError(it) }
+                    ?: throwable
         }
     }
 }
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/tasks/InitializeCrossSigningTask.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/tasks/InitializeCrossSigningTask.kt
new file mode 100644
index 0000000000..9a7d84e235
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/tasks/InitializeCrossSigningTask.kt
@@ -0,0 +1,172 @@
+/*
+ * 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.matrix.android.internal.crypto.tasks
+
+import dagger.Lazy
+import im.vector.matrix.android.internal.crypto.MXOlmDevice
+import im.vector.matrix.android.internal.crypto.MyDeviceInfoHolder
+import im.vector.matrix.android.internal.crypto.crosssigning.canonicalSignable
+import im.vector.matrix.android.internal.crypto.crosssigning.toBase64NoPadding
+import im.vector.matrix.android.internal.crypto.model.CryptoCrossSigningKey
+import im.vector.matrix.android.internal.crypto.model.KeyUsage
+import im.vector.matrix.android.internal.crypto.model.rest.UploadSignatureQueryBuilder
+import im.vector.matrix.android.internal.crypto.model.rest.UserPasswordAuth
+import im.vector.matrix.android.internal.di.UserId
+import im.vector.matrix.android.internal.task.Task
+import im.vector.matrix.android.internal.util.JsonCanonicalizer
+import org.matrix.olm.OlmPkSigning
+import timber.log.Timber
+import javax.inject.Inject
+
+internal interface InitializeCrossSigningTask : Task<InitializeCrossSigningTask.Params, InitializeCrossSigningTask.Result> {
+    data class Params(
+            val authParams: UserPasswordAuth?
+    )
+
+    data class Result(
+            val masterKeyPK: String,
+            val userKeyPK: String,
+            val selfSigningKeyPK: String,
+            val masterKeyInfo: CryptoCrossSigningKey,
+            val userKeyInfo: CryptoCrossSigningKey,
+            val selfSignedKeyInfo: CryptoCrossSigningKey
+    )
+}
+
+internal class DefaultInitializeCrossSigningTask @Inject constructor(
+        @UserId private val userId: String,
+        private val olmDevice: MXOlmDevice,
+        private val myDeviceInfoHolder: Lazy<MyDeviceInfoHolder>,
+        private val uploadSigningKeysTask: UploadSigningKeysTask,
+        private val uploadSignaturesTask: UploadSignaturesTask
+) : InitializeCrossSigningTask {
+
+    override suspend fun execute(params: InitializeCrossSigningTask.Params): InitializeCrossSigningTask.Result {
+        var masterPkOlm: OlmPkSigning? = null
+        var userSigningPkOlm: OlmPkSigning? = null
+        var selfSigningPkOlm: OlmPkSigning? = null
+
+        try {
+            // =================
+            // MASTER KEY
+            // =================
+
+            masterPkOlm = OlmPkSigning()
+            val masterKeyPrivateKey = OlmPkSigning.generateSeed()
+            val masterPublicKey = masterPkOlm.initWithSeed(masterKeyPrivateKey)
+
+            Timber.v("## CrossSigning - masterPublicKey:$masterPublicKey")
+
+            // =================
+            // USER KEY
+            // =================
+            userSigningPkOlm = OlmPkSigning()
+            val uskPrivateKey = OlmPkSigning.generateSeed()
+            val uskPublicKey = userSigningPkOlm.initWithSeed(uskPrivateKey)
+
+            Timber.v("## CrossSigning - uskPublicKey:$uskPublicKey")
+
+            // Sign userSigningKey with master
+            val signedUSK = CryptoCrossSigningKey.Builder(userId, KeyUsage.USER_SIGNING)
+                    .key(uskPublicKey)
+                    .build()
+                    .canonicalSignable()
+                    .let { masterPkOlm.sign(it) }
+
+            // =================
+            // SELF SIGNING KEY
+            // =================
+            selfSigningPkOlm = OlmPkSigning()
+            val sskPrivateKey = OlmPkSigning.generateSeed()
+            val sskPublicKey = selfSigningPkOlm.initWithSeed(sskPrivateKey)
+
+            Timber.v("## CrossSigning - sskPublicKey:$sskPublicKey")
+
+            // Sign userSigningKey with master
+            val signedSSK = CryptoCrossSigningKey.Builder(userId, KeyUsage.SELF_SIGNING)
+                    .key(sskPublicKey)
+                    .build()
+                    .canonicalSignable()
+                    .let { masterPkOlm.sign(it) }
+
+            // I need to upload the keys
+            val mskCrossSigningKeyInfo = CryptoCrossSigningKey.Builder(userId, KeyUsage.MASTER)
+                    .key(masterPublicKey)
+                    .build()
+            val uploadSigningKeysParams = UploadSigningKeysTask.Params(
+                    masterKey = mskCrossSigningKeyInfo,
+                    userKey = CryptoCrossSigningKey.Builder(userId, KeyUsage.USER_SIGNING)
+                            .key(uskPublicKey)
+                            .signature(userId, masterPublicKey, signedUSK)
+                            .build(),
+                    selfSignedKey = CryptoCrossSigningKey.Builder(userId, KeyUsage.SELF_SIGNING)
+                            .key(sskPublicKey)
+                            .signature(userId, masterPublicKey, signedSSK)
+                            .build(),
+                    userPasswordAuth = params.authParams
+            )
+
+            uploadSigningKeysTask.execute(uploadSigningKeysParams)
+
+            //  Sign the current device with SSK
+            val uploadSignatureQueryBuilder = UploadSignatureQueryBuilder()
+
+            val myDevice = myDeviceInfoHolder.get().myDevice
+            val canonicalJson = JsonCanonicalizer.getCanonicalJson(Map::class.java, myDevice.signalableJSONDictionary())
+            val signedDevice = selfSigningPkOlm.sign(canonicalJson)
+            val updateSignatures = (myDevice.signatures?.toMutableMap() ?: HashMap())
+                    .also {
+                        it[userId] = (it[userId]
+                                ?: HashMap()) + mapOf("ed25519:$sskPublicKey" to signedDevice)
+                    }
+            myDevice.copy(signatures = updateSignatures).let {
+                uploadSignatureQueryBuilder.withDeviceInfo(it)
+            }
+
+            // sign MSK with device key (migration) and upload signatures
+            val message = JsonCanonicalizer.getCanonicalJson(Map::class.java, mskCrossSigningKeyInfo.signalableJSONDictionary())
+            olmDevice.signMessage(message)?.let { sign ->
+                val mskUpdatedSignatures = (mskCrossSigningKeyInfo.signatures?.toMutableMap()
+                        ?: HashMap()).also {
+                    it[userId] = (it[userId]
+                            ?: HashMap()) + mapOf("ed25519:${myDevice.deviceId}" to sign)
+                }
+                mskCrossSigningKeyInfo.copy(
+                        signatures = mskUpdatedSignatures
+                ).let {
+                    uploadSignatureQueryBuilder.withSigningKeyInfo(it)
+                }
+            }
+
+            // TODO should we ignore failure of that?
+            uploadSignaturesTask.execute(UploadSignaturesTask.Params(uploadSignatureQueryBuilder.build()))
+
+            return InitializeCrossSigningTask.Result(
+                    masterKeyPK = masterKeyPrivateKey.toBase64NoPadding(),
+                    userKeyPK = uskPrivateKey.toBase64NoPadding(),
+                    selfSigningKeyPK = sskPrivateKey.toBase64NoPadding(),
+                    masterKeyInfo = uploadSigningKeysParams.masterKey,
+                    userKeyInfo = uploadSigningKeysParams.userKey,
+                    selfSignedKeyInfo = uploadSigningKeysParams.selfSignedKey
+            )
+        } finally {
+            masterPkOlm?.releaseSigning()
+            userSigningPkOlm?.releaseSigning()
+            selfSigningPkOlm?.releaseSigning()
+        }
+    }
+}
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/tasks/SendToDeviceTask.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/tasks/SendToDeviceTask.kt
index 58c461888b..361fd25cee 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/tasks/SendToDeviceTask.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/tasks/SendToDeviceTask.kt
@@ -52,6 +52,8 @@ internal class DefaultSendToDeviceTask @Inject constructor(
                     params.transactionId ?: Random.nextInt(Integer.MAX_VALUE).toString(),
                     sendToDeviceBody
             )
+            isRetryable = true
+            maxRetryCount = 3
         }
     }
 }
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/tasks/UploadSigningKeysTask.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/tasks/UploadSigningKeysTask.kt
index 0a69039219..a66a20617c 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/tasks/UploadSigningKeysTask.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/tasks/UploadSigningKeysTask.kt
@@ -17,14 +17,13 @@
 package im.vector.matrix.android.internal.crypto.tasks
 
 import im.vector.matrix.android.api.failure.Failure
-import im.vector.matrix.android.internal.auth.registration.RegistrationFlowResponse
+import im.vector.matrix.android.api.failure.toRegistrationFlowResponse
 import im.vector.matrix.android.internal.crypto.api.CryptoApi
 import im.vector.matrix.android.internal.crypto.model.CryptoCrossSigningKey
 import im.vector.matrix.android.internal.crypto.model.rest.KeysQueryResponse
 import im.vector.matrix.android.internal.crypto.model.rest.UploadSigningKeysBody
 import im.vector.matrix.android.internal.crypto.model.rest.UserPasswordAuth
 import im.vector.matrix.android.internal.crypto.model.toRest
-import im.vector.matrix.android.internal.di.MoshiProvider
 import im.vector.matrix.android.internal.network.executeRequest
 import im.vector.matrix.android.internal.task.Task
 import org.greenrobot.eventbus.EventBus
@@ -65,37 +64,25 @@ internal class DefaultUploadSigningKeysTask @Inject constructor(
             }
             return
         } catch (throwable: Throwable) {
-            if (throwable is Failure.OtherServerError
-                    && throwable.httpCode == 401
+            val registrationFlowResponse = throwable.toRegistrationFlowResponse()
+            if (registrationFlowResponse != null
                     && params.userPasswordAuth != null
                     /* Avoid infinite loop */
                     && params.userPasswordAuth.session.isNullOrEmpty()
             ) {
-                try {
-                    MoshiProvider.providesMoshi()
-                            .adapter(RegistrationFlowResponse::class.java)
-                            .fromJson(throwable.errorBody)
-                } catch (e: Exception) {
-                    null
-                }?.let {
-                    // Retry with authentication
-                    try {
-                        val req = executeRequest<KeysQueryResponse>(eventBus) {
-                            apiCall = cryptoApi.uploadSigningKeys(
-                                    uploadQuery.copy(auth = params.userPasswordAuth.copy(session = it.session))
-                            )
-                        }
-                        if (req.failures?.isNotEmpty() == true) {
-                            throw UploadSigningKeys(req.failures)
-                        }
-                        return
-                    } catch (failure: Throwable) {
-                        throw failure
-                    }
+                // Retry with authentication
+                val req = executeRequest<KeysQueryResponse>(eventBus) {
+                    apiCall = cryptoApi.uploadSigningKeys(
+                            uploadQuery.copy(auth = params.userPasswordAuth.copy(session = registrationFlowResponse.session))
+                    )
                 }
+                if (req.failures?.isNotEmpty() == true) {
+                    throw UploadSigningKeys(req.failures)
+                }
+            } else {
+                // Other error
+                throw throwable
             }
-            // Other error
-            throw throwable
         }
     }
 }
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/tools/Tools.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/tools/Tools.kt
index 260e6165ba..c3d2c30079 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/tools/Tools.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/tools/Tools.kt
@@ -18,6 +18,7 @@ package im.vector.matrix.android.internal.crypto.tools
 
 import org.matrix.olm.OlmPkDecryption
 import org.matrix.olm.OlmPkEncryption
+import org.matrix.olm.OlmPkSigning
 
 fun <T> withOlmEncryption(block: (OlmPkEncryption) -> T): T {
     val olmPkEncryption = OlmPkEncryption()
@@ -36,3 +37,12 @@ fun <T> withOlmDecryption(block: (OlmPkDecryption) -> T): T {
         olmPkDecryption.releaseDecryption()
     }
 }
+
+fun <T> withOlmSigning(block: (OlmPkSigning) -> T): T {
+    val olmPkSigning = OlmPkSigning()
+    try {
+        return block(olmPkSigning)
+    } finally {
+        olmPkSigning.releaseSigning()
+    }
+}
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/DefaultOutgoingSASDefaultVerificationTransaction.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/DefaultOutgoingSASDefaultVerificationTransaction.kt
index 7fd97d0231..689829b8e3 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/DefaultOutgoingSASDefaultVerificationTransaction.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/DefaultOutgoingSASDefaultVerificationTransaction.kt
@@ -138,7 +138,7 @@ internal class DefaultOutgoingSASDefaultVerificationTransaction(
 
     override fun onVerificationAccept(accept: ValidVerificationInfoAccept) {
         Timber.v("## SAS O: onVerificationAccept id:$transactionId")
-        if (state != VerificationTxState.Started) {
+        if (state != VerificationTxState.Started && state !=  VerificationTxState.SendingStart) {
             Timber.e("## SAS O: received accept request from invalid state $state")
             cancel(CancelCode.UnexpectedMessage)
             return
@@ -148,7 +148,7 @@ internal class DefaultOutgoingSASDefaultVerificationTransaction(
                 || !KNOWN_HASHES.contains(accept.hash)
                 || !KNOWN_MACS.contains(accept.messageAuthenticationCode)
                 || accept.shortAuthenticationStrings.intersect(KNOWN_SHORT_CODES).isEmpty()) {
-            Timber.e("## SAS O: received accept request from invalid state")
+            Timber.e("## SAS O: received invalid accept")
             cancel(CancelCode.UnknownMethod)
             return
         }
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/DefaultVerificationService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/DefaultVerificationService.kt
index 77dcc483bd..04a3560223 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/DefaultVerificationService.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/DefaultVerificationService.kt
@@ -82,6 +82,7 @@ import im.vector.matrix.android.internal.di.DeviceId
 import im.vector.matrix.android.internal.di.UserId
 import im.vector.matrix.android.internal.session.SessionScope
 import im.vector.matrix.android.internal.util.MatrixCoroutineDispatchers
+import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.GlobalScope
 import kotlinx.coroutines.launch
 import timber.log.Timber
@@ -102,7 +103,8 @@ internal class DefaultVerificationService @Inject constructor(
         private val coroutineDispatchers: MatrixCoroutineDispatchers,
         private val verificationTransportRoomMessageFactory: VerificationTransportRoomMessageFactory,
         private val verificationTransportToDeviceFactory: VerificationTransportToDeviceFactory,
-        private val crossSigningService: CrossSigningService
+        private val crossSigningService: CrossSigningService,
+        private val cryptoCoroutineScope: CoroutineScope
 ) : DefaultVerificationTransaction.Listener, VerificationService {
 
     private val uiHandler = Handler(Looper.getMainLooper())
@@ -125,7 +127,7 @@ internal class DefaultVerificationService @Inject constructor(
 
     // Event received from the sync
     fun onToDeviceEvent(event: Event) {
-        GlobalScope.launch(coroutineDispatchers.crypto) {
+        cryptoCoroutineScope.launch(coroutineDispatchers.crypto) {
             when (event.getClearType()) {
                 EventType.KEY_VERIFICATION_START         -> {
                     onStartRequestReceived(event)
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/SendVerificationMessageWorker.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/SendVerificationMessageWorker.kt
index 2b049e0061..95376fb0cc 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/SendVerificationMessageWorker.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/SendVerificationMessageWorker.kt
@@ -30,6 +30,10 @@ import im.vector.matrix.android.internal.worker.getSessionComponent
 import timber.log.Timber
 import javax.inject.Inject
 
+/**
+ * Possible previous worker: None
+ * Possible next worker    : None
+ */
 internal class SendVerificationMessageWorker(context: Context,
                                              params: WorkerParameters)
     : CoroutineWorker(context, params) {
@@ -48,7 +52,7 @@ internal class SendVerificationMessageWorker(context: Context,
     lateinit var cryptoService: CryptoService
 
     override suspend fun doWork(): Result {
-        val errorOutputData = Data.Builder().putBoolean("failed", true).build()
+        val errorOutputData = Data.Builder().putBoolean(OUTPUT_KEY_FAILED, true).build()
         val params = WorkerParamsFactory.fromData<Params>(inputData)
                 ?: return Result.success(errorOutputData)
 
@@ -76,4 +80,12 @@ internal class SendVerificationMessageWorker(context: Context,
             }
         }
     }
+
+    companion object {
+        private const val OUTPUT_KEY_FAILED = "failed"
+
+        fun hasFailed(outputData: Data): Boolean {
+            return outputData.getBoolean(SendVerificationMessageWorker.OUTPUT_KEY_FAILED, false)
+        }
+    }
 }
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/VerificationTransport.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/VerificationTransport.kt
index 75ffa5e082..c5c4772c51 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/VerificationTransport.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/VerificationTransport.kt
@@ -34,6 +34,9 @@ internal interface VerificationTransport {
                         onErrorReason: CancelCode,
                         onDone: (() -> Unit)?)
 
+    /**
+     * @param callback will be called with eventId and ValidVerificationInfoRequest in case of success
+     */
     fun sendVerificationRequest(supportedMethods: List<String>,
                                 localId: String,
                                 otherUserId: String,
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/VerificationTransportRoomMessage.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/VerificationTransportRoomMessage.kt
index b7b7335011..77234e82f4 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/VerificationTransportRoomMessage.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/VerificationTransportRoomMessage.kt
@@ -115,7 +115,7 @@ internal class VerificationTransportRoomMessage(
                         ?.filter { it.state == WorkInfo.State.SUCCEEDED }
                         ?.firstOrNull { it.id == enqueueInfo.second }
                         ?.let { wInfo ->
-                            if (wInfo.outputData.getBoolean("failed", false)) {
+                            if (SendVerificationMessageWorker.hasFailed(wInfo.outputData)) {
                                 Timber.e("## SAS verification [${tx?.transactionId}] failed to send verification message in state : ${tx?.state}")
                                 tx?.cancel(onErrorReason)
                             } else {
@@ -196,12 +196,15 @@ internal class VerificationTransportRoomMessage(
                         ?.filter { it.state == WorkInfo.State.SUCCEEDED }
                         ?.firstOrNull { it.id == workRequest.id }
                         ?.let { wInfo ->
-                            if (wInfo.outputData.getBoolean("failed", false)) {
+                            if (SendVerificationMessageWorker.hasFailed(wInfo.outputData)) {
                                 callback(null, null)
-                            } else if (wInfo.outputData.getString(localId) != null) {
-                                callback(wInfo.outputData.getString(localId), validInfo)
                             } else {
-                                callback(null, null)
+                                val eventId = wInfo.outputData.getString(localId)
+                                if (eventId != null) {
+                                    callback(eventId, validInfo)
+                                } else {
+                                    callback(null, null)
+                                }
                             }
                             workLiveData.removeObserver(this)
                         }
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/VerificationTransportToDevice.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/VerificationTransportToDevice.kt
index 290fc88878..59a5b80b99 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/VerificationTransportToDevice.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/VerificationTransportToDevice.kt
@@ -117,6 +117,7 @@ internal class VerificationTransportToDevice(
                                  onDone: (() -> Unit)?) {
         Timber.d("## SAS sending msg type $type")
         Timber.v("## SAS sending msg info $verificationInfo")
+        val stateBeforeCall = tx?.state
         val tx = tx ?: return
         val contentMap = MXUsersDevicesMap<Any>()
         val toSendToDeviceObject = verificationInfo.toSendToDeviceObject()
@@ -132,7 +133,11 @@ internal class VerificationTransportToDevice(
                             if (onDone != null) {
                                 onDone()
                             } else {
-                                tx.state = nextState
+                                // we may have received next state (e.g received accept in sending_start)
+                                // We only put next state if the state was what is was before we started
+                                if (tx.state == stateBeforeCall) {
+                                    tx.state = nextState
+                                }
                             }
                         }
 
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/qrcode/DefaultQrCodeVerificationTransaction.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/qrcode/DefaultQrCodeVerificationTransaction.kt
index 59ee23cc62..53fecc4865 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/qrcode/DefaultQrCodeVerificationTransaction.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/qrcode/DefaultQrCodeVerificationTransaction.kt
@@ -177,7 +177,7 @@ internal class DefaultQrCodeVerificationTransaction(
         }.exhaustive
 
         if (!canTrustOtherUserMasterKey && toVerifyDeviceIds.isEmpty()) {
-            //            // Nothing to verify
+            // Nothing to verify
             cancel(CancelCode.MismatchedKeys)
             return
         }
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/mapper/HomeServerCapabilitiesMapper.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/mapper/HomeServerCapabilitiesMapper.kt
index 66b0f1b379..a0d3662e03 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/mapper/HomeServerCapabilitiesMapper.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/mapper/HomeServerCapabilitiesMapper.kt
@@ -26,12 +26,14 @@ internal object HomeServerCapabilitiesMapper {
 
     fun map(entity: HomeServerCapabilitiesEntity): HomeServerCapabilities {
         return HomeServerCapabilities(
+                canChangePassword = entity.canChangePassword,
                 maxUploadFileSize = entity.maxUploadFileSize
         )
     }
 
     fun map(domain: HomeServerCapabilities): HomeServerCapabilitiesEntity {
         return HomeServerCapabilitiesEntity(
+                canChangePassword = domain.canChangePassword,
                 maxUploadFileSize = domain.maxUploadFileSize
         )
     }
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/mapper/RoomSummaryMapper.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/mapper/RoomSummaryMapper.kt
index 2f3cdb9545..20651069b0 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/mapper/RoomSummaryMapper.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/mapper/RoomSummaryMapper.kt
@@ -53,6 +53,7 @@ internal class RoomSummaryMapper @Inject constructor(private val timelineEventMa
                 canonicalAlias = roomSummaryEntity.canonicalAlias,
                 aliases = roomSummaryEntity.aliases.toList(),
                 isEncrypted = roomSummaryEntity.isEncrypted,
+                encryptionEventTs = roomSummaryEntity.encryptionEventTs,
                 typingRoomMemberIds = roomSummaryEntity.typingUserIds.toList(),
                 breadcrumbsIndex = roomSummaryEntity.breadcrumbsIndex,
                 roomEncryptionTrustLevel = roomSummaryEntity.roomEncryptionTrustLevel,
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/model/HomeServerCapabilitiesEntity.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/model/HomeServerCapabilitiesEntity.kt
index 0d067286e1..5743597a61 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/model/HomeServerCapabilitiesEntity.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/model/HomeServerCapabilitiesEntity.kt
@@ -20,6 +20,7 @@ import im.vector.matrix.android.api.session.homeserver.HomeServerCapabilities
 import io.realm.RealmObject
 
 internal open class HomeServerCapabilitiesEntity(
+        var canChangePassword: Boolean = true,
         var maxUploadFileSize: Long = HomeServerCapabilities.MAX_UPLOAD_FILE_SIZE_UNKNOWN,
         var lastUpdatedTimestamp: Long = 0L
 ) : RealmObject() {
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/model/RoomSummaryEntity.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/model/RoomSummaryEntity.kt
index 7009e762fb..5236cd26e6 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/model/RoomSummaryEntity.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/model/RoomSummaryEntity.kt
@@ -48,6 +48,7 @@ internal open class RoomSummaryEntity(
         // this is required for querying
         var flatAliases: String = "",
         var isEncrypted: Boolean = false,
+        var encryptionEventTs: Long? = 0,
         var typingUserIds: RealmList<String> = RealmList(),
         var roomEncryptionTrustLevelStr: String? = null,
         var inviterId: String? = null
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/FileQualifiers.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/FileQualifiers.kt
index acd6703c77..aa39fc6fe8 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/FileQualifiers.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/FileQualifiers.kt
@@ -29,3 +29,7 @@ annotation class SessionCacheDirectory
 @Qualifier
 @Retention(AnnotationRetention.RUNTIME)
 annotation class CacheDirectory
+
+@Qualifier
+@Retention(AnnotationRetention.RUNTIME)
+annotation class ExternalFilesDirectory
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/MatrixComponent.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/MatrixComponent.kt
index e929016d4f..4d6082d50b 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/MatrixComponent.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/MatrixComponent.kt
@@ -56,6 +56,9 @@ internal interface MatrixComponent {
     @CacheDirectory
     fun cacheDir(): File
 
+    @ExternalFilesDirectory
+    fun externalFilesDir(): File?
+
     fun olmManager(): OlmManager
 
     fun taskExecutor(): TaskExecutor
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/MatrixModule.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/MatrixModule.kt
index 0af22dd65a..785aecdf8e 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/MatrixModule.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/MatrixModule.kt
@@ -57,6 +57,13 @@ internal object MatrixModule {
         return context.cacheDir
     }
 
+    @JvmStatic
+    @Provides
+    @ExternalFilesDirectory
+    fun providesExternalFilesDir(context: Context): File? {
+        return context.getExternalFilesDir(null)
+    }
+
     @JvmStatic
     @Provides
     @MatrixScope
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/NetworkModule.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/NetworkModule.kt
index 4d6c66b7ed..b7ab257363 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/NetworkModule.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/NetworkModule.kt
@@ -57,7 +57,7 @@ internal object NetworkModule {
     @Provides
     @JvmStatic
     fun providesCurlLoggingInterceptor(): CurlLoggingInterceptor {
-        return CurlLoggingInterceptor(HttpLoggingInterceptor.Logger.DEFAULT)
+        return CurlLoggingInterceptor()
     }
 
     @MatrixScope
@@ -72,8 +72,8 @@ internal object NetworkModule {
                              okReplayInterceptor: OkReplayInterceptor): OkHttpClient {
         return OkHttpClient.Builder()
                 .connectTimeout(30, TimeUnit.SECONDS)
-                .readTimeout(30, TimeUnit.SECONDS)
-                .writeTimeout(30, TimeUnit.SECONDS)
+                .readTimeout(60, TimeUnit.SECONDS)
+                .writeTimeout(60, TimeUnit.SECONDS)
                 .addNetworkInterceptor(stethoInterceptor)
                 .addInterceptor(timeoutInterceptor)
                 .addInterceptor(userAgentInterceptor)
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/eventbus/EventBusTimberLogger.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/eventbus/EventBusTimberLogger.kt
new file mode 100644
index 0000000000..79d828dcab
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/eventbus/EventBusTimberLogger.kt
@@ -0,0 +1,31 @@
+/*
+ * 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.matrix.android.internal.eventbus
+
+import org.greenrobot.eventbus.Logger
+import timber.log.Timber
+import java.util.logging.Level
+
+class EventBusTimberLogger : Logger {
+    override fun log(level: Level, msg: String) {
+        Timber.d(msg)
+    }
+
+    override fun log(level: Level, msg: String, th: Throwable) {
+        Timber.e(th, msg)
+    }
+}
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/NetworkInfoReceiver.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/NetworkInfoReceiver.kt
index e8daf9b79b..645329628b 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/NetworkInfoReceiver.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/NetworkInfoReceiver.kt
@@ -14,6 +14,9 @@
  * limitations under the License.
  */
 
+// This BroadcastReceiver is used only if the build code is below 24.
+@file:Suppress("DEPRECATION")
+
 package im.vector.matrix.android.internal.network
 
 import android.content.BroadcastReceiver
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/Request.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/Request.kt
index 9714f42bb0..ea036f775b 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/Request.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/Request.kt
@@ -17,6 +17,7 @@
 package im.vector.matrix.android.internal.network
 
 import im.vector.matrix.android.api.failure.Failure
+import im.vector.matrix.android.api.failure.shouldBeRetried
 import kotlinx.coroutines.CancellationException
 import kotlinx.coroutines.delay
 import org.greenrobot.eventbus.EventBus
@@ -46,7 +47,7 @@ internal class Request<DATA>(private val eventBus: EventBus?) {
                 throw response.toFailure(eventBus)
             }
         } catch (exception: Throwable) {
-            if (isRetryable && currentRetryCount++ < maxRetryCount && exception is IOException) {
+            if (isRetryable && currentRetryCount++ < maxRetryCount && exception.shouldBeRetried()) {
                 delay(currentDelay)
                 currentDelay = (currentDelay * 2L).coerceAtMost(maxDelay)
                 return execute()
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/UserAgentHolder.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/UserAgentHolder.kt
index 0f3da0c834..15c91a629a 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/UserAgentHolder.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/UserAgentHolder.kt
@@ -51,7 +51,7 @@ internal class UserAgentHolder @Inject constructor(private val context: Context,
             appName = pm.getApplicationLabel(appInfo).toString()
 
             val pkgInfo = pm.getPackageInfo(context.applicationContext.packageName, 0)
-            appVersion = pkgInfo.versionName
+            appVersion = pkgInfo.versionName ?: ""
 
             // Use appPackageName instead of appName if appName contains any non-ASCII character
             if (!appName.matches("\\A\\p{ASCII}*\\z".toRegex())) {
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/DefaultFileService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/DefaultFileService.kt
index 9eaea8cc34..cfb0d23f2b 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/DefaultFileService.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/DefaultFileService.kt
@@ -16,7 +16,6 @@
 
 package im.vector.matrix.android.internal.session
 
-import android.os.Environment
 import arrow.core.Try
 import im.vector.matrix.android.api.MatrixCallback
 import im.vector.matrix.android.api.session.content.ContentUrlResolver
@@ -25,6 +24,7 @@ import im.vector.matrix.android.api.util.Cancelable
 import im.vector.matrix.android.internal.crypto.attachments.ElementToDecrypt
 import im.vector.matrix.android.internal.crypto.attachments.MXEncryptedAttachments
 import im.vector.matrix.android.internal.di.CacheDirectory
+import im.vector.matrix.android.internal.di.ExternalFilesDirectory
 import im.vector.matrix.android.internal.di.SessionCacheDirectory
 import im.vector.matrix.android.internal.di.Unauthenticated
 import im.vector.matrix.android.internal.extensions.foldToCallback
@@ -44,6 +44,8 @@ import javax.inject.Inject
 internal class DefaultFileService @Inject constructor(
         @CacheDirectory
         private val cacheDirectory: File,
+        @ExternalFilesDirectory
+        private val externalFilesDirectory: File?,
         @SessionCacheDirectory
         private val sessionCacheDirectory: File,
         private val contentUrlResolver: ContentUrlResolver,
@@ -77,9 +79,15 @@ internal class DefaultFileService @Inject constructor(
                                 .url(resolvedUrl)
                                 .build()
 
-                        val response = okHttpClient.newCall(request).execute()
+                        val response = try {
+                            okHttpClient.newCall(request).execute()
+                        } catch (e: Throwable) {
+                            return@flatMap Try.Failure(e)
+                        }
+
                         var inputStream = response.body?.byteStream()
                         Timber.v("Response size ${response.body?.contentLength()} - Stream available: ${inputStream?.available()}")
+
                         if (!response.isSuccessful || inputStream == null) {
                             return@flatMap Try.Failure(IOException())
                         }
@@ -103,7 +111,7 @@ internal class DefaultFileService @Inject constructor(
     private fun copyFile(file: File, downloadMode: FileService.DownloadMode): File {
         return when (downloadMode) {
             FileService.DownloadMode.TO_EXPORT          ->
-                file.copyTo(File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), file.name), true)
+                file.copyTo(File(externalFilesDirectory, file.name), true)
             FileService.DownloadMode.FOR_EXTERNAL_SHARE ->
                 file.copyTo(File(File(cacheDirectory, "ext_share"), file.name), true)
             FileService.DownloadMode.FOR_INTERNAL_USE   ->
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/DefaultSession.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/DefaultSession.kt
index 25dc939196..b30c29a719 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/DefaultSession.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/DefaultSession.kt
@@ -25,6 +25,7 @@ import im.vector.matrix.android.api.failure.GlobalError
 import im.vector.matrix.android.api.pushrules.PushRuleService
 import im.vector.matrix.android.api.session.InitialSyncProgressService
 import im.vector.matrix.android.api.session.Session
+import im.vector.matrix.android.api.session.account.AccountService
 import im.vector.matrix.android.api.session.accountdata.AccountDataService
 import im.vector.matrix.android.api.session.cache.CacheService
 import im.vector.matrix.android.api.session.content.ContentUploadStateTracker
@@ -94,6 +95,7 @@ internal class DefaultSession @Inject constructor(
         private val homeServerCapabilitiesService: Lazy<HomeServerCapabilitiesService>,
         private val accountDataService: Lazy<AccountDataService>,
         private val _sharedSecretStorageService: Lazy<SharedSecretStorageService>,
+        private val accountService: Lazy<AccountService>,
         private val timelineEventDecryptor: TimelineEventDecryptor,
         private val shieldTrustUpdater: ShieldTrustUpdater)
     : Session,
@@ -110,7 +112,8 @@ internal class DefaultSession @Inject constructor(
         SecureStorageService by secureStorageService.get(),
         HomeServerCapabilitiesService by homeServerCapabilitiesService.get(),
         ProfileService by profileService.get(),
-        AccountDataService by accountDataService.get() {
+        AccountDataService by accountDataService.get(),
+        AccountService by accountService.get() {
 
     override val sharedSecretStorageService: SharedSecretStorageService
         get() = _sharedSecretStorageService.get()
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/SessionComponent.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/SessionComponent.kt
index 22ebb4273a..0ebfc1c4c5 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/SessionComponent.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/SessionComponent.kt
@@ -28,6 +28,7 @@ import im.vector.matrix.android.internal.crypto.verification.SendVerificationMes
 import im.vector.matrix.android.internal.di.MatrixComponent
 import im.vector.matrix.android.internal.di.SessionAssistedInjectModule
 import im.vector.matrix.android.internal.network.NetworkConnectivityChecker
+import im.vector.matrix.android.internal.session.account.AccountModule
 import im.vector.matrix.android.internal.session.cache.CacheModule
 import im.vector.matrix.android.internal.session.content.ContentModule
 import im.vector.matrix.android.internal.session.content.UploadContentWorker
@@ -35,6 +36,7 @@ import im.vector.matrix.android.internal.session.filter.FilterModule
 import im.vector.matrix.android.internal.session.group.GetGroupDataWorker
 import im.vector.matrix.android.internal.session.group.GroupModule
 import im.vector.matrix.android.internal.session.homeserver.HomeServerCapabilitiesModule
+import im.vector.matrix.android.internal.session.openid.OpenIdModule
 import im.vector.matrix.android.internal.session.profile.ProfileModule
 import im.vector.matrix.android.internal.session.pushers.AddHttpPusherWorker
 import im.vector.matrix.android.internal.session.pushers.PushersModule
@@ -55,24 +57,26 @@ import im.vector.matrix.android.internal.task.TaskExecutor
 import im.vector.matrix.android.internal.util.MatrixCoroutineDispatchers
 
 @Component(dependencies = [MatrixComponent::class],
-           modules = [
-               SessionModule::class,
-               RoomModule::class,
-               SyncModule::class,
-               HomeServerCapabilitiesModule::class,
-               SignOutModule::class,
-               GroupModule::class,
-               UserModule::class,
-               FilterModule::class,
-               GroupModule::class,
-               ContentModule::class,
-               CacheModule::class,
-               CryptoModule::class,
-               PushersModule::class,
-               AccountDataModule::class,
-               ProfileModule::class,
-               SessionAssistedInjectModule::class
-           ]
+        modules = [
+            SessionModule::class,
+            RoomModule::class,
+            SyncModule::class,
+            HomeServerCapabilitiesModule::class,
+            SignOutModule::class,
+            GroupModule::class,
+            UserModule::class,
+            FilterModule::class,
+            GroupModule::class,
+            ContentModule::class,
+            CacheModule::class,
+            CryptoModule::class,
+            PushersModule::class,
+            OpenIdModule::class,
+            AccountDataModule::class,
+            ProfileModule::class,
+            SessionAssistedInjectModule::class,
+            AccountModule::class
+        ]
 )
 @SessionScope
 internal interface SessionComponent {
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/SessionModule.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/SessionModule.kt
index 908c610914..8bdfff062f 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/SessionModule.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/SessionModule.kt
@@ -49,6 +49,7 @@ import im.vector.matrix.android.internal.di.SessionId
 import im.vector.matrix.android.internal.di.Unauthenticated
 import im.vector.matrix.android.internal.di.UserId
 import im.vector.matrix.android.internal.di.UserMd5
+import im.vector.matrix.android.internal.eventbus.EventBusTimberLogger
 import im.vector.matrix.android.internal.network.AccessTokenInterceptor
 import im.vector.matrix.android.internal.network.DefaultNetworkConnectivityChecker
 import im.vector.matrix.android.internal.network.FallbackNetworkCallbackStrategy
@@ -205,7 +206,10 @@ internal abstract class SessionModule {
         @Provides
         @SessionScope
         fun providesEventBus(): EventBus {
-            return EventBus.builder().build()
+            return EventBus
+                    .builder()
+                    .logger(EventBusTimberLogger())
+                    .build()
         }
 
         @JvmStatic
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/account/AccountAPI.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/account/AccountAPI.kt
new file mode 100644
index 0000000000..62aded3f03
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/account/AccountAPI.kt
@@ -0,0 +1,40 @@
+/*
+ * 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.matrix.android.internal.session.account
+
+import im.vector.matrix.android.internal.network.NetworkConstants
+import retrofit2.Call
+import retrofit2.http.Body
+import retrofit2.http.POST
+
+internal interface AccountAPI {
+
+    /**
+     * Ask the homeserver to change the password with the provided new password.
+     * @param params parameters to change password.
+     */
+    @POST(NetworkConstants.URI_API_PREFIX_PATH_R0 + "account/password")
+    fun changePassword(@Body params: ChangePasswordParams): Call<Unit>
+
+    /**
+     * Deactivate the user account
+     *
+     * @param params the deactivate account params
+     */
+    @POST(NetworkConstants.URI_API_PREFIX_PATH_R0 + "account/deactivate")
+    fun deactivate(@Body params: DeactivateAccountParams): Call<Unit>
+}
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/account/AccountModule.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/account/AccountModule.kt
new file mode 100644
index 0000000000..032139ce5d
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/account/AccountModule.kt
@@ -0,0 +1,47 @@
+/*
+ * 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.matrix.android.internal.session.account
+
+import dagger.Binds
+import dagger.Module
+import dagger.Provides
+import im.vector.matrix.android.api.session.account.AccountService
+import im.vector.matrix.android.internal.session.SessionScope
+import retrofit2.Retrofit
+
+@Module
+internal abstract class AccountModule {
+
+    @Module
+    companion object {
+        @Provides
+        @JvmStatic
+        @SessionScope
+        fun providesAccountAPI(retrofit: Retrofit): AccountAPI {
+            return retrofit.create(AccountAPI::class.java)
+        }
+    }
+
+    @Binds
+    abstract fun bindChangePasswordTask(task: DefaultChangePasswordTask): ChangePasswordTask
+
+    @Binds
+    abstract fun bindDeactivateAccountTask(task: DefaultDeactivateAccountTask): DeactivateAccountTask
+
+    @Binds
+    abstract fun bindAccountService(service: DefaultAccountService): AccountService
+}
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/account/ChangePasswordParams.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/account/ChangePasswordParams.kt
new file mode 100644
index 0000000000..8aa1f9834c
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/account/ChangePasswordParams.kt
@@ -0,0 +1,42 @@
+/*
+ * 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.matrix.android.internal.session.account
+
+import com.squareup.moshi.Json
+import com.squareup.moshi.JsonClass
+import im.vector.matrix.android.internal.crypto.model.rest.UserPasswordAuth
+
+/**
+ * Class to pass request parameters to update the password.
+ */
+@JsonClass(generateAdapter = true)
+internal data class ChangePasswordParams(
+        @Json(name = "auth")
+        val auth: UserPasswordAuth? = null,
+
+        @Json(name = "new_password")
+        val newPassword: String? = null
+) {
+    companion object {
+        fun create(userId: String, oldPassword: String, newPassword: String): ChangePasswordParams {
+            return ChangePasswordParams(
+                    auth = UserPasswordAuth(user = userId, password = oldPassword),
+                    newPassword = newPassword
+            )
+        }
+    }
+}
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/account/ChangePasswordTask.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/account/ChangePasswordTask.kt
new file mode 100644
index 0000000000..60cf92e5d1
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/account/ChangePasswordTask.kt
@@ -0,0 +1,62 @@
+/*
+ * 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.matrix.android.internal.session.account
+
+import im.vector.matrix.android.api.failure.toRegistrationFlowResponse
+import im.vector.matrix.android.internal.di.UserId
+import im.vector.matrix.android.internal.network.executeRequest
+import im.vector.matrix.android.internal.task.Task
+import org.greenrobot.eventbus.EventBus
+import javax.inject.Inject
+
+internal interface ChangePasswordTask : Task<ChangePasswordTask.Params, Unit> {
+    data class Params(
+            val password: String,
+            val newPassword: String
+    )
+}
+
+internal class DefaultChangePasswordTask @Inject constructor(
+        private val accountAPI: AccountAPI,
+        private val eventBus: EventBus,
+        @UserId private val userId: String
+) : ChangePasswordTask {
+
+    override suspend fun execute(params: ChangePasswordTask.Params) {
+        val changePasswordParams = ChangePasswordParams.create(userId, params.password, params.newPassword)
+        try {
+            executeRequest<Unit>(eventBus) {
+                apiCall = accountAPI.changePassword(changePasswordParams)
+            }
+        } catch (throwable: Throwable) {
+            val registrationFlowResponse = throwable.toRegistrationFlowResponse()
+
+            if (registrationFlowResponse != null
+                    /* Avoid infinite loop */
+                    && changePasswordParams.auth?.session == null) {
+                // Retry with authentication
+                executeRequest<Unit>(eventBus) {
+                    apiCall = accountAPI.changePassword(
+                            changePasswordParams.copy(auth = changePasswordParams.auth?.copy(session = registrationFlowResponse.session))
+                    )
+                }
+            } else {
+                throw throwable
+            }
+        }
+    }
+}
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/account/DeactivateAccountParams.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/account/DeactivateAccountParams.kt
new file mode 100644
index 0000000000..9960f61dbc
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/account/DeactivateAccountParams.kt
@@ -0,0 +1,40 @@
+/*
+ * 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.matrix.android.internal.session.account
+
+import com.squareup.moshi.Json
+import com.squareup.moshi.JsonClass
+import im.vector.matrix.android.internal.crypto.model.rest.UserPasswordAuth
+
+@JsonClass(generateAdapter = true)
+internal data class DeactivateAccountParams(
+        @Json(name = "auth")
+        val auth: UserPasswordAuth? = null,
+
+        // Set to true to erase all data of the account
+        @Json(name = "erase")
+        val erase: Boolean
+) {
+    companion object {
+        fun create(userId: String, password: String, erase: Boolean): DeactivateAccountParams {
+            return DeactivateAccountParams(
+                    auth = UserPasswordAuth(user = userId, password = password),
+                    erase = erase
+            )
+        }
+    }
+}
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/account/DeactivateAccountTask.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/account/DeactivateAccountTask.kt
new file mode 100644
index 0000000000..f5b105cfee
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/account/DeactivateAccountTask.kt
@@ -0,0 +1,49 @@
+/*
+ * 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.matrix.android.internal.session.account
+
+import im.vector.matrix.android.internal.di.UserId
+import im.vector.matrix.android.internal.network.executeRequest
+import im.vector.matrix.android.internal.session.cleanup.CleanupSession
+import im.vector.matrix.android.internal.task.Task
+import org.greenrobot.eventbus.EventBus
+import javax.inject.Inject
+
+internal interface DeactivateAccountTask : Task<DeactivateAccountTask.Params, Unit> {
+    data class Params(
+            val password: String,
+            val eraseAllData: Boolean
+    )
+}
+
+internal class DefaultDeactivateAccountTask @Inject constructor(
+        private val accountAPI: AccountAPI,
+        private val eventBus: EventBus,
+        @UserId private val userId: String,
+        private val cleanupSession: CleanupSession
+) : DeactivateAccountTask {
+
+    override suspend fun execute(params: DeactivateAccountTask.Params) {
+        val deactivateAccountParams = DeactivateAccountParams.create(userId, params.password, params.eraseAllData)
+
+        executeRequest<Unit>(eventBus) {
+            apiCall = accountAPI.deactivate(deactivateAccountParams)
+        }
+
+        cleanupSession.handle()
+    }
+}
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/account/DefaultAccountService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/account/DefaultAccountService.kt
new file mode 100644
index 0000000000..f6db1dd3db
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/account/DefaultAccountService.kt
@@ -0,0 +1,45 @@
+/*
+ * 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.matrix.android.internal.session.account
+
+import im.vector.matrix.android.api.MatrixCallback
+import im.vector.matrix.android.api.session.account.AccountService
+import im.vector.matrix.android.api.util.Cancelable
+import im.vector.matrix.android.internal.task.TaskExecutor
+import im.vector.matrix.android.internal.task.configureWith
+import javax.inject.Inject
+
+internal class DefaultAccountService @Inject constructor(private val changePasswordTask: ChangePasswordTask,
+                                                         private val deactivateAccountTask: DeactivateAccountTask,
+                                                         private val taskExecutor: TaskExecutor) : AccountService {
+
+    override fun changePassword(password: String, newPassword: String, callback: MatrixCallback<Unit>): Cancelable {
+        return changePasswordTask
+                .configureWith(ChangePasswordTask.Params(password, newPassword)) {
+                    this.callback = callback
+                }
+                .executeBy(taskExecutor)
+    }
+
+    override fun deactivateAccount(password: String, eraseAllData: Boolean, callback: MatrixCallback<Unit>): Cancelable {
+        return deactivateAccountTask
+                .configureWith(DeactivateAccountTask.Params(password, eraseAllData)) {
+                    this.callback = callback
+                }
+                .executeBy(taskExecutor)
+    }
+}
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/cleanup/CleanupSession.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/cleanup/CleanupSession.kt
new file mode 100644
index 0000000000..ebd0fad39c
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/cleanup/CleanupSession.kt
@@ -0,0 +1,87 @@
+/*
+ * 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.matrix.android.internal.session.cleanup
+
+import im.vector.matrix.android.BuildConfig
+import im.vector.matrix.android.internal.SessionManager
+import im.vector.matrix.android.internal.auth.SessionParamsStore
+import im.vector.matrix.android.internal.crypto.CryptoModule
+import im.vector.matrix.android.internal.database.RealmKeysUtils
+import im.vector.matrix.android.internal.di.CryptoDatabase
+import im.vector.matrix.android.internal.di.SessionCacheDirectory
+import im.vector.matrix.android.internal.di.SessionDatabase
+import im.vector.matrix.android.internal.di.SessionFilesDirectory
+import im.vector.matrix.android.internal.di.SessionId
+import im.vector.matrix.android.internal.di.UserMd5
+import im.vector.matrix.android.internal.di.WorkManagerProvider
+import im.vector.matrix.android.internal.session.SessionModule
+import im.vector.matrix.android.internal.session.cache.ClearCacheTask
+import io.realm.Realm
+import io.realm.RealmConfiguration
+import timber.log.Timber
+import java.io.File
+import javax.inject.Inject
+
+internal class CleanupSession @Inject constructor(
+        private val workManagerProvider: WorkManagerProvider,
+        @SessionId private val sessionId: String,
+        private val sessionManager: SessionManager,
+        private val sessionParamsStore: SessionParamsStore,
+        @SessionDatabase private val clearSessionDataTask: ClearCacheTask,
+        @CryptoDatabase private val clearCryptoDataTask: ClearCacheTask,
+        @SessionFilesDirectory private val sessionFiles: File,
+        @SessionCacheDirectory private val sessionCache: File,
+        private val realmKeysUtils: RealmKeysUtils,
+        @SessionDatabase private val realmSessionConfiguration: RealmConfiguration,
+        @CryptoDatabase private val realmCryptoConfiguration: RealmConfiguration,
+        @UserMd5 private val userMd5: String
+) {
+    suspend fun handle() {
+        Timber.d("Cleanup: release session...")
+        sessionManager.releaseSession(sessionId)
+
+        Timber.d("Cleanup: cancel pending works...")
+        workManagerProvider.cancelAllWorks()
+
+        Timber.d("Cleanup: delete session params...")
+        sessionParamsStore.delete(sessionId)
+
+        Timber.d("Cleanup: clear session data...")
+        clearSessionDataTask.execute(Unit)
+
+        Timber.d("Cleanup: clear crypto data...")
+        clearCryptoDataTask.execute(Unit)
+
+        Timber.d("Cleanup: clear file system")
+        sessionFiles.deleteRecursively()
+        sessionCache.deleteRecursively()
+
+        Timber.d("Cleanup: clear the database keys")
+        realmKeysUtils.clear(SessionModule.getKeyAlias(userMd5))
+        realmKeysUtils.clear(CryptoModule.getKeyAlias(userMd5))
+
+        // Sanity check
+        if (BuildConfig.DEBUG) {
+            Realm.getGlobalInstanceCount(realmSessionConfiguration)
+                    .takeIf { it > 0 }
+                    ?.let { Timber.e("All realm instance for session has not been closed ($it)") }
+            Realm.getGlobalInstanceCount(realmCryptoConfiguration)
+                    .takeIf { it > 0 }
+                    ?.let { Timber.e("All realm instance for crypto has not been closed ($it)") }
+        }
+    }
+}
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/content/DefaultContentUrlResolver.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/content/DefaultContentUrlResolver.kt
index f288f949cd..df12ad6131 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/content/DefaultContentUrlResolver.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/content/DefaultContentUrlResolver.kt
@@ -18,46 +18,46 @@ package im.vector.matrix.android.internal.session.content
 
 import im.vector.matrix.android.api.auth.data.HomeServerConnectionConfig
 import im.vector.matrix.android.api.session.content.ContentUrlResolver
+import im.vector.matrix.android.internal.network.NetworkConstants
 import javax.inject.Inject
 
 private const val MATRIX_CONTENT_URI_SCHEME = "mxc://"
-private const val URI_PREFIX_CONTENT_API = "_matrix/media/v1/"
 
-internal class DefaultContentUrlResolver @Inject constructor(private val homeServerConnectionConfig: HomeServerConnectionConfig) : ContentUrlResolver {
+internal class DefaultContentUrlResolver @Inject constructor(homeServerConnectionConfig: HomeServerConnectionConfig) : ContentUrlResolver {
 
-    companion object {
-        fun getUploadUrl(homeServerConnectionConfig: HomeServerConnectionConfig): String {
-            val baseUrl = homeServerConnectionConfig.homeServerUri.toString()
-            val sep = if (baseUrl.endsWith("/")) "" else "/"
+    private val baseUrl = homeServerConnectionConfig.homeServerUri.toString()
+    private val sep = if (baseUrl.endsWith("/")) "" else "/"
 
-            return baseUrl + sep + URI_PREFIX_CONTENT_API + "upload"
-        }
-    }
+    override val uploadUrl = baseUrl + sep + NetworkConstants.URI_API_MEDIA_PREFIX_PATH_R0 + "upload"
 
     override fun resolveFullSize(contentUrl: String?): String? {
-        if (contentUrl?.isValidMatrixContentUrl() == true) {
-            val baseUrl = homeServerConnectionConfig.homeServerUri.toString()
-            val prefix = URI_PREFIX_CONTENT_API + "download/"
-            return resolve(baseUrl, contentUrl, prefix)
-        }
-        return null
+        return contentUrl
+                // do not allow non-mxc content URLs
+                ?.takeIf { it.isValidMatrixContentUrl() }
+                ?.let {
+                    resolve(
+                            contentUrl = it,
+                            prefix = NetworkConstants.URI_API_MEDIA_PREFIX_PATH_R0 + "download/"
+                    )
+                }
     }
 
     override fun resolveThumbnail(contentUrl: String?, width: Int, height: Int, method: ContentUrlResolver.ThumbnailMethod): String? {
-        if (contentUrl?.isValidMatrixContentUrl() == true) {
-            val baseUrl = homeServerConnectionConfig.homeServerUri.toString()
-            val prefix = URI_PREFIX_CONTENT_API + "thumbnail/"
-            val params = "?width=$width&height=$height&method=${method.value}"
-            return resolve(baseUrl, contentUrl, prefix, params)
-        }
-        // do not allow non-mxc content URLs
-        return null
+        return contentUrl
+                // do not allow non-mxc content URLs
+                ?.takeIf { it.isValidMatrixContentUrl() }
+                ?.let {
+                    resolve(
+                            contentUrl = it,
+                            prefix = NetworkConstants.URI_API_MEDIA_PREFIX_PATH_R0 + "thumbnail/",
+                            params = "?width=$width&height=$height&method=${method.value}"
+                    )
+                }
     }
 
-    private fun resolve(baseUrl: String,
-                        contentUrl: String,
+    private fun resolve(contentUrl: String,
                         prefix: String,
-                        params: String? = null): String? {
+                        params: String = ""): String? {
         var serverAndMediaId = contentUrl.removePrefix(MATRIX_CONTENT_URI_SCHEME)
         val fragmentOffset = serverAndMediaId.indexOf("#")
         var fragment = ""
@@ -66,9 +66,7 @@ internal class DefaultContentUrlResolver @Inject constructor(private val homeSer
             serverAndMediaId = serverAndMediaId.substring(0, fragmentOffset)
         }
 
-        val sep = if (baseUrl.endsWith("/")) "" else "/"
-
-        return baseUrl + sep + prefix + serverAndMediaId + (params ?: "") + fragment
+        return baseUrl + sep + prefix + serverAndMediaId + params + fragment
     }
 
     private fun String.isValidMatrixContentUrl(): Boolean {
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/content/FileUploader.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/content/FileUploader.kt
index 4fa0cb5013..1153b39b0a 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/content/FileUploader.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/content/FileUploader.kt
@@ -17,7 +17,7 @@
 package im.vector.matrix.android.internal.session.content
 
 import com.squareup.moshi.Moshi
-import im.vector.matrix.android.api.auth.data.SessionParams
+import im.vector.matrix.android.api.session.content.ContentUrlResolver
 import im.vector.matrix.android.internal.di.Authenticated
 import im.vector.matrix.android.internal.network.ProgressRequestBody
 import im.vector.matrix.android.internal.network.awaitResponse
@@ -37,10 +37,10 @@ import javax.inject.Inject
 internal class FileUploader @Inject constructor(@Authenticated
                                                 private val okHttpClient: OkHttpClient,
                                                 private val eventBus: EventBus,
-                                                sessionParams: SessionParams,
+                                                contentUrlResolver: ContentUrlResolver,
                                                 moshi: Moshi) {
 
-    private val uploadUrl = DefaultContentUrlResolver.getUploadUrl(sessionParams.homeServerConnectionConfig)
+    private val uploadUrl = contentUrlResolver.uploadUrl
     private val responseAdapter = moshi.adapter(ContentUploadResponse::class.java)
 
     suspend fun uploadFile(file: File,
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/content/UploadContentWorker.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/content/UploadContentWorker.kt
index 1b736d349f..03ae366ed5 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/content/UploadContentWorker.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/content/UploadContentWorker.kt
@@ -46,6 +46,10 @@ private data class NewImageAttributes(
         val newFileSize: Int
 )
 
+/**
+ * Possible previous worker: None
+ * Possible next worker    : Always [MultipleEventSendingDispatcherWorker]
+ */
 internal class UploadContentWorker(val context: Context, params: WorkerParameters) : CoroutineWorker(context, params) {
 
     @JsonClass(generateAdapter = true)
@@ -64,12 +68,14 @@ internal class UploadContentWorker(val context: Context, params: WorkerParameter
     override suspend fun doWork(): Result {
         val params = WorkerParamsFactory.fromData<Params>(inputData)
                 ?: return Result.success()
+                        .also { Timber.e("Unable to parse work parameters") }
+
         Timber.v("Starting upload media work with params $params")
 
         if (params.lastFailureMessage != null) {
             // Transmit the error
-            Timber.v("Stop upload media work due to input failure")
             return Result.success(inputData)
+                    .also { Timber.e("Work cancelled due to input error from parent") }
         }
 
         // Just defensive code to ensure that we never have an uncaught exception that could break the queue
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/group/GetGroupDataWorker.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/group/GetGroupDataWorker.kt
index 93705774e6..bb33212f9c 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/group/GetGroupDataWorker.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/group/GetGroupDataWorker.kt
@@ -23,8 +23,13 @@ import com.squareup.moshi.JsonClass
 import im.vector.matrix.android.internal.worker.SessionWorkerParams
 import im.vector.matrix.android.internal.worker.WorkerParamsFactory
 import im.vector.matrix.android.internal.worker.getSessionComponent
+import timber.log.Timber
 import javax.inject.Inject
 
+/**
+ * Possible previous worker: None
+ * Possible next worker    : None
+ */
 internal class GetGroupDataWorker(context: Context, params: WorkerParameters) : CoroutineWorker(context, params) {
 
     @JsonClass(generateAdapter = true)
@@ -39,6 +44,7 @@ internal class GetGroupDataWorker(context: Context, params: WorkerParameters) :
     override suspend fun doWork(): Result {
         val params = WorkerParamsFactory.fromData<Params>(inputData)
                 ?: return Result.failure()
+                        .also { Timber.e("Unable to parse work parameters") }
 
         val sessionComponent = getSessionComponent(params.sessionId) ?: return Result.success()
         sessionComponent.inject(this)
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/group/GroupSummaryUpdater.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/group/GroupSummaryUpdater.kt
index 3ca5a03822..9808b584aa 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/group/GroupSummaryUpdater.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/group/GroupSummaryUpdater.kt
@@ -69,13 +69,13 @@ internal class GroupSummaryUpdater @Inject constructor(
 
         val workData = WorkerParamsFactory.toData(getGroupDataWorkerParams)
 
-        val sendWork = workManagerProvider.matrixOneTimeWorkRequestBuilder<GetGroupDataWorker>()
+        val getGroupWork = workManagerProvider.matrixOneTimeWorkRequestBuilder<GetGroupDataWorker>()
                 .setInputData(workData)
                 .setConstraints(WorkManagerProvider.workConstraints)
                 .build()
 
         workManagerProvider.workManager
-                .beginUniqueWork(GET_GROUP_DATA_WORKER, ExistingWorkPolicy.APPEND, sendWork)
+                .beginUniqueWork(GET_GROUP_DATA_WORKER, ExistingWorkPolicy.APPEND, getGroupWork)
                 .enqueue()
     }
 
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/homeserver/CapabilitiesAPI.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/homeserver/CapabilitiesAPI.kt
index c83a61cfb0..f37bbfe798 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/homeserver/CapabilitiesAPI.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/homeserver/CapabilitiesAPI.kt
@@ -22,6 +22,12 @@ import retrofit2.http.GET
 
 internal interface CapabilitiesAPI {
 
+    /**
+     * Request the homeserver capabilities
+     */
+    @GET(NetworkConstants.URI_API_PREFIX_PATH_R0 + "capabilities")
+    fun getCapabilities(): Call<GetCapabilitiesResult>
+
     /**
      * Request the upload capabilities
      */
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/homeserver/DefaultGetHomeServerCapabilitiesTask.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/homeserver/DefaultGetHomeServerCapabilitiesTask.kt
index 2dbd627ce5..9f068381f0 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/homeserver/DefaultGetHomeServerCapabilitiesTask.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/homeserver/DefaultGetHomeServerCapabilitiesTask.kt
@@ -51,15 +51,23 @@ internal class DefaultGetHomeServerCapabilitiesTask @Inject constructor(
             apiCall = capabilitiesAPI.getUploadCapabilities()
         }
 
+        val capabilities = runCatching {
+            executeRequest<GetCapabilitiesResult>(eventBus) {
+                apiCall = capabilitiesAPI.getCapabilities()
+            }
+        }.getOrNull()
+
         // TODO Add other call here (get version, etc.)
 
-        insertInDb(uploadCapabilities)
+        insertInDb(capabilities, uploadCapabilities)
     }
 
-    private suspend fun insertInDb(getUploadCapabilitiesResult: GetUploadCapabilitiesResult) {
+    private suspend fun insertInDb(getCapabilitiesResult: GetCapabilitiesResult?, getUploadCapabilitiesResult: GetUploadCapabilitiesResult) {
         monarchy.awaitTransaction { realm ->
             val homeServerCapabilitiesEntity = HomeServerCapabilitiesEntity.getOrCreate(realm)
 
+            homeServerCapabilitiesEntity.canChangePassword = getCapabilitiesResult.canChangePassword()
+
             homeServerCapabilitiesEntity.maxUploadFileSize = getUploadCapabilitiesResult.maxUploadSize
                     ?: HomeServerCapabilities.MAX_UPLOAD_FILE_SIZE_UNKNOWN
 
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/homeserver/GetCapabilitiesResult.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/homeserver/GetCapabilitiesResult.kt
new file mode 100644
index 0000000000..ffaa998789
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/homeserver/GetCapabilitiesResult.kt
@@ -0,0 +1,58 @@
+/*
+ * 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.matrix.android.internal.session.homeserver
+
+import com.squareup.moshi.Json
+import com.squareup.moshi.JsonClass
+import im.vector.matrix.android.api.extensions.orTrue
+
+/**
+ * Ref: https://matrix.org/docs/spec/client_server/latest#get-matrix-client-r0-capabilities
+ */
+@JsonClass(generateAdapter = true)
+internal data class GetCapabilitiesResult(
+        /**
+         * Required. The custom capabilities the server supports, using the Java package naming convention.
+         */
+        @Json(name = "capabilities")
+        val capabilities: Capabilities? = null
+)
+
+@JsonClass(generateAdapter = true)
+internal data class Capabilities(
+        /**
+         * Capability to indicate if the user can change their password.
+         */
+        @Json(name = "m.change_password")
+        val changePassword: ChangePassword? = null
+
+        // No need for m.room_versions for the moment
+)
+
+@JsonClass(generateAdapter = true)
+internal data class ChangePassword(
+        /**
+         * Required. True if the user can change their password, false otherwise.
+         */
+        @Json(name = "enabled")
+        val enabled: Boolean?
+)
+
+// The spec says: If not present, the client should assume that password changes are possible via the API
+internal fun GetCapabilitiesResult?.canChangePassword(): Boolean {
+    return this?.capabilities?.changePassword?.enabled.orTrue()
+}
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/homeserver/GetUploadCapabilitiesResult.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/homeserver/GetUploadCapabilitiesResult.kt
index 8e410cc834..c98119db6c 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/homeserver/GetUploadCapabilitiesResult.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/homeserver/GetUploadCapabilitiesResult.kt
@@ -20,7 +20,7 @@ import com.squareup.moshi.Json
 import com.squareup.moshi.JsonClass
 
 @JsonClass(generateAdapter = true)
-data class GetUploadCapabilitiesResult(
+internal data class GetUploadCapabilitiesResult(
         /**
          * The maximum size an upload can be in bytes. Clients SHOULD use this as a guide when uploading content.
          * If not listed or null, the size limit should be treated as unknown.
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/openid/GetOpenIdTokenTask.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/openid/GetOpenIdTokenTask.kt
new file mode 100644
index 0000000000..c8f394dc47
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/openid/GetOpenIdTokenTask.kt
@@ -0,0 +1,37 @@
+/*
+ * 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.matrix.android.internal.session.openid
+
+import im.vector.matrix.android.internal.di.UserId
+import im.vector.matrix.android.internal.network.executeRequest
+import im.vector.matrix.android.internal.task.Task
+import org.greenrobot.eventbus.EventBus
+import javax.inject.Inject
+
+internal interface GetOpenIdTokenTask : Task<Unit, RequestOpenIdTokenResponse>
+
+internal class DefaultGetOpenIdTokenTask @Inject constructor(
+        @UserId private val userId: String,
+        private val openIdAPI: OpenIdAPI,
+        private val eventBus: EventBus) : GetOpenIdTokenTask {
+
+    override suspend fun execute(params: Unit): RequestOpenIdTokenResponse {
+        return executeRequest(eventBus) {
+            apiCall = openIdAPI.openIdToken(userId)
+        }
+    }
+}
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/openid/OpenIdAPI.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/openid/OpenIdAPI.kt
new file mode 100644
index 0000000000..ee2e85a33e
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/openid/OpenIdAPI.kt
@@ -0,0 +1,38 @@
+/*
+ * 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.matrix.android.internal.session.openid
+
+import im.vector.matrix.android.api.util.JsonDict
+import im.vector.matrix.android.internal.network.NetworkConstants
+import retrofit2.Call
+import retrofit2.http.Body
+import retrofit2.http.POST
+import retrofit2.http.Path
+
+internal interface OpenIdAPI {
+
+    /**
+     * Gets a bearer token from the homeserver that the user can
+     * present to a third party in order to prove their ownership
+     * of the Matrix account they are logged into.
+     * Ref: https://matrix.org/docs/spec/client_server/latest#post-matrix-client-r0-user-userid-openid-request-token
+     *
+     * @param userId the user id
+     */
+    @POST(NetworkConstants.URI_API_PREFIX_PATH_R0 + "user/{userId}/openid/request_token")
+    fun openIdToken(@Path("userId") userId: String, @Body body: JsonDict = emptyMap()): Call<RequestOpenIdTokenResponse>
+}
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/openid/OpenIdModule.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/openid/OpenIdModule.kt
new file mode 100644
index 0000000000..c6993167e8
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/openid/OpenIdModule.kt
@@ -0,0 +1,38 @@
+/*
+ * 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.matrix.android.internal.session.openid
+
+import dagger.Binds
+import dagger.Module
+import dagger.Provides
+import retrofit2.Retrofit
+
+@Module
+internal abstract class OpenIdModule {
+
+    @Module
+    companion object {
+        @JvmStatic
+        @Provides
+        fun providesOpenIdAPI(retrofit: Retrofit): OpenIdAPI {
+            return retrofit.create(OpenIdAPI::class.java)
+        }
+    }
+
+    @Binds
+    abstract fun bindGetOpenIdTokenTask(task: DefaultGetOpenIdTokenTask): GetOpenIdTokenTask
+}
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/openid/RequestOpenIdTokenResponse.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/openid/RequestOpenIdTokenResponse.kt
new file mode 100644
index 0000000000..4beb3fe420
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/openid/RequestOpenIdTokenResponse.kt
@@ -0,0 +1,48 @@
+/*
+ * 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.matrix.android.internal.session.openid
+
+import com.squareup.moshi.Json
+import com.squareup.moshi.JsonClass
+
+@JsonClass(generateAdapter = true)
+internal data class RequestOpenIdTokenResponse(
+        /**
+         * Required. An access token the consumer may use to verify the identity of the person who generated the token.
+         * This is given to the federation API GET /openid/userinfo to verify the user's identity.
+         */
+        @Json(name = "access_token")
+        val openIdToken: String,
+
+        /**
+         * Required. The string "Bearer".
+         */
+        @Json(name = "token_type")
+        val tokenType: String,
+
+        /**
+         * Required. The homeserver domain the consumer should use when attempting to verify the user's identity.
+         */
+        @Json(name = "matrix_server_name")
+        val matrixServerName: String,
+
+        /**
+         * Required. The number of seconds before this token expires and a new one must be generated.
+         */
+        @Json(name = "expires_in")
+        val expiresIn: Int
+)
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/pushers/AddHttpPusherWorker.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/pushers/AddHttpPusherWorker.kt
index adb4bf32c2..77100ffc49 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/pushers/AddHttpPusherWorker.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/pushers/AddHttpPusherWorker.kt
@@ -31,6 +31,7 @@ import im.vector.matrix.android.internal.worker.SessionWorkerParams
 import im.vector.matrix.android.internal.worker.WorkerParamsFactory
 import im.vector.matrix.android.internal.worker.getSessionComponent
 import org.greenrobot.eventbus.EventBus
+import timber.log.Timber
 import javax.inject.Inject
 
 internal class AddHttpPusherWorker(context: Context, params: WorkerParameters)
@@ -50,6 +51,7 @@ internal class AddHttpPusherWorker(context: Context, params: WorkerParameters)
     override suspend fun doWork(): Result {
         val params = WorkerParamsFactory.fromData<Params>(inputData)
                 ?: return Result.failure()
+                        .also { Timber.e("Unable to parse work parameters") }
 
         val sessionComponent = getSessionComponent(params.sessionId) ?: return Result.success()
         sessionComponent.inject(this)
@@ -72,7 +74,6 @@ internal class AddHttpPusherWorker(context: Context, params: WorkerParameters)
                             it.state = PusherState.FAILED_TO_REGISTER
                         }
                     }
-                    // always return success, or the chain will be stuck for ever!
                     Result.failure()
                 }
             }
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomSummaryUpdater.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomSummaryUpdater.kt
index f4886c72da..6e0adccfb9 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomSummaryUpdater.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomSummaryUpdater.kt
@@ -136,6 +136,7 @@ internal class RoomSummaryUpdater @Inject constructor(
         roomSummaryEntity.aliases.addAll(roomAliases)
         roomSummaryEntity.flatAliases = roomAliases.joinToString(separator = "|", prefix = "|")
         roomSummaryEntity.isEncrypted = encryptionEvent != null
+        roomSummaryEntity.encryptionEventTs = encryptionEvent?.originServerTs
         roomSummaryEntity.typingUserIds.clear()
         roomSummaryEntity.typingUserIds.addAll(ephemeralResult?.typingUserIds.orEmpty())
 
@@ -152,7 +153,7 @@ internal class RoomSummaryUpdater @Inject constructor(
 
         if (updateMembers) {
             val otherRoomMembers = RoomMemberHelper(realm, roomId)
-                    .queryRoomMembersEvent()
+                    .queryActiveRoomMembersEvent()
                     .notEqualTo(RoomMemberSummaryEntityFields.USER_ID, userId)
                     .findAll()
                     .asSequence()
@@ -161,15 +162,7 @@ internal class RoomSummaryUpdater @Inject constructor(
             roomSummaryEntity.otherMemberIds.clear()
             roomSummaryEntity.otherMemberIds.addAll(otherRoomMembers)
             if (roomSummaryEntity.isEncrypted) {
-                // The set of “all users” depends on the type of room:
-                // For regular / topic rooms, all users including yourself, are considered when decorating a room
-                // For 1:1 and group DM rooms, all other users (i.e. excluding yourself) are considered when decorating a room
-                val listToCheck = if (roomSummaryEntity.isDirect) {
-                    roomSummaryEntity.otherMemberIds.toList()
-                } else {
-                    roomSummaryEntity.otherMemberIds.toList() + userId
-                }
-                eventBus.post(SessionToCryptoRoomMembersUpdate(roomId, listToCheck))
+                eventBus.post(SessionToCryptoRoomMembersUpdate(roomId, roomSummaryEntity.isDirect, roomSummaryEntity.otherMemberIds.toList() + userId))
             }
         }
     }
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/relation/SendRelationWorker.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/relation/SendRelationWorker.kt
index 5857eaa89b..9a8f1a7dc6 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/relation/SendRelationWorker.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/relation/SendRelationWorker.kt
@@ -31,6 +31,7 @@ import im.vector.matrix.android.internal.worker.SessionWorkerParams
 import im.vector.matrix.android.internal.worker.WorkerParamsFactory
 import im.vector.matrix.android.internal.worker.getSessionComponent
 import org.greenrobot.eventbus.EventBus
+import timber.log.Timber
 import javax.inject.Inject
 
 // TODO This is not used. Delete?
@@ -51,10 +52,12 @@ internal class SendRelationWorker(context: Context, params: WorkerParameters) :
     override suspend fun doWork(): Result {
         val params = WorkerParamsFactory.fromData<Params>(inputData)
                 ?: return Result.failure()
+                        .also { Timber.e("Unable to parse work parameters") }
 
         if (params.lastFailureMessage != null) {
             // Transmit the error
             return Result.success(inputData)
+                    .also { Timber.e("Work cancelled due to input error from parent") }
         }
 
         val sessionComponent = getSessionComponent(params.sessionId) ?: return Result.success()
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/DefaultSendService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/DefaultSendService.kt
index a99337695a..1037b7c79c 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/DefaultSendService.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/DefaultSendService.kt
@@ -228,7 +228,7 @@ internal class DefaultSendService @AssistedInject constructor(
                     keys.forEach { isRoomEncrypted ->
                         // Should never be empty
                         val localEchoes = get(isRoomEncrypted).orEmpty()
-                        val uploadWork = createUploadMediaWork(localEchoes, attachment, isRoomEncrypted, compressBeforeSending, startChain = true)
+                        val uploadWork = createUploadMediaWork(localEchoes, attachment, isRoomEncrypted, compressBeforeSending)
 
                         val dispatcherWork = createMultipleEventDispatcherWork(isRoomEncrypted)
 
@@ -293,14 +293,13 @@ internal class DefaultSendService @AssistedInject constructor(
     private fun createUploadMediaWork(allLocalEchos: List<Event>,
                                       attachment: ContentAttachmentData,
                                       isRoomEncrypted: Boolean,
-                                      compressBeforeSending: Boolean,
-                                      startChain: Boolean): OneTimeWorkRequest {
+                                      compressBeforeSending: Boolean): OneTimeWorkRequest {
         val uploadMediaWorkerParams = UploadContentWorker.Params(sessionId, allLocalEchos, attachment, isRoomEncrypted, compressBeforeSending)
         val uploadWorkData = WorkerParamsFactory.toData(uploadMediaWorkerParams)
 
         return workManagerProvider.matrixOneTimeWorkRequestBuilder<UploadContentWorker>()
                 .setConstraints(WorkManagerProvider.workConstraints)
-                .startChain(startChain)
+                .startChain(true)
                 .setInputData(uploadWorkData)
                 .setBackoffCriteria(BackoffPolicy.LINEAR, WorkManagerProvider.BACKOFF_DELAY, TimeUnit.MILLISECONDS)
                 .build()
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/EncryptEventWorker.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/EncryptEventWorker.kt
index e4424f1cb3..6af2f8dab6 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/EncryptEventWorker.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/EncryptEventWorker.kt
@@ -35,6 +35,10 @@ import im.vector.matrix.android.internal.worker.getSessionComponent
 import timber.log.Timber
 import javax.inject.Inject
 
+/**
+ * Possible previous worker: None
+ * Possible next worker    : Always [SendEventWorker]
+ */
 internal class EncryptEventWorker(context: Context, params: WorkerParameters)
     : CoroutineWorker(context, params) {
 
@@ -53,14 +57,14 @@ internal class EncryptEventWorker(context: Context, params: WorkerParameters)
     override suspend fun doWork(): Result {
         Timber.v("Start Encrypt work")
         val params = WorkerParamsFactory.fromData<Params>(inputData)
-                ?: return Result.success().also {
-                    Timber.e("Work cancelled due to input error from parent")
-                }
+                ?: return Result.success()
+                        .also { Timber.e("Unable to parse work parameters") }
 
         Timber.v("Start Encrypt work for event ${params.event.eventId}")
         if (params.lastFailureMessage != null) {
             // Transmit the error
             return Result.success(inputData)
+                    .also { Timber.e("Work cancelled due to input error from parent") }
         }
 
         val sessionComponent = getSessionComponent(params.sessionId) ?: return Result.success()
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/LocalEchoEventFactory.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/LocalEchoEventFactory.kt
index a4a6eb6972..5f0515e669 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/LocalEchoEventFactory.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/LocalEchoEventFactory.kt
@@ -314,7 +314,7 @@ internal class LocalEchoEventFactory @Inject constructor(
                 msgType = MessageType.MSGTYPE_AUDIO,
                 body = attachment.name ?: "audio",
                 audioInfo = AudioInfo(
-                        mimeType = attachment.getSafeMimeType()?.takeIf { it.isNotBlank() } ?: "audio/mpeg",
+                        mimeType = attachment.getSafeMimeType()?.takeIf { it.isNotBlank() },
                         size = attachment.size
                 ),
                 url = attachment.queryUri.toString()
@@ -327,8 +327,7 @@ internal class LocalEchoEventFactory @Inject constructor(
                 msgType = MessageType.MSGTYPE_FILE,
                 body = attachment.name ?: "file",
                 info = FileInfo(
-                        mimeType = attachment.getSafeMimeType()?.takeIf { it.isNotBlank() }
-                                ?: "application/octet-stream",
+                        mimeType = attachment.getSafeMimeType()?.takeIf { it.isNotBlank() },
                         size = attachment.size
                 ),
                 url = attachment.queryUri.toString()
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/MultipleEventSendingDispatcherWorker.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/MultipleEventSendingDispatcherWorker.kt
index 8c31dd1682..aec7cb3c5c 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/MultipleEventSendingDispatcherWorker.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/MultipleEventSendingDispatcherWorker.kt
@@ -25,6 +25,7 @@ import com.squareup.moshi.JsonClass
 import im.vector.matrix.android.api.session.events.model.Event
 import im.vector.matrix.android.api.session.room.send.SendState
 import im.vector.matrix.android.internal.di.WorkManagerProvider
+import im.vector.matrix.android.internal.session.content.UploadContentWorker
 import im.vector.matrix.android.internal.session.room.timeline.TimelineSendEventWorkCommon
 import im.vector.matrix.android.internal.worker.SessionWorkerParams
 import im.vector.matrix.android.internal.worker.WorkerParamsFactory
@@ -36,6 +37,9 @@ import javax.inject.Inject
 
 /**
  * This worker creates a new work for each events passed in parameter
+ *
+ * Possible previous worker: Always [UploadContentWorker]
+ * Possible next worker    : None, but it will post new work to send events, encrypted or not
  */
 internal class MultipleEventSendingDispatcherWorker(context: Context, params: WorkerParameters)
     : CoroutineWorker(context, params) {
@@ -55,9 +59,8 @@ internal class MultipleEventSendingDispatcherWorker(context: Context, params: Wo
     override suspend fun doWork(): Result {
         Timber.v("Start dispatch sending multiple event work")
         val params = WorkerParamsFactory.fromData<Params>(inputData)
-                ?: return Result.success().also {
-                    Timber.e("Work cancelled due to input error from parent")
-                }
+                ?: return Result.success()
+                        .also { Timber.e("Unable to parse work parameters") }
 
         val sessionComponent = getSessionComponent(params.sessionId) ?: return Result.success()
         sessionComponent.inject(this)
@@ -68,6 +71,7 @@ internal class MultipleEventSendingDispatcherWorker(context: Context, params: Wo
             }
             // Transmit the error if needed?
             return Result.success(inputData)
+                    .also { Timber.e("Work cancelled due to input error from parent") }
         }
 
         // Create a work for every event
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/RedactEventWorker.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/RedactEventWorker.kt
index 3ff318aa8a..7e0b665d63 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/RedactEventWorker.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/RedactEventWorker.kt
@@ -26,8 +26,13 @@ import im.vector.matrix.android.internal.worker.SessionWorkerParams
 import im.vector.matrix.android.internal.worker.WorkerParamsFactory
 import im.vector.matrix.android.internal.worker.getSessionComponent
 import org.greenrobot.eventbus.EventBus
+import timber.log.Timber
 import javax.inject.Inject
 
+/**
+ * Possible previous worker: None
+ * Possible next worker    : None
+ */
 internal class RedactEventWorker(context: Context, params: WorkerParameters) : CoroutineWorker(context, params) {
 
     @JsonClass(generateAdapter = true)
@@ -46,10 +51,12 @@ internal class RedactEventWorker(context: Context, params: WorkerParameters) : C
     override suspend fun doWork(): Result {
         val params = WorkerParamsFactory.fromData<Params>(inputData)
                 ?: return Result.failure()
+                        .also { Timber.e("Unable to parse work parameters") }
 
         if (params.lastFailureMessage != null) {
             // Transmit the error
             return Result.success(inputData)
+                    .also { Timber.e("Work cancelled due to input error from parent") }
         }
 
         val sessionComponent = getSessionComponent(params.sessionId) ?: return Result.success()
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/SendEventWorker.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/SendEventWorker.kt
index 69d288a932..d55b9665f6 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/SendEventWorker.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/SendEventWorker.kt
@@ -32,6 +32,10 @@ import org.greenrobot.eventbus.EventBus
 import timber.log.Timber
 import javax.inject.Inject
 
+/**
+ * Possible previous worker: [EncryptEventWorker] or first worker
+ * Possible next worker    : None
+ */
 internal class SendEventWorker(context: Context,
                                params: WorkerParameters)
     : CoroutineWorker(context, params) {
@@ -49,9 +53,8 @@ internal class SendEventWorker(context: Context,
 
     override suspend fun doWork(): Result {
         val params = WorkerParamsFactory.fromData<Params>(inputData)
-                ?: return Result.success().also {
-                    Timber.e("Work cancelled due to input error from parent")
-                }
+                ?: return Result.success()
+                        .also { Timber.e("Unable to parse work parameters") }
 
         val sessionComponent = getSessionComponent(params.sessionId) ?: return Result.success()
         sessionComponent.inject(this)
@@ -65,6 +68,7 @@ internal class SendEventWorker(context: Context,
             localEchoUpdater.updateSendState(event.eventId, SendState.UNDELIVERED)
             // Transmit the error
             return Result.success(inputData)
+                    .also { Timber.e("Work cancelled due to input error from parent") }
         }
         return try {
             sendEvent(event)
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/timeline/DefaultTimeline.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/timeline/DefaultTimeline.kt
index 53bd620e51..f2bee734ce 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/timeline/DefaultTimeline.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/timeline/DefaultTimeline.kt
@@ -171,10 +171,13 @@ internal class DefaultTimeline(
                 val realm = Realm.getInstance(realmConfiguration)
                 backgroundRealm.set(realm)
 
-                roomEntity = RoomEntity.where(realm, roomId = roomId).findFirst()?.also {
-                    it.sendingTimelineEvents.addChangeListener { _ ->
-                        postSnapshot()
+                roomEntity = RoomEntity.where(realm, roomId = roomId).findFirst()
+                roomEntity?.sendingTimelineEvents?.addChangeListener { events ->
+                    // Remove in memory as soon as they are known by database
+                    events.forEach { te ->
+                        inMemorySendingEvents.removeAll { te.eventId == it.eventId }
                     }
+                    postSnapshot()
                 }
 
                 nonFilteredEvents = buildEventQuery(realm).sort(TimelineEventEntityFields.DISPLAY_INDEX, Sort.DESCENDING).findAll()
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/signout/SignOutTask.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/signout/SignOutTask.kt
index b14a7758c5..610ade5744 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/signout/SignOutTask.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/signout/SignOutTask.kt
@@ -16,58 +16,31 @@
 
 package im.vector.matrix.android.internal.session.signout
 
-import im.vector.matrix.android.BuildConfig
 import im.vector.matrix.android.api.failure.Failure
 import im.vector.matrix.android.api.failure.MatrixError
-import im.vector.matrix.android.internal.SessionManager
-import im.vector.matrix.android.internal.auth.SessionParamsStore
-import im.vector.matrix.android.internal.crypto.CryptoModule
-import im.vector.matrix.android.internal.database.RealmKeysUtils
-import im.vector.matrix.android.internal.di.CryptoDatabase
-import im.vector.matrix.android.internal.di.SessionCacheDirectory
-import im.vector.matrix.android.internal.di.SessionDatabase
-import im.vector.matrix.android.internal.di.SessionFilesDirectory
-import im.vector.matrix.android.internal.di.SessionId
-import im.vector.matrix.android.internal.di.UserMd5
-import im.vector.matrix.android.internal.di.WorkManagerProvider
 import im.vector.matrix.android.internal.network.executeRequest
-import im.vector.matrix.android.internal.session.SessionModule
-import im.vector.matrix.android.internal.session.cache.ClearCacheTask
+import im.vector.matrix.android.internal.session.cleanup.CleanupSession
 import im.vector.matrix.android.internal.task.Task
-import io.realm.Realm
-import io.realm.RealmConfiguration
 import org.greenrobot.eventbus.EventBus
 import timber.log.Timber
-import java.io.File
 import java.net.HttpURLConnection
 import javax.inject.Inject
 
 internal interface SignOutTask : Task<SignOutTask.Params, Unit> {
     data class Params(
-            val sigOutFromHomeserver: Boolean
+            val signOutFromHomeserver: Boolean
     )
 }
 
 internal class DefaultSignOutTask @Inject constructor(
-        private val workManagerProvider: WorkManagerProvider,
-        @SessionId private val sessionId: String,
         private val signOutAPI: SignOutAPI,
-        private val sessionManager: SessionManager,
-        private val sessionParamsStore: SessionParamsStore,
-        @SessionDatabase private val clearSessionDataTask: ClearCacheTask,
-        @CryptoDatabase private val clearCryptoDataTask: ClearCacheTask,
-        @SessionFilesDirectory private val sessionFiles: File,
-        @SessionCacheDirectory private val sessionCache: File,
-        private val realmKeysUtils: RealmKeysUtils,
-        @SessionDatabase private val realmSessionConfiguration: RealmConfiguration,
-        @CryptoDatabase private val realmCryptoConfiguration: RealmConfiguration,
-        @UserMd5 private val userMd5: String,
-        private val eventBus: EventBus
+        private val eventBus: EventBus,
+        private val cleanupSession: CleanupSession
 ) : SignOutTask {
 
     override suspend fun execute(params: SignOutTask.Params) {
         // It should be done even after a soft logout, to be sure the deviceId is deleted on the
-        if (params.sigOutFromHomeserver) {
+        if (params.signOutFromHomeserver) {
             Timber.d("SignOut: send request...")
             try {
                 executeRequest<Unit>(eventBus) {
@@ -87,37 +60,7 @@ internal class DefaultSignOutTask @Inject constructor(
             }
         }
 
-        Timber.d("SignOut: release session...")
-        sessionManager.releaseSession(sessionId)
-
-        Timber.d("SignOut: cancel pending works...")
-        workManagerProvider.cancelAllWorks()
-
-        Timber.d("SignOut: delete session params...")
-        sessionParamsStore.delete(sessionId)
-
-        Timber.d("SignOut: clear session data...")
-        clearSessionDataTask.execute(Unit)
-
-        Timber.d("SignOut: clear crypto data...")
-        clearCryptoDataTask.execute(Unit)
-
-        Timber.d("SignOut: clear file system")
-        sessionFiles.deleteRecursively()
-        sessionCache.deleteRecursively()
-
-        Timber.d("SignOut: clear the database keys")
-        realmKeysUtils.clear(SessionModule.getKeyAlias(userMd5))
-        realmKeysUtils.clear(CryptoModule.getKeyAlias(userMd5))
-
-        // Sanity check
-        if (BuildConfig.DEBUG) {
-            Realm.getGlobalInstanceCount(realmSessionConfiguration)
-                    .takeIf { it > 0 }
-                    ?.let { Timber.e("All realm instance for session has not been closed ($it)") }
-            Realm.getGlobalInstanceCount(realmCryptoConfiguration)
-                    .takeIf { it > 0 }
-                    ?.let { Timber.e("All realm instance for crypto has not been closed ($it)") }
-        }
+        Timber.d("SignOut: cleanup session...")
+        cleanupSession.handle()
     }
 }
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/CryptoSyncHandler.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/CryptoSyncHandler.kt
index 10e7ceb692..86ca561dfe 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/CryptoSyncHandler.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/CryptoSyncHandler.kt
@@ -39,10 +39,10 @@ internal class CryptoSyncHandler @Inject constructor(private val cryptoService:
         toDevice.events?.forEachIndexed { index, event ->
             initialSyncProgressService?.reportProgress(((index / total.toFloat()) * 100).toInt())
             // Decrypt event if necessary
-            decryptEvent(event, null)
+            decryptToDeviceEvent(event, null)
             if (event.getClearType() == EventType.MESSAGE
                     && event.getClearContent()?.toModel<MessageContent>()?.msgType == "m.bad.encrypted") {
-                Timber.e("## handleToDeviceEvent() : Warning: Unable to decrypt to-device event : ${event.content}")
+                Timber.e("## CRYPTO | handleToDeviceEvent() : Warning: Unable to decrypt to-device event : ${event.content}")
             } else {
                 verificationService.onToDeviceEvent(event)
                 cryptoService.onToDeviceEvent(event)
@@ -61,28 +61,24 @@ internal class CryptoSyncHandler @Inject constructor(private val cryptoService:
      * @param timelineId the timeline identifier
      * @return true if the event has been decrypted
      */
-    private fun decryptEvent(event: Event, timelineId: String?): Boolean {
+    private fun decryptToDeviceEvent(event: Event, timelineId: String?): Boolean {
+        Timber.v("## CRYPTO | decryptToDeviceEvent")
         if (event.getClearType() == EventType.ENCRYPTED) {
             var result: MXEventDecryptionResult? = null
             try {
                 result = cryptoService.decryptEvent(event, timelineId ?: "")
             } catch (exception: MXCryptoError) {
                 event.mCryptoError = (exception as? MXCryptoError.Base)?.errorType // setCryptoError(exception.cryptoError)
+                Timber.e("## CRYPTO | Failed to decrypt to device event: ${event.mCryptoError ?: exception}")
             }
 
             if (null != result) {
-//                event.mxDecryptionResult = MXDecryptionResult(
-//                        payload = result.clearEvent,
-//                        keysClaimed = map
-//                )
-                // TODO persist that?
                 event.mxDecryptionResult = OlmDecryptionResult(
                         payload = result.clearEvent,
                         senderKey = result.senderCurve25519Key,
                         keysClaimed = result.claimedEd25519Key?.let { mapOf("ed25519" to it) },
                         forwardingCurve25519KeyChain = result.forwardingCurve25519KeyChain
                 )
-//                event.setClearData(result)
                 return true
             }
         }
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/SyncTask.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/SyncTask.kt
index b56594bd16..b3db4d0961 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/SyncTask.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/SyncTask.kt
@@ -53,8 +53,6 @@ internal class DefaultSyncTask @Inject constructor(
 
     private suspend fun doSync(params: SyncTask.Params) {
         Timber.v("Sync task started on Thread: ${Thread.currentThread().name}")
-        // Maybe refresh the home server capabilities data we know
-        getHomeServerCapabilitiesTask.execute(Unit)
 
         val requestParams = HashMap<String, String>()
         var timeout = 0L
@@ -73,6 +71,9 @@ internal class DefaultSyncTask @Inject constructor(
             initialSyncProgressService.endAll()
             initialSyncProgressService.startTask(R.string.initial_sync_start_importing_account, 100)
         }
+        // Maybe refresh the home server capabilities data we know
+        getHomeServerCapabilitiesTask.execute(Unit)
+
         val syncResponse = executeRequest<SyncResponse>(eventBus) {
             apiCall = syncAPI.sync(requestParams)
         }
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/job/SyncWorker.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/job/SyncWorker.kt
index c844db8d33..ab4e1938ce 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/job/SyncWorker.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/job/SyncWorker.kt
@@ -35,6 +35,10 @@ import javax.inject.Inject
 
 private const val DEFAULT_LONG_POOL_TIMEOUT = 0L
 
+/**
+ * Possible previous worker: None
+ * Possible next worker    : None
+ */
 internal class SyncWorker(context: Context,
                           workerParameters: WorkerParameters
 ) : CoroutineWorker(context, workerParameters) {
@@ -53,7 +57,10 @@ internal class SyncWorker(context: Context,
 
     override suspend fun doWork(): Result {
         Timber.i("Sync work starting")
-        val params = WorkerParamsFactory.fromData<Params>(inputData) ?: return Result.success()
+        val params = WorkerParamsFactory.fromData<Params>(inputData)
+                ?: return Result.success()
+                        .also { Timber.e("Unable to parse work parameters") }
+
         val sessionComponent = getSessionComponent(params.sessionId) ?: return Result.success()
         sessionComponent.inject(this)
         return runCatching {
@@ -76,7 +83,6 @@ internal class SyncWorker(context: Context,
     }
 
     companion object {
-
         private const val BG_SYNC_WORK_NAME = "BG_SYNCP"
 
         fun requireBackgroundSync(workManagerProvider: WorkManagerProvider, sessionId: String, serverTimeout: Long = 0) {
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/user/accountdata/AccountDataAPI.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/user/accountdata/AccountDataAPI.kt
index 824af2d1c3..65ec05e76e 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/user/accountdata/AccountDataAPI.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/user/accountdata/AccountDataAPI.kt
@@ -19,7 +19,6 @@ package im.vector.matrix.android.internal.session.user.accountdata
 import im.vector.matrix.android.internal.network.NetworkConstants
 import retrofit2.Call
 import retrofit2.http.Body
-import retrofit2.http.POST
 import retrofit2.http.PUT
 import retrofit2.http.Path
 
@@ -34,15 +33,4 @@ interface AccountDataAPI {
      */
     @PUT(NetworkConstants.URI_API_PREFIX_PATH_R0 + "user/{userId}/account_data/{type}")
     fun setAccountData(@Path("userId") userId: String, @Path("type") type: String, @Body params: Any): Call<Unit>
-
-    /**
-     * Gets a bearer token from the homeserver that the user can
-     * present to a third party in order to prove their ownership
-     * of the Matrix account they are logged into.
-     *
-     * @param userId the user id
-     * @param body   the body content
-     */
-    @POST(NetworkConstants.URI_API_PREFIX_PATH_R0 + "user/{userId}/openid/request_token")
-    fun openIdToken(@Path("userId") userId: String, @Body body: Map<Any, Any>): Call<Map<Any, Any>>
 }
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/util/Debouncer.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/util/Debouncer.kt
index 6a294d8d6c..575551da1b 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/util/Debouncer.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/util/Debouncer.kt
@@ -23,11 +23,9 @@ internal class Debouncer(private val handler: Handler) {
     private val runnables = HashMap<String, Runnable>()
 
     fun debounce(identifier: String, r: Runnable, millis: Long): Boolean {
-        if (runnables.containsKey(identifier)) {
-            // debounce
-            val old = runnables[identifier]
-            handler.removeCallbacks(old)
-        }
+        // debounce
+        runnables[identifier]?.let { runnable -> handler.removeCallbacks(runnable) }
+
         insertRunnable(identifier, r, millis)
         return true
     }
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/worker/SessionWorkerParams.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/worker/SessionWorkerParams.kt
index c05367cf10..3cbe6c7866 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/worker/SessionWorkerParams.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/worker/SessionWorkerParams.kt
@@ -16,9 +16,16 @@
 
 package im.vector.matrix.android.internal.worker
 
+/**
+ * Note about the Worker usage:
+ * The workers we chain, or when using the append strategy, should never return Result.Failure(), else the chain will be broken forever
+ */
 interface SessionWorkerParams {
     val sessionId: String
 
-    // Null is no error occurs. When chaining Workers, first step is to check that there is no lastFailureMessage from the previous workers
+    /**
+     * Null when no error occurs. When chaining Workers, first step is to check that there is no lastFailureMessage from the previous workers
+     * If it is the case, the worker should just transmit the error and shouldn't do anything else
+     */
     val lastFailureMessage: String?
 }
diff --git a/matrix-sdk-android/src/main/res/values-bg/strings.xml b/matrix-sdk-android/src/main/res/values-bg/strings.xml
index 2a8c087e25..ad2d2e7895 100644
--- a/matrix-sdk-android/src/main/res/values-bg/strings.xml
+++ b/matrix-sdk-android/src/main/res/values-bg/strings.xml
@@ -202,4 +202,12 @@
     <string name="notice_room_canonical_alias_set">%1$s настрой %2$s като основен адрес за тази стая.</string>
     <string name="notice_room_canonical_alias_unset">%1$s премахна основния адрес за тази стая.</string>
 
+    <string name="notice_room_guest_access_can_join">%1$s разреши на гости да се присъединяват в стаята.</string>
+    <string name="notice_room_guest_access_forbidden">%1$s предотврати присъединяването на гости в стаята.</string>
+
+    <string name="notice_end_to_end_ok">%1$s включи шифроване от-край-до-край.</string>
+    <string name="notice_end_to_end_unknown_algorithm">%1$s включи шифроване от-край-до-край (неразпознат алгоритъм %2$s).</string>
+
+    <string name="key_verification_request_fallback_message">%s изпрати запитване за потвърждение на ключа ви, но клиентът ви не поддържа верифициране посредством чат. Ще трябва да използвате стария метод за верифициране на ключове.</string>
+
 </resources>
diff --git a/matrix-sdk-android/src/main/res/values-bn-rIN/strings.xml b/matrix-sdk-android/src/main/res/values-bn-rIN/strings.xml
new file mode 100644
index 0000000000..4400dcd9b6
--- /dev/null
+++ b/matrix-sdk-android/src/main/res/values-bn-rIN/strings.xml
@@ -0,0 +1,24 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<resources>
+    <string name="summary_user_sent_image">%1$s একটি ফটো পাঠিয়েছে।</string>
+    <string name="summary_user_sent_sticker">%1$s একটি স্তিকার পাঠিয়েছে।</string>
+
+    <string name="notice_room_invite_no_invitee">%s এর আমন্ত্রণ</string>
+    <string name="notice_room_invite">%1$s %2$s কে আমন্ত্রণ করেছে</string>
+    <string name="notice_room_invite_you">%1$s আপনাকে আমন্ত্রণ করেছে</string>
+    <string name="notice_room_join">%1$s রুম এ যোগ দিয়েছে</string>
+    <string name="notice_room_leave">%1$s রুম ছেড়ে দিয়েছে</string>
+    <string name="notice_room_reject">%1$s আমন্ত্রণ টি বাতিল করেছে</string>
+    <string name="notice_room_kick">%1$s %2$s কে কিক করেছে</string>
+    <string name="notice_room_unban">%1$s %2$s কে নিষিদ্ধ তালিকা থেকে মুক্ত করেছে</string>
+    <string name="notice_room_ban">%1$s %2$s কে নিষিদ্ধ করেছে</string>
+    <string name="notice_room_withdraw">%1$s %2$s এর আমন্ত্রণ ফেরত নিয়েছে</string>
+    <string name="notice_avatar_url_changed">%1$s নিজের অবতার পরিবর্তন করেছে</string>
+    <string name="notice_display_name_set">%1$s নিজের প্রদর্শন নাম %2$s রেখেছে</string>
+    <string name="notice_display_name_changed_from">%1$s নিজের প্রদর্শন নাম %2$s থেকে %3$s তে পরিবর্তন করেছে</string>
+    <string name="notice_display_name_removed">%1$s নিজের প্রদর্শন নাম মুছে দিয়েছে (%2$s)</string>
+    <string name="notice_room_topic_changed">%1$s বিষয় টি এতে পরিবর্তন করেছে: %2$s</string>
+    <string name="notice_room_name_changed">%1$s রুম এর নাম এতে পরিবর্তন করেছে: %2$s</string>
+    <string name="notice_placed_video_call">%s একটি ভিডিও কল স্থাপন করেছিল।</string>
+    <string name="notice_placed_voice_call">%s একটি ভয়েস কল দিয়েছে।</string>
+</resources>
diff --git a/matrix-sdk-android/src/main/res/values-ca/strings.xml b/matrix-sdk-android/src/main/res/values-ca/strings.xml
index 4c2f4a8a7f..c59ee3b23d 100644
--- a/matrix-sdk-android/src/main/res/values-ca/strings.xml
+++ b/matrix-sdk-android/src/main/res/values-ca/strings.xml
@@ -30,20 +30,20 @@
 
     <string name="notice_requested_voip_conference">%1$s ha sol·licitat una conferència VoIP</string>
     <string name="notice_room_unban">%1$s ha readmès a %2$s</string>
-    <string name="notice_room_ban">%1$s ha expulsat a %2$s</string>
+    <string name="notice_room_ban">%1$s ha vetat a %2$s</string>
     <string name="notice_room_withdraw">%1$s ha retirat la invitació de %2$s</string>
     <string name="notice_avatar_url_changed">%1$s ha canviat el seu avatar</string>
     <string name="notice_made_future_room_visibility">%1$s ha permès a %2$s veure l\'historial que es generi a partir d\'ara</string>
     <string name="notice_room_visibility_joined">tots els membres de la sala, des del punt en què hi entrin.</string>
     <string name="notice_room_visibility_world_readable">qualsevol.</string>
     <string name="notice_voip_started">S\'ha iniciat la conferència VoIP</string>
-    <string name="notice_voip_finished">S\'ha finalitzat la conferència VoIP</string>
+    <string name="notice_voip_finished">S\'ha finalitzat la conferència de veu IP</string>
 
     <string name="notice_avatar_changed_too">(s\'ha canviat també l\'avatar)</string>
     <string name="notice_room_name_removed">%1$s ha eliminat el nom de la sala</string>
     <string name="notice_room_topic_removed">%1$s ha eliminat el tema de la sala</string>
     <string name="notice_profile_change_redacted">%1$s ha actualitzat el seu perfil %2$s</string>
-    <string name="notice_room_third_party_invite">%1$s ha enviat una invitació a l\'usuari %2$s per a entrar a la sala</string>
+    <string name="notice_room_third_party_invite">%1$s ha enviat una invitació a %2$s per a entrar a la sala</string>
     <string name="notice_room_third_party_registered_invite">%1$s ha acceptat la invitació per a %2$s</string>
 
     <string name="notice_crypto_unable_to_decrypt">** No s\'ha pogut desencriptar: %s **</string>
diff --git a/matrix-sdk-android/src/main/res/values-cs/strings.xml b/matrix-sdk-android/src/main/res/values-cs/strings.xml
index 61f3db0b25..7e5081b6e9 100644
--- a/matrix-sdk-android/src/main/res/values-cs/strings.xml
+++ b/matrix-sdk-android/src/main/res/values-cs/strings.xml
@@ -1,57 +1,57 @@
 <?xml version='1.0' encoding='UTF-8'?>
 <resources>
     <string name="summary_message">%1$s: %2$s</string>
-    <string name="summary_user_sent_image">%1$s poslal obrázek.</string>
-    <string name="summary_user_sent_sticker">%1$s poslal nálepku.</string>
+    <string name="summary_user_sent_image">Uživatel %1$s poslal obrázek.</string>
+    <string name="summary_user_sent_sticker">Uživatel %1$s poslal nálepku.</string>
 
-    <string name="notice_room_invite_no_invitee">Pozvánka od %s</string>
-    <string name="notice_room_invite">%1$s pozval %2$s</string>
-    <string name="notice_room_invite_you">%1$s Vás pozval</string>
-    <string name="notice_room_join">%1$s se připojil</string>
-    <string name="notice_room_leave">%1$s odešel</string>
-    <string name="notice_room_reject">%1$s odmítl pozvání</string>
-    <string name="notice_room_kick">%1$s vyhodil %2$s</string>
-    <string name="notice_room_unban">%1$s znovu povolil vstup %2$s</string>
-    <string name="notice_room_ban">%1$s zakázal vstup %2$s</string>
-    <string name="notice_room_withdraw">%1$s stáhnul pozvání pro %2$s</string>
-    <string name="notice_avatar_url_changed">%1$s změnil svůj profilový obrázek</string>
-    <string name="notice_display_name_set">%1$s nastavil své zobrazované jméno na %2$s</string>
-    <string name="notice_display_name_changed_from">%1$s změnil své zobrazované jméno z %2$s na %3$s</string>
-    <string name="notice_display_name_removed">%1$s odstranil své zobrazované jméno (%2$s)</string>
-    <string name="notice_room_topic_changed">%1$s změnil téma na: %2$s</string>
-    <string name="notice_room_name_changed">%1$s změnil název místnosti na: %2$s</string>
-    <string name="notice_placed_video_call">%s uskutečnil videohovor.</string>
-    <string name="notice_placed_voice_call">%s uskutečnil hlasový hovor.</string>
-    <string name="notice_answered_call">%s přijal hovor.</string>
-    <string name="notice_ended_call">%s ukončil hovor.</string>
-    <string name="notice_made_future_room_visibility">%1$s zviditelnil budoucí historii místnosti %2$s</string>
-    <string name="notice_room_visibility_invited">všem členům místnosti od doby kdy byli pozváni.</string>
-    <string name="notice_room_visibility_joined">všem členům místnosti od doby kdy se připojili.</string>
-    <string name="notice_room_visibility_shared">všem členům místnosti.</string>
-    <string name="notice_room_visibility_world_readable">komukoliv.</string>
+    <string name="notice_room_invite_no_invitee">Pozvánka od uživatele %s</string>
+    <string name="notice_room_invite">Uživatel %1$s pozval uživatele %2$s</string>
+    <string name="notice_room_invite_you">Uživatel %1$s vás pozval</string>
+    <string name="notice_room_join">Uživatel %1$s se připojil</string>
+    <string name="notice_room_leave">Uživatel %1$s odešel</string>
+    <string name="notice_room_reject">Uživatel %1$s odmítl pozvání</string>
+    <string name="notice_room_kick">Uživatel %1$s vykopl uživatele %2$s</string>
+    <string name="notice_room_unban">Uživatel %1$s znovu povolil vstup uživateli %2$s</string>
+    <string name="notice_room_ban">Uživatel %1$s vykázal uživatele %2$s</string>
+    <string name="notice_room_withdraw">Uživatel %1$s zrušil pozvání pro uživatele %2$s</string>
+    <string name="notice_avatar_url_changed">Uživatel %1$s změnil svůj profilový obrázek</string>
+    <string name="notice_display_name_set">Uživatel %1$s nastavil své zobrazované jméno na %2$s</string>
+    <string name="notice_display_name_changed_from">Uživatel %1$s změnil své zobrazované jméno z %2$s na %3$s</string>
+    <string name="notice_display_name_removed">Uživatel %1$s odstranil své zobrazované jméno (%2$s)</string>
+    <string name="notice_room_topic_changed">Uživatel %1$s změnil téma na: %2$s</string>
+    <string name="notice_room_name_changed">Uživatel %1$s změnil název místnosti na: %2$s</string>
+    <string name="notice_placed_video_call">Uživatel %s uskutečnil videohovor.</string>
+    <string name="notice_placed_voice_call">Uživatel %s uskutečnil hlasový hovor.</string>
+    <string name="notice_answered_call">Uživatel %s přijal hovor.</string>
+    <string name="notice_ended_call">Uživatel %s ukončil hovor.</string>
+    <string name="notice_made_future_room_visibility">Uživatel %1$s nastavit viditelnost budoucích zpráv v místnosti pro %2$s</string>
+    <string name="notice_room_visibility_invited">všechny členy místnosti od chvíle, kdy budou pozváni.</string>
+    <string name="notice_room_visibility_joined">všechny členy místnosti od chvíle, kdy se připojí.</string>
+    <string name="notice_room_visibility_shared">všechny členy místnosti.</string>
+    <string name="notice_room_visibility_world_readable">kohokoliv.</string>
     <string name="notice_room_visibility_unknown">neznámým (%s).</string>
-    <string name="notice_end_to_end">%1$s zapnul E2E šifrování (%2$s)</string>
+    <string name="notice_end_to_end">Uživatel %1$s zapnul end-to-end šifrování (%2$s)</string>
 
-    <string name="notice_requested_voip_conference">%1$s požádal o VoIP konferenci</string>
+    <string name="notice_requested_voip_conference">Uživatel %1$s požádal o VoIP konferenci</string>
     <string name="notice_voip_started">Začala VoIP konference</string>
     <string name="notice_voip_finished">VoIP konference skončila</string>
 
     <string name="notice_avatar_changed_too">(profilový obrázek byl také změněn)</string>
-    <string name="notice_room_name_removed">%1$s odstranil název místnosti</string>
-    <string name="notice_room_topic_removed">%1$s odstranil téma místnosti</string>
-    <string name="notice_profile_change_redacted">%1$s aktualizoval svůj profil %2$s</string>
-    <string name="notice_room_third_party_invite">%1$s pozval %2$s aby se připojil do místnosti</string>
-    <string name="notice_room_third_party_registered_invite">%1$s přijal pozvání do %2$s</string>
+    <string name="notice_room_name_removed">Uživatel %1$s odstranil název místnosti</string>
+    <string name="notice_room_topic_removed">Uživatel %1$s odstranil téma místnosti</string>
+    <string name="notice_profile_change_redacted">Uživatel %1$s aktualizoval svůj profil %2$s</string>
+    <string name="notice_room_third_party_invite">Uživatel %1$s do této místnosti pozval uživatele %2$s</string>
+    <string name="notice_room_third_party_registered_invite">Uživatel %1$s přijal pozvání pro %2$s</string>
 
-    <string name="notice_crypto_unable_to_decrypt">** Není možno dešifrovat: %s **</string>
-    <string name="notice_crypto_error_unkwown_inbound_session_id">Odesílatelovo zařízení nám neposlalo klíče pro tuto zprávu.</string>
+    <string name="notice_crypto_unable_to_decrypt">** Nelze dešifrovat: %s **</string>
+    <string name="notice_crypto_error_unkwown_inbound_session_id">Odesílatelovo zařízení neposlalo klíče pro tuto zprávu.</string>
 
-    <string name="message_reply_to_prefix">Odpověď na</string>
+    <string name="message_reply_to_prefix">V odpovědi na</string>
 
-    <string name="could_not_redact">Není možno sloučit</string>
-    <string name="unable_to_send_message">Není možné odeslat zprávu</string>
+    <string name="could_not_redact">Nelze vymazat</string>
+    <string name="unable_to_send_message">Zprávu nelze odeslat</string>
 
-    <string name="message_failed_to_upload">Nepodařilo se nahrát obrázek</string>
+    <string name="message_failed_to_upload">Obrázek nelze nahrát</string>
 
     <string name="network_error">Chyba sítě</string>
     <string name="matrix_error">Chyba v Matrixu</string>
@@ -74,19 +74,18 @@
     <string name="room_displayname_two_members">%1$s a %2$s</string>
 
     <plurals name="room_displayname_three_and_more_members">
-        <item quantity="one">%1$s a 1 další</item>
+        <item quantity="one">%1$s a jeden další</item>
         <item quantity="few">%1$s a %2$d další</item>
-        <item quantity="many">%1$s a %2$d dalších</item>
-        <item quantity="other" />
+        <item quantity="other">%1$s a %2$d dalších</item>
     </plurals>
 
     <string name="room_displayname_empty_room">Prázdná místnost</string>
 
-    <string name="notice_room_update">%s upravil/a tuto místnost.</string>
+    <string name="notice_room_update">Uživatel %s upgradoval tuto místnost.</string>
 
     <string name="notice_event_redacted_with_reason">Zpráva byla smazána [důvod: %1$s]</string>
-    <string name="notice_event_redacted_by_with_reason">Zpráva smazána [smazal/a %1$s] [důvod: %2$s]</string>
-    <string name="notice_room_third_party_revoked_invite">"%1$s obnovil/a pozvánku do místnosti pro  %2$s"</string>
+    <string name="notice_event_redacted_by_with_reason">Zpráva smazána uživatelem %1$s [důvod: %2$s]</string>
+    <string name="notice_room_third_party_revoked_invite">Uživatel %1$s obnovil pozvánku do místnosti pro uživatele %2$s</string>
     <string name="verification_emoji_cat">Kočka</string>
     <string name="verification_emoji_lion">Lev</string>
     <string name="verification_emoji_horse">Kůň</string>
@@ -96,7 +95,7 @@
     <string name="verification_emoji_rabbit">Králík</string>
     <string name="verification_emoji_panda">Panda</string>
     <string name="verification_emoji_rooster">Kohout</string>
-    <string name="verification_emoji_penguin">Tučnák</string>
+    <string name="verification_emoji_penguin">Tučňák</string>
     <string name="verification_emoji_turtle">Želva</string>
     <string name="verification_emoji_fish">Ryba</string>
     <string name="verification_emoji_octopus">Chobotnice</string>
@@ -105,7 +104,7 @@
     <string name="verification_emoji_tree">Strom</string>
     <string name="verification_emoji_cactus">Kaktus</string>
     <string name="verification_emoji_mushroom">Houba</string>
-    <string name="verification_emoji_globe">Glóbus</string>
+    <string name="verification_emoji_globe">Zeměkoule</string>
     <string name="verification_emoji_moon">Měsíc</string>
     <string name="verification_emoji_cloud">Mrak</string>
     <string name="verification_emoji_fire">Oheň</string>
@@ -120,14 +119,14 @@
     <string name="verification_emoji_robot">Robot</string>
     <string name="verification_emoji_hat">Klobouk</string>
     <string name="verification_emoji_glasses">Brýle</string>
-    <string name="verification_emoji_santa">Santa</string>
+    <string name="verification_emoji_santa">Santa Klaus</string>
     <string name="verification_emoji_thumbsup">Zvednutý palec</string>
     <string name="verification_emoji_umbrella">Deštník</string>
     <string name="verification_emoji_hourglass">Přesípací hodiny</string>
     <string name="verification_emoji_clock">Hodiny</string>
     <string name="verification_emoji_gift">Dárek</string>
     <string name="verification_emoji_lightbulb">Žárovka</string>
-    <string name="verification_emoji_book">Knížka</string>
+    <string name="verification_emoji_book">Kniha</string>
     <string name="verification_emoji_pencil">Tužka</string>
     <string name="verification_emoji_paperclip">Sponka</string>
     <string name="verification_emoji_scissors">Nůžky</string>
@@ -137,31 +136,43 @@
     <string name="verification_emoji_telephone">Telefon</string>
     <string name="verification_emoji_flag">Vlajka</string>
     <string name="verification_emoji_train">Vlak</string>
-    <string name="verification_emoji_bicycle">Kolo</string>
+    <string name="verification_emoji_bicycle">Jízdní kolo</string>
     <string name="verification_emoji_airplane">Letadlo</string>
     <string name="verification_emoji_rocket">Raketa</string>
-    <string name="verification_emoji_trophy">Pohár</string>
+    <string name="verification_emoji_trophy">Trofej</string>
     <string name="verification_emoji_ball">Míč</string>
     <string name="verification_emoji_guitar">Kytara</string>
     <string name="verification_emoji_trumpet">Trumpeta</string>
     <string name="verification_emoji_bell">Zvon</string>
     <string name="verification_emoji_anchor">Kotva</string>
     <string name="verification_emoji_headphone">Sluchátka</string>
-    <string name="verification_emoji_folder">Složka</string>
-    <string name="initial_sync_start_importing_account">Úvodní synchronizace:
-\nStahuji účet…</string>
-    <string name="initial_sync_start_importing_account_crypto">Uvodní synchronizace:
-\nStahuji klíče</string>
-    <string name="initial_sync_start_importing_account_rooms">Uvodní synchnizace:
-\nStahuji místnost</string>
-    <string name="initial_sync_start_importing_account_joined_rooms">Uvodní synchronizace:
-\nStahuji moje místnosti</string>
-    <string name="initial_sync_start_importing_account_left_rooms">Uvodní synchonizace:
-\nStahuji místnosti, které jsem opustil/a</string>
-    <string name="initial_sync_start_importing_account_groups">Úvodní sychronizace:
-\nImportuji komunity</string>
-    <string name="initial_sync_start_importing_account_data">Úvodní synchronizace:
-\nImportuji data účtu</string>
+    <string name="verification_emoji_folder">Desky</string>
+    <string name="initial_sync_start_importing_account">Úvodní synchronizace: 
+\nImport účtu…</string>
+    <string name="initial_sync_start_importing_account_crypto">Úvodní synchronizace: 
+\nImport klíčů</string>
+    <string name="initial_sync_start_importing_account_rooms">Úvodní synchronizace: 
+\nImport místností</string>
+    <string name="initial_sync_start_importing_account_joined_rooms">Úvodní synchronizace: 
+\nImport místností, kterými jste členy</string>
+    <string name="initial_sync_start_importing_account_left_rooms">Úvodní synchronizace: 
+\nImport opuštěných místností</string>
+    <string name="initial_sync_start_importing_account_groups">Úvodní synchronizace: 
+\nImport skupin</string>
+    <string name="initial_sync_start_importing_account_data">Úvodní synchronizace: 
+\nImport dat účtu</string>
 
-    <string name="event_status_sending_message">Posílám zprávu…</string>
+    <string name="event_status_sending_message">Odesílání zprávy…</string>
+    <string name="verification_emoji_wrench">Maticový klíč</string>
+    <string name="verification_emoji_pin">Připínáček</string>
+
+    <string name="initial_sync_start_importing_account_invited_rooms">Úvodní synchronizace:
+\nImport pozvánek</string>
+    <string name="clear_timeline_send_queue">Vymazat frontu neodeslaných zpráv</string>
+
+    <string name="notice_room_invite_with_reason">Uživatel %1$s pozval uživatele %2$s. Důvod: %3$s</string>
+    <string name="notice_room_invite_you_with_reason">Uživatel %1$s váš pozval. Důvod: %2$s</string>
+    <string name="notice_room_leave_with_reason">Uživatel %1$s odešel. Důvod: %2$s</string>
+    <string name="notice_event_redacted">Zpráva odstraněna</string>
+    <string name="notice_event_redacted_by">Zprávu odstranil/a %1$s</string>
 </resources>
diff --git a/matrix-sdk-android/src/main/res/values-de/strings.xml b/matrix-sdk-android/src/main/res/values-de/strings.xml
index fa66f96aba..dc874c2b94 100644
--- a/matrix-sdk-android/src/main/res/values-de/strings.xml
+++ b/matrix-sdk-android/src/main/res/values-de/strings.xml
@@ -11,7 +11,7 @@
     <string name="notice_room_leave">%1$s hat den Raum verlassen</string>
     <string name="notice_room_reject">%1$s hat die Einladung abgelehnt</string>
     <string name="notice_room_kick">%1$s hat %2$s gekickt</string>
-    <string name="notice_room_unban">%1$s hat die Verbannung von %2$s aufgehoben</string>
+    <string name="notice_room_unban">%1$s hat die Sperre von %2$s aufgehoben</string>
     <string name="notice_room_ban">%1$s hat %2$s verbannt</string>
     <string name="notice_room_withdraw">%1$s hat die Einladung für %2$s zurückgezogen</string>
     <string name="notice_avatar_url_changed">%1$s hat das Profilbild geändert</string>
@@ -41,7 +41,7 @@
     <string name="notice_room_topic_removed">%1$s hat das Raum-Thema entfernt</string>
     <string name="notice_profile_change_redacted">%1$s hat das Benutzerprofil aktualisiert %2$s</string>
     <string name="notice_room_third_party_invite">%1$s hat eine Einladung an %2$s gesendet</string>
-    <string name="notice_room_third_party_registered_invite">%1$s hat die Einladung für %2$s akzeptiert</string>
+    <string name="notice_room_third_party_registered_invite">%1$s hat die Einladung in %2$s akzeptiert</string>
 
     <string name="notice_crypto_unable_to_decrypt">** Nicht entschlüsselbar: %s **</string>
     <string name="notice_crypto_error_unkwown_inbound_session_id">Das absendende Gerät hat uns keine Schlüssel für diese Nachricht übermittelt.</string>
@@ -76,7 +76,7 @@
     <string name="message_reply_to_prefix">Als Antwort auf</string>
 
     <string name="reply_to_an_image">hat ein Bild gesendet.</string>
-    <string name="reply_to_a_video">sandte ein Video.</string>
+    <string name="reply_to_a_video">hat ein Video gesendet.</string>
     <string name="reply_to_an_audio_file">hat eine Audio-Datei gesendet.</string>
     <string name="reply_to_a_file">sandte eine Datei.</string>
 
@@ -112,7 +112,7 @@
     <string name="verification_emoji_penguin">Pinguin</string>
     <string name="verification_emoji_turtle">Schildkröte</string>
     <string name="verification_emoji_fish">Fisch</string>
-    <string name="verification_emoji_octopus">Tintenfisch</string>
+    <string name="verification_emoji_octopus">Oktopus</string>
     <string name="verification_emoji_butterfly">Schmetterling</string>
     <string name="verification_emoji_flower">Blume</string>
     <string name="verification_emoji_tree">Baum</string>
@@ -128,12 +128,12 @@
     <string name="verification_emoji_corn">Mais</string>
     <string name="verification_emoji_cake">Kuchen</string>
     <string name="verification_emoji_heart">Herz</string>
-    <string name="verification_emoji_smiley">Lächeln</string>
+    <string name="verification_emoji_smiley">Smiley</string>
     <string name="verification_emoji_robot">Roboter</string>
     <string name="verification_emoji_hat">Hut</string>
     <string name="verification_emoji_glasses">Brille</string>
     <string name="verification_emoji_wrench">Schraubenschlüssel</string>
-    <string name="verification_emoji_santa">Nikolaus</string>
+    <string name="verification_emoji_santa">Weihnachtsmann</string>
     <string name="verification_emoji_thumbsup">Daumen hoch</string>
     <string name="verification_emoji_umbrella">Regenschirm</string>
     <string name="verification_emoji_hourglass">Sanduhr</string>
@@ -141,10 +141,10 @@
     <string name="verification_emoji_gift">Geschenk</string>
     <string name="verification_emoji_lightbulb">Glühbirne</string>
     <string name="verification_emoji_book">Buch</string>
-    <string name="verification_emoji_pencil">Stift</string>
+    <string name="verification_emoji_pencil">Bleistift</string>
     <string name="verification_emoji_paperclip">Büroklammer</string>
-    <string name="verification_emoji_scissors">Scheren</string>
-    <string name="verification_emoji_lock">sperren</string>
+    <string name="verification_emoji_scissors">Schere</string>
+    <string name="verification_emoji_lock">Schloss</string>
     <string name="verification_emoji_key">Schlüssel</string>
     <string name="verification_emoji_hammer">Hammer</string>
     <string name="verification_emoji_telephone">Telefon</string>
@@ -183,11 +183,34 @@
     <string name="notice_room_leave_with_reason">%1$s ging. Grund: %2$s</string>
     <string name="notice_room_reject_with_reason">%1$s hat die Einladung abgelehnt. Grund: %2$s</string>
     <string name="notice_room_kick_with_reason">%1$s hat %2$s gekickt. Grund: %3$s</string>
-    <string name="notice_room_unban_with_reason">%1$s hat Verbannung für %2$s aufgehoben. Grund: %3$s</string>
+    <string name="notice_room_unban_with_reason">%1$s hat Sperre von %2$s aufgehoben. Grund: %3$s</string>
     <string name="notice_room_ban_with_reason">%1$s hat %2$s verbannt. Grund: %3$s</string>
     <string name="notice_room_third_party_invite_with_reason">%1$s hat eine Einladung an %2$s gesandt um diesem Raum beizutreten. Grund: %3$s</string>
     <string name="notice_room_third_party_revoked_invite_with_reason">%1$s hat Einladung an %2$s zu Betreten dieses Raumes zurückgezogen. Grund: %3$s</string>
     <string name="notice_room_third_party_registered_invite_with_reason">%1$s hat die Einladung für %2$s angenommen. Grund: %3$s</string>
     <string name="notice_room_withdraw_with_reason">%1$s hat Einladung für %2$s verworfen. Grund: %3$s</string>
 
+    <plurals name="notice_room_aliases_added">
+        <item quantity="one">%1$s fügt %2$s als eine Adresse für diesen Raum hinzu.</item>
+        <item quantity="other">%1$s fügt %2$s als Adressen für diesen Raum hinzu.</item>
+    </plurals>
+
+    <plurals name="notice_room_aliases_removed">
+        <item quantity="one">%1$s entfernt %2$s als eine Adresse für diesen Raum.</item>
+        <item quantity="other">%1$s entfernt %2$s als Adressen für diesen Raum.</item>
+    </plurals>
+
+    <string name="notice_room_aliases_added_and_removed">%1$s fügt %2$s als Adresse für diesen Raum hinzu und entfernt %3$s.</string>
+
+    <string name="notice_room_canonical_alias_set">%1$s legt die Hauptadresse fest für diesen Raum als %2$s fest.</string>
+    <string name="notice_room_canonical_alias_unset">%1$s entfernt die Hauptadresse für diesen Raum.</string>
+
+    <string name="notice_room_guest_access_can_join">%1$s hat Gästen erlaubt den Raum zu betreten.</string>
+    <string name="notice_room_guest_access_forbidden">%1$s hat Gäste unterbunden den Raum zu betreten.</string>
+
+    <string name="notice_end_to_end_ok">%1$s aktivierte Ende-zu-Ende-Verschlüsselung.</string>
+    <string name="notice_end_to_end_unknown_algorithm">%1$s aktivierte Ende-zu-Ende-Verschlüsselung (unbekannter Algorithmus %2$s).</string>
+
+    <string name="key_verification_request_fallback_message">%s fordert zur Überprüfung Ihres Schlüssels auf, jedoch unterstützt Ihr Client nicht die Schlüsselüberprüfung im Chat. Sie müssen die herkömmliche Schlüsselüberprüfung verwenden, um die Schlüssel zu überprüfen.</string>
+
 </resources>
diff --git a/matrix-sdk-android/src/main/res/values-es/strings.xml b/matrix-sdk-android/src/main/res/values-es/strings.xml
index bcffeb0c87..69f02d2ef4 100644
--- a/matrix-sdk-android/src/main/res/values-es/strings.xml
+++ b/matrix-sdk-android/src/main/res/values-es/strings.xml
@@ -6,8 +6,8 @@
 
     <string name="notice_room_invite_no_invitee">la invitación de %s</string>
     <string name="notice_room_invite">%1$s invitó a %2$s</string>
-    <string name="notice_room_invite_you">%1$s te invitó</string>
-    <string name="notice_room_join">%1$s se unió</string>
+    <string name="notice_room_invite_you">%1$s te ha invitado</string>
+    <string name="notice_room_join">%1$s se ha unido</string>
     <string name="notice_room_leave">%1$s salió</string>
     <string name="notice_room_reject">%1$s rechazó la invitación</string>
     <string name="notice_room_kick">%1$s expulsó a %2$s</string>
@@ -178,4 +178,45 @@
     <string name="notice_room_third_party_registered_invite_with_reason">%1$s ha aceptado la invitación para %2$s. Razón: %3$s</string>
     <string name="notice_room_canonical_alias_unset">%1$s ha eliminado la dirección principal para esta sala.</string>
 
+    <string name="notice_room_update">%s ha actualizado la sala.</string>
+
+    <string name="verification_emoji_globe">Globo Terráqueo</string>
+    <string name="verification_emoji_smiley">Cara sonriente</string>
+    <string name="verification_emoji_robot">Robot</string>
+    <string name="verification_emoji_santa">Papá Noel</string>
+    <string name="verification_emoji_pin">Pin</string>
+
+    <string name="initial_sync_start_importing_account_crypto">Sincronización Inicial:
+\nImportando criptografía</string>
+    <string name="initial_sync_start_importing_account_joined_rooms">Sincronización Inicial:
+\nImportando Salas a las que te has unido</string>
+    <string name="initial_sync_start_importing_account_invited_rooms">Sincronización Inicial:
+\nImportando Salas a las que has sido invitada</string>
+    <string name="initial_sync_start_importing_account_left_rooms">Sincronización Inicial:
+\nImportando Salas Abandonadas</string>
+    <string name="notice_room_invite_no_invitee_with_reason">Invitación de %1$s. Razón: %2$s</string>
+    <string name="notice_room_unban_with_reason">%1$s ha desbaneado a %2$s. Razón: %3$s</string>
+    <string name="notice_room_third_party_invite_with_reason">%1$s envió una invitación a %2$s para que se una a la sala. Razón: %3$s</string>
+    <string name="notice_room_third_party_revoked_invite_with_reason">%1$s revocó la invitación de %2$s para unirse a la sala. Razón: %3$s</string>
+    <string name="notice_room_withdraw_with_reason">%1$s ha retirado la invitación de %2$s. Razón: %3$s</string>
+
+    <plurals name="notice_room_aliases_added">
+        <item quantity="one">%1$s ha añadido %2$s como alias de esta sala.</item>
+        <item quantity="other">%1$s ha añadido %2$s como alias de esta sala.</item>
+    </plurals>
+
+    <plurals name="notice_room_aliases_removed">
+        <item quantity="one">%1$s ha quitado %2$s como alias de esta habitación.</item>
+        <item quantity="other">%1$s ha quitado %2$s como alias de esta habitación.</item>
+    </plurals>
+
+    <string name="notice_room_canonical_alias_set">%1$s ha establecido la dirección principal de esta sala a %2$s.</string>
+    <string name="notice_room_guest_access_can_join">%1$s ha permitido que los invitados se unan a la sala.</string>
+    <string name="notice_room_guest_access_forbidden">%1$s ha impedido que los invitados se unan a la sala.</string>
+
+    <string name="notice_end_to_end_ok">%1$s ha activado la encriptación extremo a extremo.</string>
+    <string name="notice_end_to_end_unknown_algorithm">%1$s ha activado la encriptación de extremo a extremo (algoritmo no reconocido %2$s).</string>
+
+    <string name="key_verification_request_fallback_message">%s solicita verificar su clave, pero su cliente no soporta la verificación de la clave en chat. Necesitará usar la verificación de claves clásica para poder verificar las claves.</string>
+
 </resources>
diff --git a/matrix-sdk-android/src/main/res/values-eu/strings.xml b/matrix-sdk-android/src/main/res/values-eu/strings.xml
index 08b9b28332..4b2cc183a0 100644
--- a/matrix-sdk-android/src/main/res/values-eu/strings.xml
+++ b/matrix-sdk-android/src/main/res/values-eu/strings.xml
@@ -202,4 +202,12 @@
     <string name="notice_room_canonical_alias_set">%1$s erabiltzaileak %2$s ezarri du gela honen helbide nagusi gisa.</string>
     <string name="notice_room_canonical_alias_unset">%1$s erabiltzaileak gela honen helbide nagusia kendu du.</string>
 
+    <string name="notice_room_guest_access_can_join">%1$k gonbidatuak gelara sartzea onartu du.</string>
+    <string name="notice_room_guest_access_forbidden">%1%k gonbidatuak gelara sartzea galerazi du.</string>
+
+    <string name="notice_end_to_end_ok">%1$s erabiltzaileak muturretik muturrerako zifratzea gaitu du.</string>
+    <string name="notice_end_to_end_unknown_algorithm">%1$s erabiltzaileak muturretik muturrerako zifratzea gaitu du. (%2$s algoritmo ezezaguna).</string>
+
+    <string name="key_verification_request_fallback_message">%s(e)k zure gakoa egiaztatzea eskatu du, baina zure bezeroak ez du txatean gakoa egiaztatzea onartzen. Gako egiaztaketa zaharra erabili beharko duzu.</string>
+
 </resources>
diff --git a/matrix-sdk-android/src/main/res/values-fa/strings.xml b/matrix-sdk-android/src/main/res/values-fa/strings.xml
new file mode 100644
index 0000000000..eced727ce4
--- /dev/null
+++ b/matrix-sdk-android/src/main/res/values-fa/strings.xml
@@ -0,0 +1,210 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<resources>
+    <string name="summary_message">%1$s: %2$s</string>
+    <string name="summary_user_sent_image">%1$s تصویری فرستاد.</string>
+    <string name="summary_user_sent_sticker">%1$s برچسبی فرستاد.</string>
+
+    <string name="notice_room_invite_no_invitee">دعوت %s</string>
+    <string name="notice_room_invite">‫%1$s، %2$s را دعوت کرد</string>
+    <string name="notice_room_invite_you">%1$s دعوتتان کرد</string>
+    <string name="notice_room_join">%1$s پیوست</string>
+    <string name="notice_room_leave">%1$s رفت</string>
+    <string name="notice_room_reject">%1$s دعوت را رد کرد</string>
+    <string name="notice_room_kick">%1$s، %2$s را اخراج کرد</string>
+    <string name="notice_room_unban">%1$s، انسداد %2$s را رفع کرد</string>
+    <string name="notice_room_ban">%1$s، %2$s را مسدود کرد</string>
+    <string name="notice_room_withdraw">%1$s دعوت %2$s را نپذیرفت</string>
+    <string name="notice_avatar_url_changed">%1$s تصویرش را عوض کرد</string>
+    <string name="notice_display_name_set">%1$s نام نمایشیش را به %2$s تنظیم کرد</string>
+    <string name="notice_display_name_changed_from">%1$s نام نمایشیش را از %2$s به %3$s تغییر داد</string>
+    <string name="notice_display_name_removed">%1$s نام نمایشیش (%2$s) را برداشت</string>
+    <string name="notice_room_topic_changed">%1$s موضوع را به %2$s تغییر داد</string>
+    <string name="notice_room_name_changed">%1$s نام اتاق را به %2$s تغییر داد</string>
+    <string name="notice_placed_video_call">%s یک تماس تصویری برقرار کرد.</string>
+    <string name="notice_placed_voice_call">%s یک تماس صوتی برقرار کرد.</string>
+    <string name="notice_answered_call">%s تماس را پاسخ داد.</string>
+    <string name="notice_ended_call">%s به تماس پایان داد.</string>
+    <string name="notice_made_future_room_visibility">%1$s تاریخچهٔ آیندهٔ اتاق را برای %2$s نمایان کرد</string>
+    <string name="notice_room_visibility_invited">همهٔ اعضای اتاق، از زمان دعوت شدنشان.</string>
+    <string name="notice_room_visibility_joined">همهٔ اعضای اتاق، از زمان پیوستنشان.</string>
+    <string name="notice_room_visibility_shared">همهٔ اعضای اتاق.</string>
+    <string name="notice_room_visibility_world_readable">هرکسی.</string>
+    <string name="notice_room_visibility_unknown">ناشناخته (%s).</string>
+    <string name="notice_end_to_end">%1$s رمزنگاری سرتاسری را روشن کرد (%2$s)</string>
+    <string name="notice_room_update">%s این اتاق را ارتقا داد.</string>
+
+    <string name="notice_requested_voip_conference">%1$s درخواست یک گردهمایی صوتی داد</string>
+    <string name="notice_voip_started">گردهمایی صوتی آغاز شد</string>
+    <string name="notice_voip_finished">گردهمایی صوتی پایان یافت</string>
+
+    <string name="notice_avatar_changed_too">(تصویر هم عوض شد)</string>
+    <string name="notice_room_name_removed">%1$s نام اتاق را برداشت</string>
+    <string name="notice_room_topic_removed">%1$s موضوع اتاق را برداشت</string>
+    <string name="notice_event_redacted">پیام برداشته شد</string>
+    <string name="notice_event_redacted_by">پیام به دست %1$s برداشته شد</string>
+    <string name="notice_event_redacted_with_reason">پیام برداشته شد [دلیل: %1$s]</string>
+    <string name="notice_event_redacted_by_with_reason">پیام به دست %1$s برداشته شد [دلیل: %2$s]</string>
+    <string name="notice_room_third_party_invite">%1$s دعوتی برای پیوستن %2$s به اتاق فرستاد</string>
+    <string name="notice_room_third_party_revoked_invite">%1$s دعوت پیوستن به اتاق %2$s را باطل کرد</string>
+    <string name="notice_room_third_party_registered_invite">%1$s دعوت برای %2$s را پذیرفت</string>
+
+    <string name="notice_crypto_unable_to_decrypt">** ناتوان در رمزگشایی: %s **</string>
+    <string name="notice_crypto_error_unkwown_inbound_session_id">افزارهٔ فرستنده، کلیدهای این پیام را برایمان نفرستاده است.</string>
+
+    <string name="message_reply_to_prefix">در پاسخ به</string>
+
+    <string name="unable_to_send_message">ناتوان در فرستادن پیام</string>
+
+    <string name="message_failed_to_upload">شکست در بارگذاری تصویر</string>
+
+    <string name="network_error">خطای شبکه</string>
+    <string name="matrix_error">خطای ماتریس</string>
+
+    <string name="room_error_join_failed_empty_room">در حال حاضر امکان بازپیوست به اتاقی خالی وجود ندارد‌‌.</string>
+
+    <string name="encrypted_message">پیام رمزنگاشته</string>
+
+    <string name="medium_email">نشانی رایانامه</string>
+    <string name="medium_phone_number">شماره تلفن</string>
+
+    <string name="reply_to_an_image">تصویری فرستاد.</string>
+    <string name="reply_to_a_video">ویدیویی فرستاد.</string>
+    <string name="reply_to_an_audio_file">پرونده‌ای صوتی فرستاد.</string>
+    <string name="reply_to_a_file">پرونده‌ای فرستاد.</string>
+
+    <string name="room_displayname_invite_from">دعوت از %s</string>
+    <string name="room_displayname_room_invite">دعوت اتاق</string>
+
+    <string name="room_displayname_two_members">%1$s و %2$s</string>
+
+    <plurals name="room_displayname_three_and_more_members">
+        <item quantity="one">%1$s و ۱ نفر دیگر</item>
+        <item quantity="other">%1$s و %2$d نفر دیگر</item>
+    </plurals>
+
+    <string name="room_displayname_empty_room">اتاق خالی</string>
+
+
+    <string name="verification_emoji_dog">سگ</string>
+    <string name="verification_emoji_cat">گربه</string>
+    <string name="verification_emoji_lion">شیر</string>
+    <string name="verification_emoji_horse">اسب</string>
+    <string name="verification_emoji_unicorn">تک‌شاخ</string>
+    <string name="verification_emoji_pig">خوک</string>
+    <string name="verification_emoji_elephant">فیل</string>
+    <string name="verification_emoji_rabbit">خرگوش</string>
+    <string name="verification_emoji_panda">پاندا</string>
+    <string name="verification_emoji_rooster">خروس</string>
+    <string name="verification_emoji_penguin">پنگوئن</string>
+    <string name="verification_emoji_turtle">لاک‌پشت</string>
+    <string name="verification_emoji_fish">ماهی</string>
+    <string name="verification_emoji_octopus">هشت‌پا</string>
+    <string name="verification_emoji_butterfly">پروانه</string>
+    <string name="verification_emoji_flower">گل</string>
+    <string name="verification_emoji_tree">درخت</string>
+    <string name="verification_emoji_cactus">کاکتوس</string>
+    <string name="verification_emoji_mushroom">قارچ</string>
+    <string name="verification_emoji_globe">جهان</string>
+    <string name="verification_emoji_moon">ماه</string>
+    <string name="verification_emoji_cloud">ابر</string>
+    <string name="verification_emoji_fire">آتش</string>
+    <string name="verification_emoji_banana">موز</string>
+    <string name="verification_emoji_apple">سیب</string>
+    <string name="verification_emoji_strawberry">توت‌فرنگی</string>
+    <string name="verification_emoji_corn">بلال</string>
+    <string name="verification_emoji_pizza">پیتزا</string>
+    <string name="verification_emoji_cake">کیک</string>
+    <string name="verification_emoji_heart">قلب</string>
+    <string name="verification_emoji_smiley">لبخندک</string>
+    <string name="verification_emoji_robot">آدم‌آهنی</string>
+    <string name="verification_emoji_hat">کلاه</string>
+    <string name="verification_emoji_glasses">عینک</string>
+    <string name="verification_emoji_wrench">آچار</string>
+    <string name="verification_emoji_santa">بابانوئل</string>
+    <string name="verification_emoji_thumbsup">شست</string>
+    <string name="verification_emoji_umbrella">چتر</string>
+    <string name="verification_emoji_hourglass">ساعت شنی</string>
+    <string name="verification_emoji_clock">ساعت</string>
+    <string name="verification_emoji_gift">هدیه</string>
+    <string name="verification_emoji_lightbulb">حباب لامپ</string>
+    <string name="verification_emoji_book">کتاب</string>
+    <string name="verification_emoji_pencil">مداد</string>
+    <string name="verification_emoji_paperclip">گیره کاغذ</string>
+    <string name="verification_emoji_scissors">قیچی</string>
+    <string name="verification_emoji_lock">قفل</string>
+    <string name="verification_emoji_key">کلید</string>
+    <string name="verification_emoji_hammer">چکّش</string>
+    <string name="verification_emoji_telephone">تلفن</string>
+    <string name="verification_emoji_flag">پرچم</string>
+    <string name="verification_emoji_train">قطار</string>
+    <string name="verification_emoji_bicycle">دوچرخه</string>
+    <string name="verification_emoji_airplane">هواپیما</string>
+    <string name="verification_emoji_rocket">موشک</string>
+    <string name="verification_emoji_trophy">جام</string>
+    <string name="verification_emoji_ball">توپ</string>
+    <string name="verification_emoji_guitar">گیتار</string>
+    <string name="verification_emoji_trumpet">ترومپت</string>
+    <string name="verification_emoji_bell">زنگ</string>
+    <string name="verification_emoji_anchor">لنگر</string>
+    <string name="verification_emoji_headphone">هدفون</string>
+    <string name="verification_emoji_folder">پوشه</string>
+    <string name="verification_emoji_pin">پونز</string>
+
+    <string name="initial_sync_start_importing_account">همگام‌سازی نخستین:
+\nدر حال درون‌ریزی حساب…</string>
+    <string name="initial_sync_start_importing_account_crypto">همگام‌سازی نخستین:
+\nدر حال درون‌ریزی رمزنگاری</string>
+    <string name="initial_sync_start_importing_account_rooms">همگام‌سازی نخستین:
+\nدر حال درون‌ریزی اتاق‌ها</string>
+    <string name="initial_sync_start_importing_account_joined_rooms">همگام‌سازی نخستین:
+\nدر حال درون‌ریزی اتاق‌های پیوسته</string>
+    <string name="initial_sync_start_importing_account_invited_rooms">همگام‌سازی نخستین:
+\nدر حال درون‌ریزی اتاق‌های دعوت‌شده</string>
+    <string name="initial_sync_start_importing_account_left_rooms">همگام‌سازی نخستین:
+\nدر حال درون‌ریزی اتاق‌های ترک‌شده</string>
+    <string name="initial_sync_start_importing_account_groups">همگام‌سازی نخستین:
+\nدر حال درون‌ریزی اجتماع‌ها</string>
+    <string name="initial_sync_start_importing_account_data">همگام‌سازی نخستین:
+\nدر حال درون‌ریزی داده‌های حساب</string>
+
+    <string name="event_status_sending_message">در حال فرستادن پیام…</string>
+    <string name="clear_timeline_send_queue">پاک‌سازی صفِ در حال فرستادن</string>
+
+    <string name="notice_room_invite_no_invitee_with_reason">دعوت %1$s. دلیل: %2$s</string>
+    <string name="notice_room_invite_with_reason">%1$s، %2$s را دعوت کرد. دلیل: %3$s</string>
+    <string name="notice_room_invite_you_with_reason">%1$s دعوتتان کرد. دلیل: %2$s</string>
+    <string name="notice_room_join_with_reason">%1$s پیوست. دلیل: %2$s</string>
+    <string name="notice_room_leave_with_reason">%1$s رفت. دلیل: %2$s</string>
+    <string name="notice_room_reject_with_reason">%1$s دعوت را رد کرد. دلیل: %2$s</string>
+    <string name="notice_room_kick_with_reason">%1$s، %2$s را اخراج کرد. دلیل: %3$s</string>
+    <string name="notice_room_unban_with_reason">%1$s انسداد %2$s را رفع کرد. دلیل: %3$s</string>
+    <string name="notice_room_ban_with_reason">%1$s، %2$s را مسدود کرد. دلیل: %3$s</string>
+    <string name="notice_room_third_party_invite_with_reason">%1$s دعوتی برای پیوستن %2$s به اتاق فرستاد. دلیل: %3$s</string>
+    <string name="notice_room_third_party_revoked_invite_with_reason">%1$s دعوت %2$s برای پیوستن به اتاق را باطل کرد. دلیل: %3$s</string>
+    <string name="notice_room_third_party_registered_invite_with_reason">%1$s دعوت برای %2$s را پذیرفت. دلیل: %3$s</string>
+    <string name="notice_room_withdraw_with_reason">%1$s دعوت %2$s را نپذیرفت. دلیل: %3$s</string>
+
+    <plurals name="notice_room_aliases_added">
+        <item quantity="one">%1$s، %2$s را به عنوان نشانی‌ای برای این اتاق افزود.</item>
+        <item quantity="other">%1$s، %2$s را به عنوان نشانی‌هایی برای این اتاق افزود.</item>
+    </plurals>
+
+    <plurals name="notice_room_aliases_removed">
+        <item quantity="one">%1$s، %2$s را به عنوان نشانی‌ای برای این اتاق برداشت.</item>
+        <item quantity="other">%1$s، %3$s را به عنوان نشانی‌هایی برای این اتاق برداشت.</item>
+    </plurals>
+
+    <string name="notice_room_aliases_added_and_removed">%1$s برای نشانی این اتاق، %2$s را افزود و %3$s را برداشت.</string>
+
+    <string name="notice_room_canonical_alias_set">%1$s نشانی اصلی این اتاق را به %2$s تنظیم کرد.</string>
+    <string name="notice_room_canonical_alias_unset">%1$s نشانی اصلی را برای این اتاق برداشت.</string>
+
+    <string name="notice_room_guest_access_can_join">%1$s اجازه داد میمهانان به گروه بپیوندند.</string>
+    <string name="notice_room_guest_access_forbidden">%1$s جلوی پیوستن میمهانان به گروه را گرفت.</string>
+
+    <string name="notice_end_to_end_ok">%1$s رمزنگاری سرتاسری را روشن کرد.</string>
+    <string name="notice_end_to_end_unknown_algorithm">%1$s رمزنگاری سرتاسری را روشن کرد (الگوریتم تشخیص‌داده‌نشده %2$s ).</string>
+
+    <string name="key_verification_request_fallback_message">%s درخواست تأیید کلیدتان را دارد، ولی کارخواهتان تأیید کلید درون گپ را پشتیبانی نمی‌کند. برای تأیید کلیدها لازم است از تأییدیهٔ کلید قدیمی استفاده کنید.</string>
+
+</resources>
diff --git a/matrix-sdk-android/src/main/res/values-fi/strings.xml b/matrix-sdk-android/src/main/res/values-fi/strings.xml
index b101b91736..9487aa7db4 100644
--- a/matrix-sdk-android/src/main/res/values-fi/strings.xml
+++ b/matrix-sdk-android/src/main/res/values-fi/strings.xml
@@ -5,18 +5,18 @@
     <string name="notice_room_invite_no_invitee">Käyttäjän %s kutsu</string>
     <string name="notice_room_invite">%1$s kutsui käyttäjän %2$s</string>
     <string name="notice_room_invite_you">%1$s kutsui sinut</string>
-    <string name="notice_room_join">%1$s liittyi</string>
-    <string name="notice_room_leave">%1$s poistui</string>
+    <string name="notice_room_join">%1$s liittyi huoneeseen</string>
+    <string name="notice_room_leave">%1$s poistui huoneesta</string>
     <string name="notice_room_reject">%1$s hylkäsi kutsun</string>
     <string name="notice_room_kick">%1$s poisti käyttäjän %2$s</string>
     <string name="notice_room_unban">%1$s poisti porttikiellon käyttäjältä %2$s</string>
     <string name="notice_room_ban">%1$s antoi porttikiellon käyttäjälle %2$s</string>
     <string name="notice_room_withdraw">%1$s veti takaisin kutsun käyttäjälle %2$s</string>
-    <string name="notice_avatar_url_changed">%1$s vaihtoi profiilikuvaa</string>
+    <string name="notice_avatar_url_changed">%1$s vaihtoi profiilikuvaansa</string>
     <string name="notice_display_name_set">%1$s asetti näyttönimekseen %2$s</string>
     <string name="notice_display_name_changed_from">%1$s muutti näyttönimensä nimestä %2$s nimeen %3$s</string>
     <string name="notice_display_name_removed">%1$s poisti näyttönimensä (%2$s)</string>
-    <string name="notice_room_topic_changed">%1$s vaihtoi aiheeksi %2$s</string>
+    <string name="notice_room_topic_changed">%1$s vaihtoi aiheeksi: %2$s</string>
     <string name="notice_room_name_changed">%1$s vaihtoi huoneen nimeksi %2$s</string>
     <string name="notice_placed_video_call">%s soitti videopuhelun.</string>
     <string name="notice_placed_voice_call">%s soitti äänipuhelun.</string>
@@ -38,7 +38,7 @@
     <string name="notice_room_name_removed">%1$s poisti huoneen nimen</string>
     <string name="notice_room_topic_removed">%1$s poisti huoneen aiheen</string>
     <string name="notice_profile_change_redacted">%1$s päivitti profiilinsa %2$s</string>
-    <string name="notice_room_third_party_invite">%1$s lähetti liittymiskutsun käyttäjälle %2$s</string>
+    <string name="notice_room_third_party_invite">%1$s lähetti liittymiskutsun huoneeseen käyttäjälle %2$s</string>
     <string name="notice_room_third_party_registered_invite">%1$s hyväksyi kutsun käyttäjän %2$s puolesta</string>
     <string name="notice_crypto_unable_to_decrypt">** Salauksen purku epäonnistui: %s **</string>
     <string name="notice_crypto_error_unkwown_inbound_session_id">Lähettäjän laite ei ole lähettänyt avaimia tähän viestiin.</string>
@@ -177,15 +177,36 @@
     <string name="notice_room_invite_no_invitee_with_reason">Henkilön %1$s kutsu. Syy: %2$s</string>
     <string name="notice_room_invite_with_reason">%1$s kutsui henkilön %2$s. Syy: %3$s</string>
     <string name="notice_room_invite_you_with_reason">%1$s kutsui sinut. Syy: %2$s</string>
-    <string name="notice_room_join_with_reason">%1$s liittyi. Syy: %2$s</string>
-    <string name="notice_room_leave_with_reason">%1$s poistui. Syy: %2$s</string>
+    <string name="notice_room_join_with_reason">%1$s liittyi huoneeseen. Syy: %2$s</string>
+    <string name="notice_room_leave_with_reason">%1$s poistui huoneesta. Syy: %2$s</string>
     <string name="notice_room_reject_with_reason">%1$s hylkäsi kutsun. Syy: %2$s</string>
-    <string name="notice_room_kick_with_reason">%1$s potkaisi käyttäjän %2$s pois. Syy: %3$s</string>
-    <string name="notice_room_unban_with_reason">%1$s poisti eston käyttäjältä %2$s. Syy: %3$s</string>
-    <string name="notice_room_ban_with_reason">%1$s esti käyttäjän %2$s. Syy: %3$s</string>
-    <string name="notice_room_third_party_invite_with_reason">%1$s lähetti kutsun käyttäjälle %2$s huoneeseen liittymiseksi. Syy: %3$s</string>
-    <string name="notice_room_third_party_revoked_invite_with_reason">%1$s kumosi kutsun käyttäjälle %2$s huoneeseen liittymiseksi. Syy: %3$s</string>
+    <string name="notice_room_kick_with_reason">%1$s poisti käyttäjän %2$s huoneesta. Syy: %3$s</string>
+    <string name="notice_room_unban_with_reason">%1$s poisti porttikiellon käyttäjältä %2$s. Syy: %3$s</string>
+    <string name="notice_room_ban_with_reason">%1$s antoi porttikiellon käyttäjälle %2$s. Syy: %3$s</string>
+    <string name="notice_room_third_party_invite_with_reason">%1$s lähetti kutsun liittyä huoneeseen käyttäjälle %2$s. Syy: %3$s</string>
+    <string name="notice_room_third_party_revoked_invite_with_reason">%1$s kumosi kutsun liittyä huoneeseen käyttäjälle %2$s. Syy: %3$s</string>
     <string name="notice_room_third_party_registered_invite_with_reason">%1$s hyväksyi kutsun liityäkseen huoneeseen %2$s. Syy: %3$s</string>
-    <string name="notice_room_withdraw_with_reason">%1$s poisti käyttäjän %2$s kutsun. Syy: %3$s</string>
+    <string name="notice_room_withdraw_with_reason">%1$s veti takaisin käyttäjän %2$s kutsun. Syy: %3$s</string>
+
+    <plurals name="notice_room_aliases_added">
+        <item quantity="one">%1$s lisäsi tälle huoneelle osoitteen %2$s.</item>
+        <item quantity="other">%1$s lisäsi tälle huoneelle osoitteet %2$s.</item>
+    </plurals>
+
+    <plurals name="notice_room_aliases_removed">
+        <item quantity="one">%1$s poisti tältä huoneelta osoitteen %2$s.</item>
+        <item quantity="other">%1$s poisti tältä huoneelta osoitteet %3$s.</item>
+    </plurals>
+
+    <string name="notice_room_aliases_added_and_removed">%1$s lisäsi tälle huoneelle osoitteen %2$s ja poisti osoitteen %3$s.</string>
+
+    <string name="notice_room_canonical_alias_set">%1$s asetti tämän huoneen pääosoitteeksi %2$s.</string>
+    <string name="notice_room_canonical_alias_unset">%1$s poisti tämän huoneen pääosoitteen.</string>
+
+    <string name="notice_room_guest_access_can_join">%1$s salli vieraiden liittyä huoneeseen.</string>
+    <string name="notice_room_guest_access_forbidden">%1$s esti vieraita liittymästä huoneeseen.</string>
+
+    <string name="notice_end_to_end_ok">%1$s laittoi päälle osapuolten välisen salauksen.</string>
+    <string name="notice_end_to_end_unknown_algorithm">%1$s laittoi päälle osapuolisten välisen salauksen (tuntematon algoritmi %2$s).</string>
 
 </resources>
diff --git a/matrix-sdk-android/src/main/res/values-fr/strings.xml b/matrix-sdk-android/src/main/res/values-fr/strings.xml
index 73341fe57b..ce50359c52 100644
--- a/matrix-sdk-android/src/main/res/values-fr/strings.xml
+++ b/matrix-sdk-android/src/main/res/values-fr/strings.xml
@@ -7,8 +7,8 @@
     <string name="notice_room_invite_no_invitee">invitation de %s</string>
     <string name="notice_room_invite">%1$s a invité %2$s</string>
     <string name="notice_room_invite_you">%1$s vous a invité</string>
-    <string name="notice_room_join">%1$s a rejoint la discussion</string>
-    <string name="notice_room_leave">%1$s est parti</string>
+    <string name="notice_room_join">%1$s a rejoint le salon</string>
+    <string name="notice_room_leave">%1$s est parti du salon</string>
     <string name="notice_room_reject">%1$s a rejeté l’invitation</string>
     <string name="notice_room_kick">%1$s a expulsé %2$s</string>
     <string name="notice_room_unban">%1$s a révoqué le bannissement de %2$s</string>
@@ -177,7 +177,7 @@
     <string name="notice_room_invite_with_reason">%1$s a invité %2$s. Raison : %3$s</string>
     <string name="notice_room_invite_you_with_reason">%1$s vous a invité. Raison : %2$s</string>
     <string name="notice_room_join_with_reason">%1$s a rejoint le salon. Raison : %2$s</string>
-    <string name="notice_room_leave_with_reason">%1$s est parti. Raison : %2$s</string>
+    <string name="notice_room_leave_with_reason">%1$s est parti du salon. Raison : %2$s</string>
     <string name="notice_room_reject_with_reason">%1$s a refusé l’invitation. Raison : %2$s</string>
     <string name="notice_room_kick_with_reason">%1$s a expulsé %2$s. Raison : %3$s</string>
     <string name="notice_room_unban_with_reason">%1$s a révoqué le bannissement de %2$s. Raison : %3$s</string>
@@ -202,4 +202,12 @@
     <string name="notice_room_canonical_alias_set">%1$s a défini %2$s comme adresse principale pour ce salon.</string>
     <string name="notice_room_canonical_alias_unset">%1$s a supprimé l’adresse principale de ce salon.</string>
 
+    <string name="notice_room_guest_access_can_join">%1$s a autorisé les visiteurs à rejoindre le salon.</string>
+    <string name="notice_room_guest_access_forbidden">%1$s a empêché les visiteurs de rejoindre le salon.</string>
+
+    <string name="notice_end_to_end_ok">%1$s a activé le chiffrement de bout en bout.</string>
+    <string name="notice_end_to_end_unknown_algorithm">%1$s a activé le chiffrement de bout en bout (algorithme %2$s inconnu).</string>
+
+    <string name="key_verification_request_fallback_message">%s demande à vérifier votre clé, mais votre client ne supporte pas la vérification de clés dans les discussions. Vous devrez utiliser l’ancienne vérification de clés pour vérifier les clés.</string>
+
 </resources>
diff --git a/matrix-sdk-android/src/main/res/values-hu/strings.xml b/matrix-sdk-android/src/main/res/values-hu/strings.xml
index 1367b8bf43..a83ea5058b 100644
--- a/matrix-sdk-android/src/main/res/values-hu/strings.xml
+++ b/matrix-sdk-android/src/main/res/values-hu/strings.xml
@@ -4,72 +4,72 @@
     <string name="summary_user_sent_image">%1$s küldött egy képet.</string>
 
     <string name="notice_room_invite_no_invitee">%s meghívója</string>
-    <string name="notice_room_invite">%1$s meghívta %2$s -t</string>
+    <string name="notice_room_invite">%1$s meghívta: %2$s</string>
     <string name="notice_room_invite_you">%1$s meghívott</string>
-    <string name="notice_room_join">%1$s csatlakozott</string>
-    <string name="notice_room_leave">%1$s kilépett</string>
+    <string name="notice_room_join">%1$s belépett a szobába</string>
+    <string name="notice_room_leave">%1$s kilépett a szobából</string>
     <string name="notice_room_reject">%1$s elutasította a meghívást</string>
-    <string name="notice_room_kick">%1$s kidobta %2$s -t</string>
-    <string name="notice_room_unban">%1$s feloldotta tiltását %2$s -nak/nek</string>
-    <string name="notice_room_ban">%1$s kitiltotta %2$s -t</string>
-    <string name="notice_room_withdraw">%1$s visszavonta %2$s\'s meghívását</string>
-    <string name="notice_avatar_url_changed">%1$s megváltoztatták a felhasználó képüket</string>
-    <string name="notice_display_name_set">%1$s megváltoztatták a megjelenő nevüket erre: %2$s</string>
-    <string name="notice_display_name_changed_from">%1$s megváltoztatták a megjelenő nevüket erről %2$s erre %3$s</string>
-    <string name="notice_display_name_removed">%1$s eltávolították a megjelenő nevüket (%2$s)</string>
+    <string name="notice_room_kick">%1$s kidobta: %2$s</string>
+    <string name="notice_room_unban">%1$s feloldotta %2$s tiltását</string>
+    <string name="notice_room_ban">%1$s kitiltotta: %2$s</string>
+    <string name="notice_room_withdraw">%1$s visszavonta %2$s meghívását</string>
+    <string name="notice_avatar_url_changed">%1$s megváltoztatta a profilképét</string>
+    <string name="notice_display_name_set">%1$s megváltoztatta a megjelenő nevét erre: %2$s</string>
+    <string name="notice_display_name_changed_from">%1$s megváltoztatta a megjelenítendő nevét erről: %2$s, erre: %3$s</string>
+    <string name="notice_display_name_removed">%1$s eltávolította a megjelenítendő nevét (%2$s)</string>
     <string name="notice_room_topic_changed">%1$s megváltoztatta a témát erre: %2$s</string>
     <string name="notice_room_name_changed">%1$s megváltoztatta a szoba nevét erre: %2$s</string>
     <string name="notice_placed_video_call">%s videóhívást kezdeményezett.</string>
     <string name="notice_placed_voice_call">%s hanghívást kezdeményezett.</string>
-    <string name="notice_answered_call">%s elfogadta a hívást.</string>
+    <string name="notice_answered_call">%s fogadta a hívást.</string>
     <string name="notice_ended_call">%s befejezte a hívást.</string>
     <string name="notice_made_future_room_visibility">%1$s láthatóvá tette a jövőbeli előzményeket %2$s számára</string>
-    <string name="notice_room_visibility_invited">az összes szoba tag, onnantól, hogy meg lettek hívva.</string>
-    <string name="notice_room_visibility_joined">az összes szoba tag, onnantól, hogy csatlakoztak.</string>
-    <string name="notice_room_visibility_shared">az összes szoba tag.</string>
+    <string name="notice_room_visibility_invited">az összes szobatag, onnantól, hogy meg lettek hívva.</string>
+    <string name="notice_room_visibility_joined">az összes szobatag, onnantól, hogy csatlakoztak.</string>
+    <string name="notice_room_visibility_shared">az összes szobatag.</string>
     <string name="notice_room_visibility_world_readable">bárki.</string>
     <string name="notice_room_visibility_unknown">ismeretlen (%s).</string>
-    <string name="notice_end_to_end">%1$s bekapcsolta a végtől végig titkosítást (%2$s)</string>
+    <string name="notice_end_to_end">%1$s bekapcsolta a végpontok közötti titkosítást (%2$s)</string>
 
     <string name="notice_requested_voip_conference">%1$s hanghívás konferenciát kérelmezett</string>
     <string name="notice_voip_started">Hanghívás konferencia elindult</string>
     <string name="notice_voip_finished">Hanghívás konferencia befejeződött</string>
 
-    <string name="notice_avatar_changed_too">(profilképp is meg lett változtatva)</string>
+    <string name="notice_avatar_changed_too">(a profilkép is megváltozott)</string>
     <string name="notice_room_name_removed">%1$s eltávolította a szoba nevét</string>
     <string name="notice_room_topic_removed">%1$s eltávolította a szoba témáját</string>
-    <string name="notice_profile_change_redacted">%1$s megváltoztatták a profiljukat %2$s</string>
-    <string name="notice_room_third_party_invite">"%1$s meghívót küldött %2$s -nak/-nek  hogy csatlakozzon a szobához"</string>
-    <string name="notice_room_third_party_registered_invite">%1$s elfogadta a meghívót a %2$s -hoz</string>
+    <string name="notice_profile_change_redacted">%1$s megváltoztatta a(z) %2$s profilját</string>
+    <string name="notice_room_third_party_invite">%1$s meghívót küldött %2$s számára, hogy csatlakozzon a szobához</string>
+    <string name="notice_room_third_party_registered_invite">%1$s elfogadta a meghívót ebbe: %2$s</string>
 
     <string name="notice_crypto_unable_to_decrypt">** Visszafejtés sikertelen: %s **</string>
     <string name="notice_crypto_error_unkwown_inbound_session_id">A küldő eszköze nem küldte el a kulcsokat ehhez az üzenethez.</string>
 
-    <string name="could_not_redact">Szerkesztés sikertelen</string>
+    <string name="could_not_redact">Kitakarás sikertelen</string>
     <string name="unable_to_send_message">Üzenet küldése sikertelen</string>
 
     <string name="message_failed_to_upload">Kép feltöltése sikertelen</string>
 
-    <string name="network_error">Hálózat hiba</string>
+    <string name="network_error">Hálózati hiba</string>
     <string name="matrix_error">Matrix hiba</string>
 
-    <string name="room_error_join_failed_empty_room">Jelenleg nem lehetséges újracsatlakozni egy üres szobába.</string>
+    <string name="room_error_join_failed_empty_room">Jelenleg nem lehetséges újracsatlakozni egy üres szobához.</string>
 
     <string name="encrypted_message">Titkosított üzenet</string>
 
-    <string name="medium_email">Email cím</string>
+    <string name="medium_email">E-mail cím</string>
     <string name="medium_phone_number">Telefonszám</string>
 
     <string name="summary_user_sent_sticker">%1$s küldött egy matricát.</string>
 
     <string name="message_reply_to_prefix">Válasz erre:</string>
 
-    <string name="reply_to_an_image">kép elküldve.</string>
-    <string name="reply_to_a_video">videó elküldve.</string>
-    <string name="reply_to_an_audio_file">hangfájl elküldve.</string>
-    <string name="reply_to_a_file">fájl elküldve.</string>
+    <string name="reply_to_an_image">képet küldött.</string>
+    <string name="reply_to_a_video">videót küldött.</string>
+    <string name="reply_to_an_audio_file">hangfájlt küldött.</string>
+    <string name="reply_to_a_file">fájlt küldött.</string>
 
-    <string name="room_displayname_invite_from">%s meghívott</string>
+    <string name="room_displayname_invite_from">Meghívó tőle: %s</string>
     <string name="room_displayname_room_invite">Meghívó egy szobába</string>
     <string name="room_displayname_two_members">%1$s és %2$s</string>
     <string name="room_displayname_empty_room">Üres szoba</string>
@@ -171,12 +171,12 @@
     <string name="event_status_sending_message">Üzenet küldése…</string>
     <string name="clear_timeline_send_queue">Küldő sor ürítése</string>
 
-    <string name="notice_room_third_party_revoked_invite">%1$s visszavonta a meghívót a belépéshez ebbe a szobába: %2$s</string>
+    <string name="notice_room_third_party_revoked_invite">%1$s visszavonta %2$s meghívását, hogy csatlakozzon a szobához</string>
     <string name="notice_room_invite_no_invitee_with_reason">%1$s meghívója. Ok: %2$s</string>
     <string name="notice_room_invite_with_reason">%1$s meghívta őt: %2$s. Ok: %3$s</string>
     <string name="notice_room_invite_you_with_reason">%1$s meghívott. Ok: %2$s</string>
-    <string name="notice_room_join_with_reason">%1$s csatlakozott. Ok: %2$s</string>
-    <string name="notice_room_leave_with_reason">%1$s kilépett. Ok: %2$s</string>
+    <string name="notice_room_join_with_reason">%1$s belépett a szobába. Mert: %2$s</string>
+    <string name="notice_room_leave_with_reason">%1$s kilépett a szobából. Ok: %2$s</string>
     <string name="notice_room_reject_with_reason">%1$s visszautasította a meghívót. Ok: %2$s</string>
     <string name="notice_room_kick_with_reason">%1$s kirúgta őt: %2$s. Ok: %3$s</string>
     <string name="notice_room_unban_with_reason">%1$s visszaengedte őt: %2$s. Ok: %3$s</string>
@@ -201,4 +201,12 @@
     <string name="notice_room_canonical_alias_set">%1$s a szoba elsődleges címét erre állította be: %2$s.</string>
     <string name="notice_room_canonical_alias_unset">%1$s eltávolította a szoba elsődleges címét.</string>
 
+    <string name="notice_room_guest_access_can_join">%1$s megengedte a vendégeknek, hogy belépjenek ebbe a szobába.</string>
+    <string name="notice_room_guest_access_forbidden">%1$s megtiltotta a vendégeknek, hogy belépjenek ebbe a szobába.</string>
+
+    <string name="notice_end_to_end_ok">%1$s bekapcsolta a végpontok közötti titkosítást.</string>
+    <string name="notice_end_to_end_unknown_algorithm">%1$s bekapcsolta a végpontok közötti titkosítást (ismeretlen algoritmus %2$s).</string>
+
+    <string name="key_verification_request_fallback_message">%s kéri a kulcsok ellenőrzését de a kliens nem támogatja a szobán belüli kulcs ellenőrzést. A hagyományos módon kell ellenőrizned a kulcsokat.</string>
+
 </resources>
diff --git a/matrix-sdk-android/src/main/res/values-it/strings.xml b/matrix-sdk-android/src/main/res/values-it/strings.xml
index 2d726272c0..9cbf1637c0 100644
--- a/matrix-sdk-android/src/main/res/values-it/strings.xml
+++ b/matrix-sdk-android/src/main/res/values-it/strings.xml
@@ -6,8 +6,8 @@
     <string name="notice_room_invite_no_invitee">Invito di %s</string>
     <string name="notice_room_invite">%1$s ha invitato %2$s</string>
     <string name="notice_room_invite_you">%1$s ti ha invitato</string>
-    <string name="notice_room_join">%1$s è entrato</string>
-    <string name="notice_room_leave">%1$s è uscito</string>
+    <string name="notice_room_join">%1$s è entrato nella stanza</string>
+    <string name="notice_room_leave">%1$s è uscito dalla stanza</string>
     <string name="notice_room_reject">%1$s ha rifiutato l\'invito</string>
     <string name="notice_room_kick">%1$s ha buttato fuori %2$s</string>
     <string name="notice_room_unban">%1$s ha tolto il bando a %2$s</string>
@@ -176,8 +176,8 @@
     <string name="notice_room_invite_no_invitee_with_reason">Invito di %1$s. Motivo: %2$s</string>
     <string name="notice_room_invite_with_reason">%1$s ha invitato %2$s. Motivo: %3$s</string>
     <string name="notice_room_invite_you_with_reason">%1$s ti ha invitato. Motivo: %2$s</string>
-    <string name="notice_room_join_with_reason">%1$s è entrato. Motivo: %2$s</string>
-    <string name="notice_room_leave_with_reason">%1$s è uscito. Motivo: %2$s</string>
+    <string name="notice_room_join_with_reason">%1$s è entrato nella stanza. Motivo: %2$s</string>
+    <string name="notice_room_leave_with_reason">%1$s è uscito dalla stanza. Motivo: %2$s</string>
     <string name="notice_room_reject_with_reason">%1$s ha rifiutato l\'invito. Motivo: %2$s</string>
     <string name="notice_room_kick_with_reason">%1$s ha buttato fuori %2$s. Motivo: %3$s</string>
     <string name="notice_room_unban_with_reason">%1$s ha riammesso %2$s. Motivo: %3$s</string>
@@ -202,4 +202,12 @@
     <string name="notice_room_canonical_alias_set">%1$s ha impostato l\'indirizzo principale per questa stanza a %2$s.</string>
     <string name="notice_room_canonical_alias_unset">%1$s ha rimosso l\'indirizzo principale per questa stanza.</string>
 
+    <string name="notice_room_guest_access_can_join">%1$s ha permesso l\'accesso alla stanza per gli ospiti.</string>
+    <string name="notice_room_guest_access_forbidden">%1$s ha impedito l\'accesso alla stanza per gli ospiti.</string>
+
+    <string name="notice_end_to_end_ok">%1$s ha attivato la cifratura end-to-end.</string>
+    <string name="notice_end_to_end_unknown_algorithm">%1$s ha attivato la cifratura end-to-end (algoritmo %2$s non riconosciuto).</string>
+
+    <string name="key_verification_request_fallback_message">%s sta chiedendo di verificare la tua chiave, ma il tuo client non supporta la verifica in-chat. Dovrai usare il metodo di verifica obsoleto per verificare le chiavi.</string>
+
 </resources>
diff --git a/matrix-sdk-android/src/main/res/values-nl/strings.xml b/matrix-sdk-android/src/main/res/values-nl/strings.xml
index 179ee89698..d08b3c7845 100644
--- a/matrix-sdk-android/src/main/res/values-nl/strings.xml
+++ b/matrix-sdk-android/src/main/res/values-nl/strings.xml
@@ -182,4 +182,41 @@
     <string name="clear_timeline_send_queue">Uitgaande wachtrij legen</string>
 
     <string name="notice_room_third_party_revoked_invite">%1$s heeft de uitnodiging voor %2$s om het gesprek toe te treden ingetrokken</string>
+    <string name="notice_room_invite_no_invitee_with_reason">Uitnodiging van %1$s. Reden: %2$s</string>
+    <string name="notice_room_invite_with_reason">%1$s heeft %2$s uitgenodigd. Reden: %3$s</string>
+    <string name="notice_room_invite_you_with_reason">%1$s heeft u uitgenodigd. Reden: %2$s</string>
+    <string name="notice_room_join_with_reason">%1$s neemt nu deel. Reden: %2$s</string>
+    <string name="notice_room_leave_with_reason">%1$s is weggegaan. Reden: %2$s</string>
+    <string name="notice_room_reject_with_reason">%1$s heeft de uitnodiging geweigerd. Reden: %2$s</string>
+    <string name="notice_room_kick_with_reason">%1$s heeft %2$s verwijderd. Reden: %3$s</string>
+    <string name="notice_room_unban_with_reason">%1$s heeft %2$s ontbannen. Reden: %3$s</string>
+    <string name="notice_room_ban_with_reason">%1$s heeft %2$s verbannen. Reden: %3$s</string>
+    <string name="notice_room_third_party_invite_with_reason">%1$s heeft %2$s een uitnodiging voor het gesprek gestuurd. Reden: %3$s</string>
+    <string name="notice_room_third_party_revoked_invite_with_reason">%1$s heeft de uitnodiging voor %2$s ingetrokken. Reden: %3$s</string>
+    <string name="notice_room_third_party_registered_invite_with_reason">%1$s heeft de uitnodiging voor %2$s aanvaard. Reden: %3$s</string>
+    <string name="notice_room_withdraw_with_reason">%1$s heeft de uitnodiging van %2$s ingetrokken. Reden: %3$s</string>
+
+    <plurals name="notice_room_aliases_added">
+        <item quantity="one">%1$s heeft %2$s als gespreksadres toegevoegd.</item>
+        <item quantity="other">%1$s heeft %2$s als gespreksadressen toegevoegd.</item>
+    </plurals>
+
+    <plurals name="notice_room_aliases_removed">
+        <item quantity="one">%1$s heeft %2$s als gespreksadres verwijderd.</item>
+        <item quantity="other">%1$s heeft %3$s als gespreksadressen verwijderd.</item>
+    </plurals>
+
+    <string name="notice_room_aliases_added_and_removed">%1$s heeft %2$s als gespreksadres toegevoegd en %3$s verwijderd.</string>
+
+    <string name="notice_room_canonical_alias_set">%1$s heeft het hoofdadres voor dit gesprek ingesteld op %2$s.</string>
+    <string name="notice_room_canonical_alias_unset">%1$s heeft het hoofdadres voor dit gesprek verwijderd.</string>
+
+    <string name="notice_room_guest_access_can_join">%1$s heeft gasten de toegang tot het gesprek verleend.</string>
+    <string name="notice_room_guest_access_forbidden">%1$s heeft gasten de toegang tot het gesprek verhinderd.</string>
+
+    <string name="notice_end_to_end_ok">%1$s heeft eind-tot-eind-versleuteling ingeschakeld.</string>
+    <string name="notice_end_to_end_unknown_algorithm">%1$s heeft eind-tot-eind-versleuteling ingeschakeld (onbekend algoritme %2$s).</string>
+
+    <string name="key_verification_request_fallback_message">%s vraagt om uw sleutel te verifiëren, maar uw cliënt biedt geen ondersteuning voor verificatie in het gesprek. U zult de verouderde sleutelverificatie moeten gebruiken om de sleutels te verifiëren.</string>
+
 </resources>
diff --git a/matrix-sdk-android/src/main/res/values-nn/strings.xml b/matrix-sdk-android/src/main/res/values-nn/strings.xml
index a8490200d3..d61849651d 100644
--- a/matrix-sdk-android/src/main/res/values-nn/strings.xml
+++ b/matrix-sdk-android/src/main/res/values-nn/strings.xml
@@ -8,10 +8,10 @@
     <string name="summary_user_sent_sticker">%1$s sende eit klistremerke.</string>
 
     <string name="notice_room_invite_no_invitee">%s si innbjoding</string>
-    <string name="notice_room_invite">%1$s baud %2$s inn</string>
-    <string name="notice_room_invite_you">%1$s baud deg inn</string>
+    <string name="notice_room_invite">%1$s inviterte %2$s</string>
+    <string name="notice_room_invite_you">%1$s inviterte deg</string>
     <string name="notice_room_join">%1$s kom inn</string>
-    <string name="notice_room_leave">%1$s fór ut</string>
+    <string name="notice_room_leave">%1$s forlot rommet</string>
     <string name="notice_room_reject">%1$s sa nei til innbjodingi</string>
     <string name="notice_room_kick">%1$s sparka %2$s</string>
     <string name="notice_room_unban">%1$s slapp %2$s inn att</string>
@@ -24,13 +24,13 @@
     <string name="notice_room_topic_changed">%1$s gjorde emnet til: %2$s</string>
     <string name="notice_room_name_changed">%1$s gjorde romnamnet til: %2$s</string>
     <string name="notice_placed_video_call">%s starta ei videosamtala.</string>
-    <string name="notice_placed_voice_call">%s starta ei røystsamtala.</string>
+    <string name="notice_placed_voice_call">%s starta eit taleanrop.</string>
     <string name="notice_answered_call">%s tok røyret.</string>
     <string name="notice_ended_call">%s la på røyret.</string>
     <string name="notice_made_future_room_visibility">%1$s gjorde den framtidige romsoga synleg for %2$s</string>
-    <string name="notice_room_visibility_invited">alle rommedlemer, frå då dei vart bodne inn.</string>
-    <string name="notice_room_visibility_joined">alle rommedlemer, frå då dei kom inn.</string>
-    <string name="notice_room_visibility_shared">alle rommedlemer.</string>
+    <string name="notice_room_visibility_invited">alle rommedlemmar, frå då dei vart invitert inn.</string>
+    <string name="notice_room_visibility_joined">alle rommedlemmar, frå då dei kom inn.</string>
+    <string name="notice_room_visibility_shared">alle rommedlemmar.</string>
     <string name="notice_room_visibility_world_readable">kven som heldst.</string>
     <string name="notice_room_visibility_unknown">uvisst (%s).</string>
     <string name="notice_end_to_end">%1$s skrudde ende-til-ende-kryptering på (%2$s)</string>
@@ -43,7 +43,7 @@
     <string name="notice_room_name_removed">%1$s tok burt romnamnet</string>
     <string name="notice_room_topic_removed">%1$s tok burt romemnet</string>
     <string name="notice_profile_change_redacted">%1$s gjorde um på skildringi si %2$s</string>
-    <string name="notice_room_third_party_invite">%1$s baud %2$s inn i romet</string>
+    <string name="notice_room_third_party_invite">%1$s inviterte %2$s til rommet</string>
     <string name="notice_room_third_party_registered_invite">%1$s sa ja til innbjodingi til %2$s</string>
 
     <string name="notice_crypto_unable_to_decrypt">** Fekk ikkje til å dekryptera: %s **</string>
@@ -149,4 +149,9 @@
     <string name="verification_emoji_folder">Mappa</string>
     <string name="verification_emoji_pin">Nål</string>
 
+    <string name="notice_room_update">%s oppgraderte rommet.</string>
+
+    <string name="clear_timeline_send_queue">Nullstill sendingskø</string>
+
+    <string name="notice_room_leave_with_reason">%1$s forlot rommet. Grunn: %2$s</string>
 </resources>
diff --git a/matrix-sdk-android/src/main/res/values-sk/strings.xml b/matrix-sdk-android/src/main/res/values-sk/strings.xml
index b729932b1f..a18cff615c 100644
--- a/matrix-sdk-android/src/main/res/values-sk/strings.xml
+++ b/matrix-sdk-android/src/main/res/values-sk/strings.xml
@@ -174,4 +174,18 @@
     <string name="clear_timeline_send_queue">Vymazať správy na odoslanie</string>
 
     <string name="notice_room_third_party_revoked_invite">%1$s zamietol pozvanie používateľa %2$s vstúpiť do miestnosti</string>
+    <string name="notice_room_invite_no_invitee_with_reason">Pozvanie od používateľa %1$s. Dôvod: %2$s</string>
+    <string name="notice_room_invite_with_reason">%1$s pozval používateľa %2$s. Dôvod: %3$s</string>
+    <string name="notice_room_invite_you_with_reason">%1$s vás pozval. Dôvod: %2$s</string>
+    <string name="notice_room_join_with_reason">%1$s sa pridal. Dôvod: %2$s</string>
+    <string name="notice_room_leave_with_reason">Používateľ %1$s odišiel. Dôvod: %2$s</string>
+    <string name="notice_room_reject_with_reason">%1$s odmietol pozvanie. Dôvod: %2$s</string>
+    <string name="notice_room_kick_with_reason">%1$s vyhodil používateľa %2$s. Dôvod: %3$s</string>
+    <string name="notice_room_unban_with_reason">%1$s znovu pridaný používateľom %2$s. Dôvod: %3$s</string>
+    <string name="notice_room_ban_with_reason">%1$s vyhodil %2$s. Dôvod: %3$s</string>
+    <string name="notice_room_third_party_invite_with_reason">%1$s poslal pozvánku používateľovi %2$s, aby sa pripojil na miestnosť. Dôvod: %3$s</string>
+    <string name="notice_room_third_party_revoked_invite_with_reason">%1$s odvolal pozvánku pre používateľa %2$s, aby sa pripojil na miestnosť. Dôvod: %3$s</string>
+    <string name="notice_room_third_party_registered_invite_with_reason">%1$s prijal pozvanie od používateľa %2$s. Dôvod: %3$s</string>
+    <string name="notice_room_withdraw_with_reason">%1$s odoprel pozvánku používateľa %2$s. Dôvod: %3$s</string>
+
 </resources>
diff --git a/matrix-sdk-android/src/main/res/values-sq/strings.xml b/matrix-sdk-android/src/main/res/values-sq/strings.xml
index d4a28e28d7..e966f22064 100644
--- a/matrix-sdk-android/src/main/res/values-sq/strings.xml
+++ b/matrix-sdk-android/src/main/res/values-sq/strings.xml
@@ -198,4 +198,12 @@
     <string name="notice_room_canonical_alias_set">%1$s caktoi %2$s si adresë kryesore për këtë dhomë.</string>
     <string name="notice_room_canonical_alias_unset">%1$s hoqi adresën kryesore për këtë dhomë.</string>
 
+    <string name="notice_room_guest_access_can_join">%1$s ka lejuar vizitorë të marrin pjesë në dhomë.</string>
+    <string name="notice_room_guest_access_forbidden">%1$s ka penguar vizitorë të marrin pjesë në dhomë.</string>
+
+    <string name="notice_end_to_end_ok">%1$s aktivizoi fshehtëzim skaj-më-skaj.</string>
+    <string name="notice_end_to_end_unknown_algorithm">%1$s aktivizoi fshehtëzim skaj-më-skaj (algoritëm i papranuar %2$s).</string>
+
+    <string name="key_verification_request_fallback_message">%s po kërkon të verifikojë kyçin tuaj, por klienti juaj nuk mbulon verifikim kyçesh brenda fjalosjeje. Që të verifikoni kyça, do t’ju duhet të përdorni verifikim të dikurshëm kyçesh.</string>
+
 </resources>
diff --git a/matrix-sdk-android/src/main/res/values-zh-rCN/strings.xml b/matrix-sdk-android/src/main/res/values-zh-rCN/strings.xml
index 6e3ced3048..38affc0599 100644
--- a/matrix-sdk-android/src/main/res/values-zh-rCN/strings.xml
+++ b/matrix-sdk-android/src/main/res/values-zh-rCN/strings.xml
@@ -170,4 +170,39 @@
     <string name="notice_room_third_party_revoked_invite">%1$s 撤回了对 %2$s 邀请</string>
     <string name="verification_emoji_pin">置顶</string>
 
+    <string name="notice_room_invite_no_invitee_with_reason">%1$s 的邀请。理由:%2$s</string>
+    <string name="notice_room_invite_with_reason">%1$s 邀请了 %2$s。理由:%3$s</string>
+    <string name="notice_room_invite_you_with_reason">%1$s 邀请了您。理由:%2$s</string>
+    <string name="notice_room_join_with_reason">%1$s 已加入。理由:%2$s</string>
+    <string name="notice_room_leave_with_reason">%1$s 已离开。理由:%2$s</string>
+    <string name="notice_room_reject_with_reason">%1$s 已拒绝邀请。理由:%2$s</string>
+    <string name="notice_room_kick_with_reason">%1$s 踢走了 %2$s。理由:%3$s</string>
+    <string name="notice_room_unban_with_reason">%1$s 取消封锁了 %2$s。理由:%3$s</string>
+    <string name="notice_room_ban_with_reason">%1$s 封锁了 %2$s。理由:%3$s</string>
+    <string name="notice_room_third_party_invite_with_reason">%1$s 已发送邀请给 %2$s 来加入聊天室。理由:%3$s</string>
+    <string name="notice_room_third_party_revoked_invite_with_reason">%1$s 撤销了 %2$s 加入聊天室的邀請。理由:%3$s</string>
+    <string name="notice_room_third_party_registered_invite_with_reason">%1$s 接受 %2$s 的邀請。理由:%3$s</string>
+    <string name="notice_room_withdraw_with_reason">%1$s 撤回了对 %2$s 的邀请。理由:%3$s</string>
+
+    <plurals name="notice_room_aliases_added">
+        <item quantity="other">%1$s 新增了 %2$s 为此聊天室的地址。</item>
+    </plurals>
+
+    <plurals name="notice_room_aliases_removed">
+        <item quantity="other">%1$s 移除了此聊天室的 %3$s 地址。</item>
+    </plurals>
+
+    <string name="notice_room_aliases_added_and_removed">%1$s 为此聊天室新增 %2$s 并移除 %3$s 地址。</string>
+
+    <string name="notice_room_canonical_alias_set">%1$s 为此聊天室设定了 %2$s 为主地址。</string>
+    <string name="notice_room_canonical_alias_unset">%1$s 为此聊天室移除了主要地址。</string>
+
+    <string name="notice_room_guest_access_can_join">%1$s 已允许访客加入聊天室。</string>
+    <string name="notice_room_guest_access_forbidden">%1$s 已禁止访客加入聊天室。</string>
+
+    <string name="notice_end_to_end_ok">%1$s 已开启端到端加密。</string>
+    <string name="notice_end_to_end_unknown_algorithm">%1$s 已开启端到端加密(无法识别的演算法 %2$s)。</string>
+
+    <string name="key_verification_request_fallback_message">%s 正在请求验证您的密钥,但您的客户端不支援聊天中密钥验证。 您将必须使用旧版的密钥验证来验证金钥。</string>
+
 </resources>
diff --git a/matrix-sdk-android/src/main/res/values-zh-rTW/strings.xml b/matrix-sdk-android/src/main/res/values-zh-rTW/strings.xml
index 7182b07080..0796c0c7dd 100644
--- a/matrix-sdk-android/src/main/res/values-zh-rTW/strings.xml
+++ b/matrix-sdk-android/src/main/res/values-zh-rTW/strings.xml
@@ -6,8 +6,8 @@
     <string name="notice_room_invite_no_invitee">%s 的邀請</string>
     <string name="notice_room_invite">%1$s 邀請了 %2$s</string>
     <string name="notice_room_invite_you">%1$s 邀請您</string>
-    <string name="notice_room_join">%1$s 已加入</string>
-    <string name="notice_room_leave">%1$s 已離開</string>
+    <string name="notice_room_join">%1$s 已加入聊天室</string>
+    <string name="notice_room_leave">%1$s 已離開聊天室</string>
     <string name="notice_room_reject">%1$s 拒絕邀請</string>
     <string name="notice_room_kick">%1$s 踢出 %2$s</string>
     <string name="notice_room_unban">%1$s 解除禁止 %2$s</string>
@@ -174,8 +174,8 @@
     <string name="notice_room_invite_no_invitee_with_reason">%1$s 的邀請。理由:%2$s</string>
     <string name="notice_room_invite_with_reason">%1$s 邀請了 %2$s。理由:%3$s</string>
     <string name="notice_room_invite_you_with_reason">%1$s 邀請了您。理由:%2$s</string>
-    <string name="notice_room_join_with_reason">%1$s 已加入。理由:%2$s</string>
-    <string name="notice_room_leave_with_reason">%1$s 已離開。理由:%2$s</string>
+    <string name="notice_room_join_with_reason">%1$s 已加入聊天室。理由:%2$s</string>
+    <string name="notice_room_leave_with_reason">%1$s 已離開聊天室。理由:%2$s</string>
     <string name="notice_room_reject_with_reason">%1$s 已回絕邀請。理由:%2$s</string>
     <string name="notice_room_kick_with_reason">%1$s 踢走了 %2$s。理由:%3$s</string>
     <string name="notice_room_unban_with_reason">%1$s 取消封鎖了 %2$s。理由:%3$s</string>
@@ -198,4 +198,12 @@
     <string name="notice_room_canonical_alias_set">%1$s 為此聊天室設定了 %2$s 為主地址。</string>
     <string name="notice_room_canonical_alias_unset">%1$s 為此聊天室移除了主要地址。</string>
 
+    <string name="notice_room_guest_access_can_join">%1$s 已允許訪客加入聊天室。</string>
+    <string name="notice_room_guest_access_forbidden">%1$s 已禁止訪客加入聊天室。</string>
+
+    <string name="notice_end_to_end_ok">%1$s 已開啟端到端加密。</string>
+    <string name="notice_end_to_end_unknown_algorithm">%1$s 已開啟端到端加密(無法識別的演算法 %2$s)。</string>
+
+    <string name="key_verification_request_fallback_message">%s 正在請求驗證您的金鑰,但您的客戶端不支援聊天中金鑰驗證。您將必須使用舊版的金鑰驗證來驗證金鑰。</string>
+
 </resources>
diff --git a/matrix-sdk-android/src/main/res/values/strings.xml b/matrix-sdk-android/src/main/res/values/strings.xml
index de70b21695..50169fd982 100644
--- a/matrix-sdk-android/src/main/res/values/strings.xml
+++ b/matrix-sdk-android/src/main/res/values/strings.xml
@@ -7,8 +7,8 @@
     <string name="notice_room_invite_no_invitee">%s\'s invitation</string>
     <string name="notice_room_invite">%1$s invited %2$s</string>
     <string name="notice_room_invite_you">%1$s invited you</string>
-    <string name="notice_room_join">%1$s joined</string>
-    <string name="notice_room_leave">%1$s left</string>
+    <string name="notice_room_join">%1$s joined the room</string>
+    <string name="notice_room_leave">%1$s left the room</string>
     <string name="notice_room_reject">%1$s rejected the invitation</string>
     <string name="notice_room_kick">%1$s kicked %2$s</string>
     <string name="notice_room_unban">%1$s unbanned %2$s</string>
@@ -246,8 +246,8 @@
     <string name="notice_room_invite_no_invitee_with_reason">%1$s\'s invitation. Reason: %2$s</string>
     <string name="notice_room_invite_with_reason">%1$s invited %2$s. Reason: %3$s</string>
     <string name="notice_room_invite_you_with_reason">%1$s invited you. Reason: %2$s</string>
-    <string name="notice_room_join_with_reason">%1$s joined. Reason: %2$s</string>
-    <string name="notice_room_leave_with_reason">%1$s left. Reason: %2$s</string>
+    <string name="notice_room_join_with_reason">%1$s joined the room. Reason: %2$s</string>
+    <string name="notice_room_leave_with_reason">%1$s left the room. Reason: %2$s</string>
     <string name="notice_room_reject_with_reason">%1$s rejected the invitation. Reason: %2$s</string>
     <string name="notice_room_kick_with_reason">%1$s kicked %2$s. Reason: %3$s</string>
     <string name="notice_room_unban_with_reason">%1$s unbanned %2$s. Reason: %3$s</string>
diff --git a/matrix-sdk-android/src/main/res/values/strings_RiotX.xml b/matrix-sdk-android/src/main/res/values/strings_RiotX.xml
index d781ec5f1e..6eb46fd7df 100644
--- a/matrix-sdk-android/src/main/res/values/strings_RiotX.xml
+++ b/matrix-sdk-android/src/main/res/values/strings_RiotX.xml
@@ -1,4 +1,32 @@
 <?xml version="1.0" encoding="utf-8"?>
 <resources>
 
+    <!--
+
+
+
+
+ 
+
+
+
+
+
+
+
+
+ PLEASE DO NOT ADD NEW STRINGS HERE, THE FILE WILL BE DELETED, ONCE ALL PR WILL BE MERGED
+
+
+
+
+
+
+
+
+
+
+
+  -->
+
 </resources>
diff --git a/matrix-sdk-android/src/release/java/im/vector/matrix/android/internal/network/interceptors/CurlLoggingInterceptor.kt b/matrix-sdk-android/src/release/java/im/vector/matrix/android/internal/network/interceptors/CurlLoggingInterceptor.kt
index 8f8a12d0b1..56b2ac0d48 100644
--- a/matrix-sdk-android/src/release/java/im/vector/matrix/android/internal/network/interceptors/CurlLoggingInterceptor.kt
+++ b/matrix-sdk-android/src/release/java/im/vector/matrix/android/internal/network/interceptors/CurlLoggingInterceptor.kt
@@ -20,7 +20,6 @@ package im.vector.matrix.android.internal.network.interceptors
 import im.vector.matrix.android.internal.di.MatrixScope
 import okhttp3.Interceptor
 import okhttp3.Response
-import okhttp3.logging.HttpLoggingInterceptor
 import java.io.IOException
 import javax.inject.Inject
 
@@ -28,7 +27,7 @@ import javax.inject.Inject
  * No op interceptor
  */
 @MatrixScope
-internal class CurlLoggingInterceptor @Inject constructor(private val logger: HttpLoggingInterceptor.Logger)
+internal class CurlLoggingInterceptor @Inject constructor()
     : Interceptor {
 
     @Throws(IOException::class)
diff --git a/matrix-sdk-android/src/sharedTest/java/im/vector/matrix/android/test/shared/TestRules.kt b/matrix-sdk-android/src/sharedTest/java/im/vector/matrix/android/test/shared/TestRules.kt
new file mode 100644
index 0000000000..bf073ecbc3
--- /dev/null
+++ b/matrix-sdk-android/src/sharedTest/java/im/vector/matrix/android/test/shared/TestRules.kt
@@ -0,0 +1,27 @@
+/*
+ * 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.matrix.android.test.shared
+
+import net.lachlanmckee.timberjunit.TimberTestRule
+
+internal fun createTimberTestRule(): TimberTestRule {
+    return TimberTestRule.builder()
+            .showThread(false)
+            .showTimestamp(false)
+            .onlyLogWhenTestFails(false)
+            .build()
+}
diff --git a/matrix-sdk-android/src/test/java/im/vector/matrix/android/MatrixTest.kt b/matrix-sdk-android/src/test/java/im/vector/matrix/android/MatrixTest.kt
new file mode 100644
index 0000000000..cef9bb69d7
--- /dev/null
+++ b/matrix-sdk-android/src/test/java/im/vector/matrix/android/MatrixTest.kt
@@ -0,0 +1,26 @@
+/*
+ * 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.matrix.android
+
+import im.vector.matrix.android.test.shared.createTimberTestRule
+import org.junit.Rule
+
+interface MatrixTest {
+
+    @Rule
+    fun timberTestRule() = createTimberTestRule()
+}
diff --git a/matrix-sdk-android/src/test/java/im/vector/matrix/android/api/pushrules/PushRuleActionsTest.kt b/matrix-sdk-android/src/test/java/im/vector/matrix/android/api/pushrules/PushRuleActionsTest.kt
index 1d5d6a4d19..21ea1cbd6a 100644
--- a/matrix-sdk-android/src/test/java/im/vector/matrix/android/api/pushrules/PushRuleActionsTest.kt
+++ b/matrix-sdk-android/src/test/java/im/vector/matrix/android/api/pushrules/PushRuleActionsTest.kt
@@ -16,6 +16,7 @@
 
 package im.vector.matrix.android.api.pushrules
 
+import im.vector.matrix.android.MatrixTest
 import im.vector.matrix.android.api.pushrules.rest.PushRule
 import im.vector.matrix.android.internal.di.MoshiProvider
 import org.junit.Assert.assertEquals
@@ -23,7 +24,7 @@ import org.junit.Assert.assertNotNull
 import org.junit.Assert.assertTrue
 import org.junit.Test
 
-class PushRuleActionsTest {
+class PushRuleActionsTest: MatrixTest {
 
     @Test
     fun test_action_parsing() {
diff --git a/matrix-sdk-android/src/test/java/im/vector/matrix/android/api/pushrules/PushrulesConditionTest.kt b/matrix-sdk-android/src/test/java/im/vector/matrix/android/api/pushrules/PushrulesConditionTest.kt
index 960d585bdc..1bf40222f8 100644
--- a/matrix-sdk-android/src/test/java/im/vector/matrix/android/api/pushrules/PushrulesConditionTest.kt
+++ b/matrix-sdk-android/src/test/java/im/vector/matrix/android/api/pushrules/PushrulesConditionTest.kt
@@ -16,6 +16,7 @@
 
 package im.vector.matrix.android.api.pushrules
 
+import im.vector.matrix.android.MatrixTest
 import im.vector.matrix.android.api.session.events.model.Event
 import im.vector.matrix.android.api.session.events.model.toContent
 import im.vector.matrix.android.api.session.room.Room
@@ -30,7 +31,7 @@ import org.junit.Assert.assertFalse
 import org.junit.Assert.assertTrue
 import org.junit.Test
 
-class PushrulesConditionTest {
+class PushrulesConditionTest: MatrixTest {
 
     /* ==========================================================================================
      * Test EventMatchCondition
diff --git a/matrix-sdk-android/src/test/java/im/vector/matrix/android/internal/crypto/keysbackup/util/Base58Test.kt b/matrix-sdk-android/src/test/java/im/vector/matrix/android/internal/crypto/keysbackup/util/Base58Test.kt
index 42295dada0..6d7ddce0b4 100644
--- a/matrix-sdk-android/src/test/java/im/vector/matrix/android/internal/crypto/keysbackup/util/Base58Test.kt
+++ b/matrix-sdk-android/src/test/java/im/vector/matrix/android/internal/crypto/keysbackup/util/Base58Test.kt
@@ -16,6 +16,7 @@
 
 package im.vector.matrix.android.internal.crypto.keysbackup.util
 
+import im.vector.matrix.android.MatrixTest
 import org.junit.Assert.assertArrayEquals
 import org.junit.Assert.assertEquals
 import org.junit.FixMethodOrder
@@ -23,7 +24,7 @@ import org.junit.Test
 import org.junit.runners.MethodSorters
 
 @FixMethodOrder(MethodSorters.JVM)
-class Base58Test {
+class Base58Test: MatrixTest {
 
     @Test
     fun encode() {
diff --git a/matrix-sdk-android/src/test/java/im/vector/matrix/android/internal/crypto/keysbackup/util/RecoveryKeyTest.kt b/matrix-sdk-android/src/test/java/im/vector/matrix/android/internal/crypto/keysbackup/util/RecoveryKeyTest.kt
index 2566275952..606be13ed9 100644
--- a/matrix-sdk-android/src/test/java/im/vector/matrix/android/internal/crypto/keysbackup/util/RecoveryKeyTest.kt
+++ b/matrix-sdk-android/src/test/java/im/vector/matrix/android/internal/crypto/keysbackup/util/RecoveryKeyTest.kt
@@ -16,13 +16,15 @@
 
 package im.vector.matrix.android.internal.crypto.keysbackup.util
 
+import im.vector.matrix.android.MatrixTest
 import org.junit.Assert.assertArrayEquals
 import org.junit.Assert.assertEquals
 import org.junit.Assert.assertFalse
 import org.junit.Assert.assertTrue
 import org.junit.Test
 
-class RecoveryKeyTest {
+class RecoveryKeyTest: MatrixTest {
+
     private val curve25519Key = byteArrayOf(
             0x77.toByte(), 0x07.toByte(), 0x6D.toByte(), 0x0A.toByte(), 0x73.toByte(), 0x18.toByte(), 0xA5.toByte(), 0x7D.toByte(),
             0x3C.toByte(), 0x16.toByte(), 0xC1.toByte(), 0x72.toByte(), 0x51.toByte(), 0xB2.toByte(), 0x66.toByte(), 0x45.toByte(),
diff --git a/matrix-sdk-android/src/test/java/im/vector/matrix/android/internal/crypto/store/db/HelperTest.kt b/matrix-sdk-android/src/test/java/im/vector/matrix/android/internal/crypto/store/db/HelperTest.kt
index d4740bdc4f..b8524c95e0 100644
--- a/matrix-sdk-android/src/test/java/im/vector/matrix/android/internal/crypto/store/db/HelperTest.kt
+++ b/matrix-sdk-android/src/test/java/im/vector/matrix/android/internal/crypto/store/db/HelperTest.kt
@@ -16,11 +16,12 @@
 
 package im.vector.matrix.android.internal.crypto.store.db
 
+import im.vector.matrix.android.MatrixTest
 import im.vector.matrix.android.internal.util.md5
 import org.junit.Assert.assertEquals
 import org.junit.Test
 
-class HelperTest {
+class HelperTest: MatrixTest {
 
     @Test
     fun testHash_ok() {
diff --git a/matrix-sdk-android/src/test/java/im/vector/matrix/android/internal/crypto/verification/qrcode/BinaryStringTest.kt b/matrix-sdk-android/src/test/java/im/vector/matrix/android/internal/crypto/verification/qrcode/BinaryStringTest.kt
index df5499cb6f..8fc93c139e 100644
--- a/matrix-sdk-android/src/test/java/im/vector/matrix/android/internal/crypto/verification/qrcode/BinaryStringTest.kt
+++ b/matrix-sdk-android/src/test/java/im/vector/matrix/android/internal/crypto/verification/qrcode/BinaryStringTest.kt
@@ -16,13 +16,14 @@
 
 package im.vector.matrix.android.internal.crypto.verification.qrcode
 
+import im.vector.matrix.android.MatrixTest
 import org.amshove.kluent.shouldEqualTo
 import org.junit.FixMethodOrder
 import org.junit.Test
 import org.junit.runners.MethodSorters
 
 @FixMethodOrder(MethodSorters.JVM)
-class BinaryStringTest {
+class BinaryStringTest: MatrixTest {
 
     /**
      * I want to put bytes to a String, and vice versa
diff --git a/matrix-sdk-android/src/test/java/im/vector/matrix/android/internal/task/CoroutineSequencersTest.kt b/matrix-sdk-android/src/test/java/im/vector/matrix/android/internal/task/CoroutineSequencersTest.kt
index a70713c44b..7d460861b1 100644
--- a/matrix-sdk-android/src/test/java/im/vector/matrix/android/internal/task/CoroutineSequencersTest.kt
+++ b/matrix-sdk-android/src/test/java/im/vector/matrix/android/internal/task/CoroutineSequencersTest.kt
@@ -16,6 +16,7 @@
 
 package im.vector.matrix.android.internal.task
 
+import im.vector.matrix.android.MatrixTest
 import kotlinx.coroutines.GlobalScope
 import kotlinx.coroutines.asCoroutineDispatcher
 import kotlinx.coroutines.delay
@@ -26,7 +27,7 @@ import org.junit.Assert.assertEquals
 import org.junit.Test
 import java.util.concurrent.Executors
 
-class CoroutineSequencersTest {
+class CoroutineSequencersTest: MatrixTest {
 
     private val dispatcher = Executors.newSingleThreadExecutor().asCoroutineDispatcher()
 
diff --git a/tools/check/forbidden_strings_in_code.txt b/tools/check/forbidden_strings_in_code.txt
index a0bd725118..3c0337ac99 100644
--- a/tools/check/forbidden_strings_in_code.txt
+++ b/tools/check/forbidden_strings_in_code.txt
@@ -60,7 +60,7 @@ private short
 final short
 
 ### Line length is limited to 160 chars. Please split long lines
-.{161}
+[^─]{161}
 
 ### "DO NOT COMMIT" has been committed
 DO NOT COMMIT
diff --git a/tools/import_from_riot.sh b/tools/import_from_riot.sh
index 7572b73f17..a2b68a347c 100755
--- a/tools/import_from_riot.sh
+++ b/tools/import_from_riot.sh
@@ -37,6 +37,7 @@ cp ../matrix-android-sdk/matrix-sdk/src/main/res/values-en-rGB/strings.xml ./mat
 cp ../matrix-android-sdk/matrix-sdk/src/main/res/values-es/strings.xml     ./matrix-sdk-android/src/main/res/values-es/strings.xml
 cp ../matrix-android-sdk/matrix-sdk/src/main/res/values-es-rMX/strings.xml ./matrix-sdk-android/src/main/res/values-es-rMX/strings.xml
 cp ../matrix-android-sdk/matrix-sdk/src/main/res/values-eu/strings.xml     ./matrix-sdk-android/src/main/res/values-eu/strings.xml
+cp ../matrix-android-sdk/matrix-sdk/src/main/res/values-fa/strings.xml     ./matrix-sdk-android/src/main/res/values-fa/strings.xml
 cp ../matrix-android-sdk/matrix-sdk/src/main/res/values-fi/strings.xml     ./matrix-sdk-android/src/main/res/values-fi/strings.xml
 cp ../matrix-android-sdk/matrix-sdk/src/main/res/values-fr/strings.xml     ./matrix-sdk-android/src/main/res/values-fr/strings.xml
 cp ../matrix-android-sdk/matrix-sdk/src/main/res/values-gl/strings.xml     ./matrix-sdk-android/src/main/res/values-gl/strings.xml
@@ -75,6 +76,7 @@ cp ../riot-android/vector/src/main/res/values-bn-rIN/strings.xml    ./vector/src
 cp ../riot-android/vector/src/main/res/values-bs/strings.xml        ./vector/src/main/res/values-bs/strings.xml
 cp ../riot-android/vector/src/main/res/values-ca/strings.xml        ./vector/src/main/res/values-ca/strings.xml
 cp ../riot-android/vector/src/main/res/values-cs/strings.xml        ./vector/src/main/res/values-cs/strings.xml
+cp ../riot-android/vector/src/main/res/values-cy/strings.xml        ./vector/src/main/res/values-cy/strings.xml
 cp ../riot-android/vector/src/main/res/values-da/strings.xml        ./vector/src/main/res/values-da/strings.xml
 cp ../riot-android/vector/src/main/res/values-de/strings.xml        ./vector/src/main/res/values-de/strings.xml
 cp ../riot-android/vector/src/main/res/values-el/strings.xml        ./vector/src/main/res/values-el/strings.xml
@@ -96,6 +98,7 @@ cp ../riot-android/vector/src/main/res/values-it/strings.xml        ./vector/src
 cp ../riot-android/vector/src/main/res/values-ja/strings.xml        ./vector/src/main/res/values-ja/strings.xml
 cp ../riot-android/vector/src/main/res/values-ko/strings.xml        ./vector/src/main/res/values-ko/strings.xml
 cp ../riot-android/vector/src/main/res/values-lv/strings.xml        ./vector/src/main/res/values-lv/strings.xml
+cp ../riot-android/vector/src/main/res/values-nb-rNO/strings.xml    ./vector/src/main/res/values-nb-rNO/strings.xml
 cp ../riot-android/vector/src/main/res/values-nl/strings.xml        ./vector/src/main/res/values-nl/strings.xml
 cp ../riot-android/vector/src/main/res/values-nn/strings.xml        ./vector/src/main/res/values-nn/strings.xml
 cp ../riot-android/vector/src/main/res/values-pl/strings.xml        ./vector/src/main/res/values-pl/strings.xml
diff --git a/tools/release/sign_apk.sh b/tools/release/sign_apk.sh
index 7f421c15f4..866510ba13 100755
--- a/tools/release/sign_apk.sh
+++ b/tools/release/sign_apk.sh
@@ -17,7 +17,7 @@ PARAM_KEYSTORE_PATH=$1
 PARAM_APK=$2
 
 # Other params
-BUILD_TOOLS_VERSION="28.0.3"
+BUILD_TOOLS_VERSION="29.0.3"
 MIN_SDK_VERSION=19
 
 echo "Signing APK with build-tools version ${BUILD_TOOLS_VERSION} for min SDK version ${MIN_SDK_VERSION}..."
diff --git a/tools/release/sign_apk_unsafe.sh b/tools/release/sign_apk_unsafe.sh
index 022f3618eb..bf021e8345 100755
--- a/tools/release/sign_apk_unsafe.sh
+++ b/tools/release/sign_apk_unsafe.sh
@@ -23,7 +23,7 @@ PARAM_KS_PASS=$3
 PARAM_KEY_PASS=$4
 
 # Other params
-BUILD_TOOLS_VERSION="28.0.3"
+BUILD_TOOLS_VERSION="29.0.3"
 MIN_SDK_VERSION=19
 
 echo "Signing APK with build-tools version ${BUILD_TOOLS_VERSION} for min SDK version ${MIN_SDK_VERSION}..."
diff --git a/tools/templates/RiotXFeature/globals.xml.ftl b/tools/templates/RiotXFeature/globals.xml.ftl
new file mode 100644
index 0000000000..7cafd80483
--- /dev/null
+++ b/tools/templates/RiotXFeature/globals.xml.ftl
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<globals>
+    <#include "root://activities/common/common_globals.xml.ftl" />
+    <global id="resOut" value="${resDir}" />
+    <global id="srcOut" value="${srcDir}/${slashedPackageName(packageName)}" />
+</globals>
diff --git a/tools/templates/RiotXFeature/recipe.xml.ftl b/tools/templates/RiotXFeature/recipe.xml.ftl
new file mode 100644
index 0000000000..88160fd0f3
--- /dev/null
+++ b/tools/templates/RiotXFeature/recipe.xml.ftl
@@ -0,0 +1,37 @@
+<?xml version="1.0"?>
+<#import "root://activities/common/kotlin_macros.ftl" as kt>
+<recipe>
+	  
+    <instantiate from="root/res/layout/fragment.xml.ftl"
+                   to="${escapeXmlAttribute(resOut)}/layout/${escapeXmlAttribute(fragmentLayout)}.xml" />
+    <open file="${escapeXmlAttribute(resOut)}/layout/${fragmentLayout}.xml" />
+
+	<#if createActivity>
+    <instantiate from="root/src/app_package/Activity.kt.ftl"
+                   to="${escapeXmlAttribute(srcOut)}/${activityClass}.kt" />
+	<open file="${escapeXmlAttribute(srcOut)}/${activityClass}.kt" />
+	</#if>
+
+    <instantiate from="root/src/app_package/Fragment.kt.ftl"
+                   to="${escapeXmlAttribute(srcOut)}/${fragmentClass}.kt" />			   
+    <open file="${escapeXmlAttribute(srcOut)}/${fragmentClass}.kt" />
+	
+    <instantiate from="root/src/app_package/ViewModel.kt.ftl"
+                   to="${escapeXmlAttribute(srcOut)}/${viewModelClass}.kt" />
+    <open file="${escapeXmlAttribute(srcOut)}/${viewModelClass}.kt" />
+	
+    <instantiate from="root/src/app_package/ViewState.kt.ftl"
+                   to="${escapeXmlAttribute(srcOut)}/${viewStateClass}.kt" />
+    <open file="${escapeXmlAttribute(srcOut)}/${viewStateClass}.kt" />
+	
+    <instantiate from="root/src/app_package/Action.kt.ftl"
+                   to="${escapeXmlAttribute(srcOut)}/${actionClass}.kt" />
+    <open file="${escapeXmlAttribute(srcOut)}/${actionClass}.kt" />
+
+    <#if createViewEvents>
+        <instantiate from="root/src/app_package/ViewEvents.kt.ftl"
+                       to="${escapeXmlAttribute(srcOut)}/${viewEventsClass}.kt" />
+    	<open file="${escapeXmlAttribute(srcOut)}/${viewEventsClass}.kt" />
+    </#if>
+	
+</recipe>
diff --git a/tools/templates/RiotXFeature/root/res/layout/fragment.xml.ftl b/tools/templates/RiotXFeature/root/res/layout/fragment.xml.ftl
new file mode 100644
index 0000000000..539c40f3f9
--- /dev/null
+++ b/tools/templates/RiotXFeature/root/res/layout/fragment.xml.ftl
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout 
+	xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:id="@+id/rootConstraintLayout"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <TextView
+        android:id="@+id/message"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="${fragmentClass}"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent"/>
+
+</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/tools/templates/RiotXFeature/root/src/app_package/Action.kt.ftl b/tools/templates/RiotXFeature/root/src/app_package/Action.kt.ftl
new file mode 100644
index 0000000000..7492907e6c
--- /dev/null
+++ b/tools/templates/RiotXFeature/root/src/app_package/Action.kt.ftl
@@ -0,0 +1,5 @@
+package ${escapeKotlinIdentifiers(packageName)}
+
+import im.vector.riotx.core.platform.VectorViewModelAction
+
+sealed class ${actionClass}: VectorViewModelAction
\ No newline at end of file
diff --git a/tools/templates/RiotXFeature/root/src/app_package/Activity.kt.ftl b/tools/templates/RiotXFeature/root/src/app_package/Activity.kt.ftl
new file mode 100644
index 0000000000..fdac319482
--- /dev/null
+++ b/tools/templates/RiotXFeature/root/src/app_package/Activity.kt.ftl
@@ -0,0 +1,49 @@
+package ${escapeKotlinIdentifiers(packageName)}
+
+import android.content.Context
+import android.content.Intent
+import androidx.appcompat.widget.Toolbar
+import im.vector.riotx.R
+import im.vector.riotx.core.extensions.addFragment
+import im.vector.riotx.core.platform.ToolbarConfigurable
+import im.vector.riotx.core.platform.VectorBaseActivity
+
+//TODO: add this activity to manifest
+class ${activityClass} : VectorBaseActivity(), ToolbarConfigurable {
+
+    companion object {
+	
+		<#if createFragmentArgs>
+		private const val EXTRA_FRAGMENT_ARGS = "EXTRA_FRAGMENT_ARGS"
+		
+		fun newIntent(context: Context, args: ${fragmentArgsClass}): Intent {
+		     return Intent(context, ${activityClass}::class.java).apply {
+		         putExtra(EXTRA_FRAGMENT_ARGS, args)
+		      }
+		}
+		<#else>
+        fun newIntent(context: Context): Intent {
+            return Intent(context, ${activityClass}::class.java)
+        }
+		</#if>
+    }
+
+    override fun getLayoutRes() = R.layout.activity_simple
+
+    override fun initUiAndData() {
+        if (isFirstCreation()) {
+			<#if createFragmentArgs>
+			val fragmentArgs: ${fragmentArgsClass} = intent?.extras?.getParcelable(EXTRA_FRAGMENT_ARGS)
+                                                   ?: return
+            addFragment(R.id.simpleFragmentContainer, ${fragmentClass}::class.java, fragmentArgs)
+			<#else>
+			addFragment(R.id.simpleFragmentContainer, ${fragmentClass}::class.java)
+			</#if>
+        }
+    }
+
+    override fun configure(toolbar: Toolbar) {
+        configureToolbar(toolbar)
+    }
+
+}
diff --git a/tools/templates/RiotXFeature/root/src/app_package/Fragment.kt.ftl b/tools/templates/RiotXFeature/root/src/app_package/Fragment.kt.ftl
new file mode 100644
index 0000000000..df69078d9d
--- /dev/null
+++ b/tools/templates/RiotXFeature/root/src/app_package/Fragment.kt.ftl
@@ -0,0 +1,47 @@
+package ${escapeKotlinIdentifiers(packageName)}
+
+import android.os.Bundle
+<#if createFragmentArgs>
+import android.os.Parcelable
+import kotlinx.android.parcel.Parcelize
+import com.airbnb.mvrx.args
+</#if>
+import android.view.View
+import com.airbnb.mvrx.fragmentViewModel
+import com.airbnb.mvrx.withState
+import im.vector.riotx.R
+import im.vector.riotx.core.platform.VectorBaseFragment
+import javax.inject.Inject
+
+<#if createFragmentArgs>
+@Parcelize
+data class ${fragmentArgsClass}() : Parcelable
+</#if>
+
+//TODO: add this fragment into FragmentModule
+class ${fragmentClass} @Inject constructor(
+        private val viewModelFactory: ${viewModelClass}.Factory
+) : VectorBaseFragment(), ${viewModelClass}.Factory by viewModelFactory {
+
+	<#if createFragmentArgs>
+		private val fragmentArgs: ${fragmentArgsClass} by args()
+	</#if>
+    private val viewModel: ${viewModelClass} by fragmentViewModel()
+
+    override fun getLayoutResId() = R.layout.${fragmentLayout}
+
+    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+        super.onViewCreated(view, savedInstanceState)
+		// Initialize your view, subscribe to viewModel... 
+    }
+
+    override fun onDestroyView() {
+        super.onDestroyView()
+		// Clear your view, unsubscribe...
+    }
+
+    override fun invalidate() = withState(viewModel) { state ->
+        //TODO
+    }
+
+}
diff --git a/tools/templates/RiotXFeature/root/src/app_package/ViewEvents.kt.ftl b/tools/templates/RiotXFeature/root/src/app_package/ViewEvents.kt.ftl
new file mode 100644
index 0000000000..4d7d2ee450
--- /dev/null
+++ b/tools/templates/RiotXFeature/root/src/app_package/ViewEvents.kt.ftl
@@ -0,0 +1,5 @@
+package ${escapeKotlinIdentifiers(packageName)}
+
+import im.vector.riotx.core.platform.VectorViewEvents
+
+sealed class ${viewEventsClass} : VectorViewEvents
\ No newline at end of file
diff --git a/tools/templates/RiotXFeature/root/src/app_package/ViewModel.kt.ftl b/tools/templates/RiotXFeature/root/src/app_package/ViewModel.kt.ftl
new file mode 100644
index 0000000000..f4090b40e6
--- /dev/null
+++ b/tools/templates/RiotXFeature/root/src/app_package/ViewModel.kt.ftl
@@ -0,0 +1,44 @@
+package ${escapeKotlinIdentifiers(packageName)}
+
+import com.airbnb.mvrx.ActivityViewModelContext
+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.riotx.core.platform.VectorViewModel
+
+<#if createViewEvents>
+<#else>
+import im.vector.riotx.core.platform.EmptyViewEvents
+</#if>
+
+class ${viewModelClass} @AssistedInject constructor(@Assisted initialState: ${viewStateClass})
+    <#if createViewEvents>
+    : VectorViewModel<${viewStateClass}, ${actionClass}, ${viewEventsClass}>(initialState) {
+    <#else>
+    : VectorViewModel<${viewStateClass}, ${actionClass}, EmptyViewEvents>(initialState) {
+    </#if>
+
+    @AssistedInject.Factory
+    interface Factory {
+        fun create(initialState: ${viewStateClass}): ${viewModelClass}
+    }
+
+    companion object : MvRxViewModelFactory<${viewModelClass}, ${viewStateClass}> {
+
+        @JvmStatic
+        override fun create(viewModelContext: ViewModelContext, state: ${viewStateClass}): ${viewModelClass}? {
+            val factory = when (viewModelContext) {
+                is FragmentViewModelContext -> viewModelContext.fragment as? Factory
+                is ActivityViewModelContext -> viewModelContext.activity as? Factory
+            }
+            return factory?.create(state) ?: error("You should let your activity/fragment implements Factory interface")
+        }
+    }
+
+    override fun handle(action: ${actionClass}) {
+		//TODO
+    }
+
+}
diff --git a/tools/templates/RiotXFeature/root/src/app_package/ViewState.kt.ftl b/tools/templates/RiotXFeature/root/src/app_package/ViewState.kt.ftl
new file mode 100644
index 0000000000..55e1f5f549
--- /dev/null
+++ b/tools/templates/RiotXFeature/root/src/app_package/ViewState.kt.ftl
@@ -0,0 +1,5 @@
+package ${escapeKotlinIdentifiers(packageName)}
+
+import com.airbnb.mvrx.MvRxState
+
+data class ${viewStateClass}() : MvRxState
\ No newline at end of file
diff --git a/tools/templates/RiotXFeature/template.xml b/tools/templates/RiotXFeature/template.xml
new file mode 100644
index 0000000000..33d2edfc70
--- /dev/null
+++ b/tools/templates/RiotXFeature/template.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0"?>
+<template
+    format="5"
+    revision="1"
+    name="RiotX Feature"
+    minApi="19"
+    minBuildApi="19"
+    description="Creates a new activity and a fragment with view model, view state and actions">
+
+    <category value="New Vector" />
+    <formfactor value="Mobile" />
+	
+  	 <parameter
+  	    id="createActivity"
+  	    name="Create host activity"
+  	    type="boolean"
+  	    default="true"
+  	    help="If true, you will have a host activity" />
+
+    <parameter
+        id="activityClass"
+        name="Activity Name"
+        type="string"
+        constraints="class|unique|nonempty"
+		visibility="createActivity"
+        default="MainActivity"
+        help="The name of the activity class to create" />
+
+    <parameter
+        id="fragmentClass"
+        name="Fragment Name"
+        type="string"
+        constraints="class|unique|nonempty"
+        suggest="${underscoreToCamelCase(classToResource(activityClass))}Fragment"
+        default="MainFragment"
+        help="The name of the fragment class to create" />
+		
+   	 <parameter
+   	    id="createFragmentArgs"
+   	    name="Create fragment Args"
+   	    type="boolean"
+   	    default="false"
+   	    help="If true, you will have a fragment args" />
+		
+	 <parameter
+	    id="fragmentArgsClass"
+	    name="Fragment Args"
+	    type="string"
+	    constraints="class|unique|nonempty"
+		visibility="createFragmentArgs"
+        suggest="${underscoreToCamelCase(classToResource(fragmentClass))}Args"
+	    default="MainArgs"
+	    help="The name of the fragment args to create" />
+		
+    <parameter
+        id="fragmentLayout"
+        name="Fragment Layout Name"
+        type="string"
+        constraints="layout|unique|nonempty"
+        suggest="fragment_${classToResource(fragmentClass)}"
+        default="main_fragment"
+        help="The name of the layout to create for the fragment" />
+
+    <parameter
+        id="viewModelClass"
+        name="ViewModel Name"
+        type="string"
+        constraints="class|unique|nonempty"
+        suggest="${underscoreToCamelCase(classToResource(fragmentClass))}ViewModel"
+        default="MainViewModel"
+        help="The name of the view model class to create" />
+		
+	 <parameter
+	    id="actionClass"
+	    name="Action Name"
+	    type="string"
+	    constraints="class|unique|nonempty"
+	    suggest="${underscoreToCamelCase(classToResource(fragmentClass))}Action"
+	    default="MainAction"
+	    help="The name of the action class to create" />
+			
+	  <parameter
+		 id="viewStateClass"
+		 name="ViewState Name"
+		 type="string"
+		 constraints="class|unique|nonempty"
+		 suggest="${underscoreToCamelCase(classToResource(fragmentClass))}ViewState"
+		 default="MainViewState"
+		 help="The name of the ViewState class to create" />
+
+	 <parameter
+   	    id="createViewEvents"
+   	    name="Create ViewEvents"
+   	    type="boolean"
+   	    default="false"
+   	    help="If true, you will have a view events" />
+		
+	 <parameter
+	    id="viewEventsClass"
+	    name="ViewEvents Class"
+	    type="string"
+	    constraints="class|unique|nonempty"
+	    visibility="createViewEvents"
+
+        suggest="${underscoreToCamelCase(classToResource(fragmentClass))}ViewEvents"
+	    default="MainViewEvents"
+	    help="The name of the view events to create" />
+
+
+		
+    <parameter
+        id="packageName"
+        name="Package name"
+        type="string"
+        constraints="package"
+        default="com.mycompany.myapp" />
+
+    <globals file="globals.xml.ftl" />
+    <execute file="recipe.xml.ftl" />
+
+</template>
diff --git a/tools/templates/configure.sh b/tools/templates/configure.sh
new file mode 100755
index 0000000000..eb2aa0dbec
--- /dev/null
+++ b/tools/templates/configure.sh
@@ -0,0 +1,24 @@
+#!/usr/bin/env bash
+
+#
+# Copyright 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.
+#
+
+echo "Configure RiotX Template..."
+{
+ln -s $(pwd)/RiotXFeature /Applications/Android\ Studio.app/Contents/plugins/android/lib/templates/other
+} && {
+  echo "Please restart Android Studio."
+}
diff --git a/vector/build.gradle b/vector/build.gradle
index ee437eabee..459b297fd6 100644
--- a/vector/build.gradle
+++ b/vector/build.gradle
@@ -15,7 +15,7 @@ androidExtensions {
 }
 
 ext.versionMajor = 0
-ext.versionMinor = 19
+ext.versionMinor = 20
 ext.versionPatch = 0
 
 static def getGitTimestamp() {
@@ -104,13 +104,13 @@ ext.abiVersionCodes = ["armeabi-v7a": 1, "arm64-v8a": 2, "x86": 3, "x86_64": 4].
 def buildNumber = System.env.BUILDKITE_BUILD_NUMBER as Integer ?: 0
 
 android {
-    compileSdkVersion 28
+    compileSdkVersion 29
     defaultConfig {
         applicationId "im.vector.riotx"
         // Set to API 19 because motionLayout is min API 18.
         // In the future we may consider using an alternative of MotionLayout to support API 16. But for security reason, maybe not.
         minSdkVersion 19
-        targetSdkVersion 28
+        targetSdkVersion 29
         multiDexEnabled true
 
         // `develop` branch will have version code from timestamp, to ensure each build from CI has a incremented versionCode.
@@ -235,6 +235,15 @@ android {
     kotlinOptions {
         jvmTarget = "1.8"
     }
+
+    sourceSets {
+        androidTest {
+            java.srcDirs += "src/sharedTest/java"
+        }
+        test {
+            java.srcDirs += "src/sharedTest/java"
+        }
+    }
 }
 
 dependencies {
@@ -250,6 +259,7 @@ dependencies {
     def daggerVersion = '2.25.4'
     def autofill_version = "1.0.0"
     def work_version = '2.3.3'
+    def arch_version = '2.1.0'
 
     implementation project(":matrix-sdk-android")
     implementation project(":matrix-sdk-android-rx")
@@ -378,10 +388,18 @@ dependencies {
     // TESTS
     testImplementation 'junit:junit:4.12'
     testImplementation 'org.amshove.kluent:kluent-android:1.44'
+    // Plant Timber tree for test
+    testImplementation 'net.lachlanmckee:timber-junit-rule:1.0.1'
 
+    androidTestImplementation 'androidx.test:core:1.2.0'
     androidTestImplementation 'androidx.test:runner:1.2.0'
+    androidTestImplementation 'androidx.test:rules:1.2.0'
+    androidTestImplementation 'androidx.test.ext:junit:1.1.1'
     androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
     androidTestImplementation 'org.amshove.kluent:kluent-android:1.44'
+    androidTestImplementation "androidx.arch.core:core-testing:$arch_version"
+    // Plant Timber tree for test
+    androidTestImplementation 'net.lachlanmckee:timber-junit-rule:1.0.1'
 }
 
 if (getGradle().getStartParameter().getTaskRequests().toString().contains("Gplay")) {
diff --git a/vector/src/androidTest/java/im/vector/riotx/InstrumentedTest.kt b/vector/src/androidTest/java/im/vector/riotx/InstrumentedTest.kt
new file mode 100644
index 0000000000..c34a3ef67b
--- /dev/null
+++ b/vector/src/androidTest/java/im/vector/riotx/InstrumentedTest.kt
@@ -0,0 +1,32 @@
+/*
+ * 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.riotx
+
+import android.content.Context
+import androidx.test.core.app.ApplicationProvider
+import im.vector.riotx.test.shared.createTimberTestRule
+import org.junit.Rule
+
+interface InstrumentedTest {
+
+    @Rule
+    fun timberTestRule() = createTimberTestRule()
+
+    fun context(): Context {
+        return ApplicationProvider.getApplicationContext()
+    }
+}
diff --git a/vector/src/androidTest/java/im/vector/riotx/features/reactions/data/EmojiDataSourceTest.kt b/vector/src/androidTest/java/im/vector/riotx/features/reactions/data/EmojiDataSourceTest.kt
new file mode 100644
index 0000000000..a3e45c3cf2
--- /dev/null
+++ b/vector/src/androidTest/java/im/vector/riotx/features/reactions/data/EmojiDataSourceTest.kt
@@ -0,0 +1,95 @@
+/*
+ * 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.riotx.features.reactions.data
+
+import im.vector.riotx.InstrumentedTest
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertTrue
+import org.junit.FixMethodOrder
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+import org.junit.runners.MethodSorters
+import kotlin.system.measureTimeMillis
+
+@RunWith(JUnit4::class)
+@FixMethodOrder(MethodSorters.JVM)
+class EmojiDataSourceTest : InstrumentedTest {
+
+    @Test
+    fun checkParsingTime() {
+        val time = measureTimeMillis {
+            EmojiDataSource(context().resources)
+        }
+
+        assertTrue("Too long to parse", time < 100)
+    }
+
+    @Test
+    fun checkNumberOfResult() {
+        val emojiDataSource = EmojiDataSource(context().resources)
+
+        assertEquals("Wrong number of emojis", 1545, emojiDataSource.rawData.emojis.size)
+        assertEquals("Wrong number of categories", 8, emojiDataSource.rawData.categories.size)
+        assertEquals("Wrong number of aliases", 57, emojiDataSource.rawData.aliases.size)
+    }
+
+    @Test
+    fun searchTestEmptySearch() {
+        val emojiDataSource = EmojiDataSource(context().resources)
+
+        assertEquals("Empty search should return 1545 results", 1545, emojiDataSource.filterWith("").size)
+    }
+
+    @Test
+    fun searchTestNoResult() {
+        val emojiDataSource = EmojiDataSource(context().resources)
+
+        assertTrue("Should not have result", emojiDataSource.filterWith("noresult").isEmpty())
+    }
+
+    @Test
+    fun searchTestOneResult() {
+        val emojiDataSource = EmojiDataSource(context().resources)
+
+        assertEquals("Should have 1 result", 1, emojiDataSource.filterWith("france").size)
+    }
+
+    @Test
+    fun searchTestManyResult() {
+        val emojiDataSource = EmojiDataSource(context().resources)
+
+        assertTrue("Should have many result", emojiDataSource.filterWith("fra").size > 1)
+    }
+
+    @Test
+    fun testTada() {
+        val emojiDataSource = EmojiDataSource(context().resources)
+
+        val result = emojiDataSource.filterWith("tada")
+
+        assertEquals("Should find tada emoji", 1, result.size)
+        assertEquals("Should find tada emoji", "🎉", result[0].emoji)
+    }
+
+    @Test
+    fun testQuickReactions() {
+        val emojiDataSource = EmojiDataSource(context().resources)
+
+        assertEquals("Should have 8 quick reactions", 8, emojiDataSource.getQuickReactions().size)
+    }
+}
diff --git a/vector/src/debug/java/im/vector/riotx/receivers/DebugReceiver.kt b/vector/src/debug/java/im/vector/riotx/receivers/DebugReceiver.kt
index 887fba364c..914d7923df 100644
--- a/vector/src/debug/java/im/vector/riotx/receivers/DebugReceiver.kt
+++ b/vector/src/debug/java/im/vector/riotx/receivers/DebugReceiver.kt
@@ -21,7 +21,7 @@ import android.content.Context
 import android.content.Intent
 import android.content.IntentFilter
 import android.content.SharedPreferences
-import android.preference.PreferenceManager
+import androidx.preference.PreferenceManager
 import androidx.core.content.edit
 import im.vector.riotx.core.utils.lsFiles
 import timber.log.Timber
diff --git a/vector/src/gplay/java/im/vector/riotx/push/fcm/FcmHelper.kt b/vector/src/gplay/java/im/vector/riotx/push/fcm/FcmHelper.kt
index 136949d66f..d62aaf0f3d 100755
--- a/vector/src/gplay/java/im/vector/riotx/push/fcm/FcmHelper.kt
+++ b/vector/src/gplay/java/im/vector/riotx/push/fcm/FcmHelper.kt
@@ -19,7 +19,7 @@ package im.vector.riotx.push.fcm
 
 import android.app.Activity
 import android.content.Context
-import android.preference.PreferenceManager
+import androidx.preference.PreferenceManager
 import android.widget.Toast
 import com.google.android.gms.common.ConnectionResult
 import com.google.android.gms.common.GoogleApiAvailability
diff --git a/vector/src/main/java/im/vector/riotx/VectorApplication.kt b/vector/src/main/java/im/vector/riotx/VectorApplication.kt
index bd85596924..2bceb38b75 100644
--- a/vector/src/main/java/im/vector/riotx/VectorApplication.kt
+++ b/vector/src/main/java/im/vector/riotx/VectorApplication.kt
@@ -56,6 +56,7 @@ import im.vector.riotx.features.version.VersionProvider
 import im.vector.riotx.push.fcm.FcmHelper
 import timber.log.Timber
 import java.text.SimpleDateFormat
+import java.util.concurrent.Executors
 import java.util.Date
 import java.util.Locale
 import javax.inject.Inject
@@ -146,7 +147,7 @@ class VectorApplication : Application(), HasVectorInjector, MatrixConfiguration.
 
     override fun providesMatrixConfiguration() = MatrixConfiguration(BuildConfig.FLAVOR_DESCRIPTION)
 
-    override fun getWorkManagerConfiguration() = androidx.work.Configuration.Builder().build()
+    override fun getWorkManagerConfiguration() = androidx.work.Configuration.Builder().setExecutor(Executors.newCachedThreadPool()).build()
 
     override fun injector(): VectorComponent {
         return vectorComponent
@@ -171,7 +172,7 @@ class VectorApplication : Application(), HasVectorInjector, MatrixConfiguration.
         MultiDex.install(this)
     }
 
-    override fun onConfigurationChanged(newConfig: Configuration?) {
+    override fun onConfigurationChanged(newConfig: Configuration) {
         super.onConfigurationChanged(newConfig)
         vectorConfiguration.onConfigurationChanged()
     }
diff --git a/vector/src/main/java/im/vector/riotx/core/di/FragmentModule.kt b/vector/src/main/java/im/vector/riotx/core/di/FragmentModule.kt
index c68972cdd4..db62ddc2d8 100644
--- a/vector/src/main/java/im/vector/riotx/core/di/FragmentModule.kt
+++ b/vector/src/main/java/im/vector/riotx/core/di/FragmentModule.kt
@@ -26,10 +26,13 @@ import im.vector.riotx.features.attachments.preview.AttachmentsPreviewFragment
 import im.vector.riotx.features.createdirect.CreateDirectRoomDirectoryUsersFragment
 import im.vector.riotx.features.createdirect.CreateDirectRoomKnownUsersFragment
 import im.vector.riotx.features.crypto.keysbackup.settings.KeysBackupSettingsFragment
+import im.vector.riotx.features.crypto.quads.SharedSecuredStorageKeyFragment
+import im.vector.riotx.features.crypto.quads.SharedSecuredStoragePassphraseFragment
 import im.vector.riotx.features.crypto.recover.BootstrapAccountPasswordFragment
 import im.vector.riotx.features.crypto.recover.BootstrapConclusionFragment
 import im.vector.riotx.features.crypto.recover.BootstrapConfirmPassphraseFragment
 import im.vector.riotx.features.crypto.recover.BootstrapEnterPassphraseFragment
+import im.vector.riotx.features.crypto.recover.BootstrapMigrateBackupFragment
 import im.vector.riotx.features.crypto.recover.BootstrapSaveRecoveryKeyFragment
 import im.vector.riotx.features.crypto.recover.BootstrapWaitingFragment
 import im.vector.riotx.features.crypto.verification.cancel.VerificationCancelFragment
@@ -80,6 +83,7 @@ import im.vector.riotx.features.settings.VectorSettingsNotificationPreferenceFra
 import im.vector.riotx.features.settings.VectorSettingsNotificationsTroubleshootFragment
 import im.vector.riotx.features.settings.VectorSettingsPreferencesFragment
 import im.vector.riotx.features.settings.VectorSettingsSecurityPrivacyFragment
+import im.vector.riotx.features.settings.account.deactivation.DeactivateAccountFragment
 import im.vector.riotx.features.settings.crosssigning.CrossSigningSettingsFragment
 import im.vector.riotx.features.settings.devices.VectorSettingsDevicesFragment
 import im.vector.riotx.features.settings.devtools.AccountDataFragment
@@ -444,4 +448,24 @@ interface FragmentModule {
     @IntoMap
     @FragmentKey(BootstrapAccountPasswordFragment::class)
     fun bindBootstrapAccountPasswordFragment(fragment: BootstrapAccountPasswordFragment): Fragment
+
+    @Binds
+    @IntoMap
+    @FragmentKey(BootstrapMigrateBackupFragment::class)
+    fun bindBootstrapMigrateBackupFragment(fragment: BootstrapMigrateBackupFragment): Fragment
+
+    @Binds
+    @IntoMap
+    @FragmentKey(DeactivateAccountFragment::class)
+    fun bindDeactivateAccountFragment(fragment: DeactivateAccountFragment): Fragment
+
+    @Binds
+    @IntoMap
+    @FragmentKey(SharedSecuredStoragePassphraseFragment::class)
+    fun bindSharedSecuredStoragePassphraseFragment(fragment: SharedSecuredStoragePassphraseFragment): Fragment
+
+    @Binds
+    @IntoMap
+    @FragmentKey(SharedSecuredStorageKeyFragment::class)
+    fun bindSharedSecuredStorageKeyFragment(fragment: SharedSecuredStorageKeyFragment): Fragment
 }
diff --git a/vector/src/main/java/im/vector/riotx/core/dialogs/ManuallyVerifyDialog.kt b/vector/src/main/java/im/vector/riotx/core/dialogs/ManuallyVerifyDialog.kt
new file mode 100644
index 0000000000..9863f7030f
--- /dev/null
+++ b/vector/src/main/java/im/vector/riotx/core/dialogs/ManuallyVerifyDialog.kt
@@ -0,0 +1,52 @@
+/*
+ * 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.riotx.core.dialogs
+
+import android.app.Activity
+import android.widget.TextView
+import androidx.appcompat.app.AlertDialog
+import im.vector.matrix.android.api.extensions.getFingerprintHumanReadable
+import im.vector.matrix.android.internal.crypto.model.CryptoDeviceInfo
+import im.vector.riotx.R
+
+object ManuallyVerifyDialog {
+
+    fun show(activity: Activity, cryptoDeviceInfo: CryptoDeviceInfo, onVerified: (() -> Unit)) {
+        val dialogLayout = activity.layoutInflater.inflate(R.layout.dialog_device_verify, null)
+        val builder = AlertDialog.Builder(activity)
+                .setTitle(R.string.cross_signing_verify_by_text)
+                .setView(dialogLayout)
+                .setPositiveButton(R.string.encryption_information_verify) { _, _ ->
+                    onVerified()
+                }
+                .setNegativeButton(R.string.cancel, null)
+
+        dialogLayout.findViewById<TextView>(R.id.encrypted_device_info_device_name)?.let {
+            it.text = cryptoDeviceInfo.displayName()
+        }
+
+        dialogLayout.findViewById<TextView>(R.id.encrypted_device_info_device_id)?.let {
+            it.text = cryptoDeviceInfo.deviceId
+        }
+
+        dialogLayout.findViewById<TextView>(R.id.encrypted_device_info_device_key)?.let {
+            it.text = cryptoDeviceInfo.getFingerprintHumanReadable()
+        }
+
+        builder.show()
+    }
+}
diff --git a/vector/src/main/java/im/vector/riotx/core/error/ErrorFormatter.kt b/vector/src/main/java/im/vector/riotx/core/error/ErrorFormatter.kt
index 88b6ef5463..557bc93bb1 100644
--- a/vector/src/main/java/im/vector/riotx/core/error/ErrorFormatter.kt
+++ b/vector/src/main/java/im/vector/riotx/core/error/ErrorFormatter.kt
@@ -18,6 +18,7 @@ package im.vector.riotx.core.error
 
 import im.vector.matrix.android.api.failure.Failure
 import im.vector.matrix.android.api.failure.MatrixError
+import im.vector.matrix.android.api.failure.isInvalidPassword
 import im.vector.riotx.R
 import im.vector.riotx.core.resources.StringProvider
 import java.net.HttpURLConnection
@@ -54,8 +55,7 @@ class DefaultErrorFormatter @Inject constructor(
                         // Special case for terms and conditions
                         stringProvider.getString(R.string.error_terms_not_accepted)
                     }
-                    throwable.error.code == MatrixError.M_FORBIDDEN
-                            && throwable.error.message == "Invalid password" -> {
+                    throwable.isInvalidPassword()                            -> {
                         stringProvider.getString(R.string.auth_invalid_login_param)
                     }
                     throwable.error.code == MatrixError.M_USER_IN_USE        -> {
@@ -67,7 +67,7 @@ class DefaultErrorFormatter @Inject constructor(
                     throwable.error.code == MatrixError.M_NOT_JSON           -> {
                         stringProvider.getString(R.string.login_error_not_json)
                     }
-                    throwable.error.code == MatrixError.M_THREEPID_DENIED           -> {
+                    throwable.error.code == MatrixError.M_THREEPID_DENIED    -> {
                         stringProvider.getString(R.string.login_error_threepid_denied)
                     }
                     throwable.error.code == MatrixError.M_LIMIT_EXCEEDED     -> {
diff --git a/vector/src/main/java/im/vector/riotx/core/files/FileSaver.kt b/vector/src/main/java/im/vector/riotx/core/files/FileSaver.kt
index 677f7894e8..f978e20ca9 100644
--- a/vector/src/main/java/im/vector/riotx/core/files/FileSaver.kt
+++ b/vector/src/main/java/im/vector/riotx/core/files/FileSaver.kt
@@ -17,7 +17,10 @@
 package im.vector.riotx.core.files
 
 import android.app.DownloadManager
+import android.content.ContentValues
 import android.content.Context
+import android.os.Build
+import android.provider.MediaStore
 import androidx.annotation.WorkerThread
 import arrow.core.Try
 import okio.buffer
@@ -54,10 +57,24 @@ fun addEntryToDownloadManager(context: Context,
                               mimeType: String,
                               title: String = file.name,
                               description: String = file.name) {
-    val downloadManager = context.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager?
-
     try {
-        downloadManager?.addCompletedDownload(title, description, true, mimeType, file.absolutePath, file.length(), true)
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
+            val contentValues = ContentValues().apply {
+                put(MediaStore.Downloads.TITLE, title)
+                put(MediaStore.Downloads.DISPLAY_NAME, description)
+                put(MediaStore.Downloads.MIME_TYPE, mimeType)
+                put(MediaStore.Downloads.SIZE, file.length())
+            }
+            context.contentResolver.insert(MediaStore.Downloads.EXTERNAL_CONTENT_URI, contentValues)?.let { uri ->
+                context.contentResolver.openOutputStream(uri)?.use { outputStream ->
+                    outputStream.sink().buffer().write(file.inputStream().use { it.readBytes() })
+                }
+            }
+        } else {
+            val downloadManager = context.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager?
+            @Suppress("DEPRECATION")
+            downloadManager?.addCompletedDownload(title, description, true, mimeType, file.absolutePath, file.length(), true)
+        }
     } catch (e: Exception) {
         Timber.e(e, "## addEntryToDownloadManager(): Exception")
     }
diff --git a/vector/src/main/java/im/vector/riotx/core/glide/VectorGlideModelLoader.kt b/vector/src/main/java/im/vector/riotx/core/glide/VectorGlideModelLoader.kt
index 1a90b0c34f..191ab6d972 100644
--- a/vector/src/main/java/im/vector/riotx/core/glide/VectorGlideModelLoader.kt
+++ b/vector/src/main/java/im/vector/riotx/core/glide/VectorGlideModelLoader.kt
@@ -95,7 +95,7 @@ class VectorGlideDataFetcher(private val activeSessionHolder: ActiveSessionHolde
 
     override fun loadData(priority: Priority, callback: DataFetcher.DataCallback<in InputStream>) {
         Timber.v("Load data: $data")
-        if (data.isLocalFile()) {
+        if (data.isLocalFile() && data.url != null) {
             val initialFile = File(data.url)
             callback.onDataReady(FileInputStream(initialFile))
             return
diff --git a/vector/src/main/java/im/vector/riotx/core/images/ImageTools.kt b/vector/src/main/java/im/vector/riotx/core/images/ImageTools.kt
deleted file mode 100644
index 84cba7392f..0000000000
--- a/vector/src/main/java/im/vector/riotx/core/images/ImageTools.kt
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright 2019 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.riotx.core.images
-
-import android.content.Context
-import android.net.Uri
-import android.provider.MediaStore
-import androidx.exifinterface.media.ExifInterface
-import timber.log.Timber
-import javax.inject.Inject
-
-class ImageTools @Inject constructor(private val context: Context) {
-
-    /**
-     * Gets the [ExifInterface] value for the orientation for this local bitmap Uri.
-     *
-     * @param uri The URI to find the orientation for.  Must be local.
-     * @return    The orientation value, which may be [ExifInterface.ORIENTATION_UNDEFINED].
-     */
-    fun getOrientationForBitmap(uri: Uri): Int {
-        var orientation = ExifInterface.ORIENTATION_UNDEFINED
-
-        if (uri.scheme == "content") {
-            val proj = arrayOf(MediaStore.Images.Media.DATA)
-            try {
-                val cursor = context.contentResolver.query(uri, proj, null, null, null)
-                cursor?.use {
-                    if (it.moveToFirst()) {
-                        val idxData = it.getColumnIndexOrThrow(MediaStore.Images.Media.DATA)
-                        val path = it.getString(idxData)
-                        if (path.isNullOrBlank()) {
-                            Timber.w("Cannot find path in media db for uri $uri")
-                            return orientation
-                        }
-                        val exif = ExifInterface(path)
-                        orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED)
-                    }
-                }
-            } catch (e: Exception) {
-                // eg SecurityException from com.google.android.apps.photos.content.GooglePhotosImageProvider URIs
-                // eg IOException from trying to parse the returned path as a file when it is an http uri.
-                Timber.e(e, "Cannot get orientation for bitmap")
-            }
-        } else if (uri.scheme == "file") {
-            try {
-                val path = uri.path
-                if (path != null) {
-                    val exif = ExifInterface(path)
-                    orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED)
-                }
-            } catch (e: Exception) {
-                Timber.e(e, "Cannot get EXIF for file uri $uri")
-            }
-        }
-
-        return orientation
-    }
-}
diff --git a/vector/src/main/java/im/vector/riotx/core/platform/EllipsizingTextView.kt b/vector/src/main/java/im/vector/riotx/core/platform/EllipsizingTextView.kt
index 2e5786b57d..f451308c36 100644
--- a/vector/src/main/java/im/vector/riotx/core/platform/EllipsizingTextView.kt
+++ b/vector/src/main/java/im/vector/riotx/core/platform/EllipsizingTextView.kt
@@ -333,7 +333,7 @@ class EllipsizingTextView @JvmOverloads constructor(context: Context, attrs: Att
          * @param workingText text to strip end punctuation from
          * @return Text without end punctuation.
          */
-        fun stripEndPunctuation(workingText: CharSequence?): String {
+        fun stripEndPunctuation(workingText: CharSequence): String {
             return mEndPunctPattern!!.matcher(workingText).replaceFirst("")
         }
     }
diff --git a/vector/src/main/java/im/vector/riotx/core/platform/VectorBaseActivity.kt b/vector/src/main/java/im/vector/riotx/core/platform/VectorBaseActivity.kt
index 2649662ee5..08cf8e57e1 100644
--- a/vector/src/main/java/im/vector/riotx/core/platform/VectorBaseActivity.kt
+++ b/vector/src/main/java/im/vector/riotx/core/platform/VectorBaseActivity.kt
@@ -23,6 +23,7 @@ import android.os.Parcelable
 import android.view.Menu
 import android.view.MenuItem
 import android.view.View
+import android.view.WindowManager
 import androidx.annotation.AttrRes
 import androidx.annotation.LayoutRes
 import androidx.annotation.MainThread
@@ -134,7 +135,7 @@ abstract class VectorBaseActivity : AppCompatActivity(), HasScreenInjector {
         restorables.forEach { it.onSaveInstanceState(outState) }
     }
 
-    override fun onRestoreInstanceState(savedInstanceState: Bundle?) {
+    override fun onRestoreInstanceState(savedInstanceState: Bundle) {
         restorables.forEach { it.onRestoreInstanceState(savedInstanceState) }
         super.onRestoreInstanceState(savedInstanceState)
     }
@@ -183,6 +184,11 @@ abstract class VectorBaseActivity : AppCompatActivity(), HasScreenInjector {
             handleGlobalError(it)
         }
 
+        // Set flag FLAG_SECURE
+        if (vectorPreferences.useFlagSecure()) {
+            window.addFlags(WindowManager.LayoutParams.FLAG_SECURE)
+        }
+
         doBeforeSetContentView()
 
         if (getLayoutRes() != -1) {
diff --git a/vector/src/main/java/im/vector/riotx/core/platform/VectorViewModel.kt b/vector/src/main/java/im/vector/riotx/core/platform/VectorViewModel.kt
index bda4426c45..e82e8b3856 100644
--- a/vector/src/main/java/im/vector/riotx/core/platform/VectorViewModel.kt
+++ b/vector/src/main/java/im/vector/riotx/core/platform/VectorViewModel.kt
@@ -30,6 +30,10 @@ import io.reactivex.Single
 abstract class VectorViewModel<S : MvRxState, VA : VectorViewModelAction, VE : VectorViewEvents>(initialState: S)
     : BaseMvRxViewModel<S>(initialState, false) {
 
+    interface Factory<S: MvRxState> {
+        fun create(state: S): BaseMvRxViewModel<S>
+    }
+
     // Used to post transient events to the View
     protected val _viewEvents = PublishDataSource<VE>()
     val viewEvents: DataSource<VE> = _viewEvents
diff --git a/vector/src/main/java/im/vector/riotx/core/platform/ViewModelTask.kt b/vector/src/main/java/im/vector/riotx/core/platform/ViewModelTask.kt
new file mode 100644
index 0000000000..abe5cc9095
--- /dev/null
+++ b/vector/src/main/java/im/vector/riotx/core/platform/ViewModelTask.kt
@@ -0,0 +1,34 @@
+/*
+ * 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.riotx.core.platform
+
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.async
+import kotlinx.coroutines.launch
+
+interface ViewModelTask<Params, Result> {
+    operator fun invoke(
+            scope: CoroutineScope,
+            params: Params,
+            onResult: (Result) -> Unit = {}
+    ) {
+        val backgroundJob = scope.async { execute(params) }
+        scope.launch { onResult(backgroundJob.await()) }
+    }
+
+    suspend fun execute(params: Params): Result
+}
diff --git a/vector/src/main/java/im/vector/riotx/core/services/CallService.kt b/vector/src/main/java/im/vector/riotx/core/services/CallService.kt
index f36b289aaa..30ab62d5b2 100644
--- a/vector/src/main/java/im/vector/riotx/core/services/CallService.kt
+++ b/vector/src/main/java/im/vector/riotx/core/services/CallService.kt
@@ -128,13 +128,13 @@ class CallService : VectorService() {
      * Display a call in progress notification.
      */
     private fun displayCallInProgressNotification(intent: Intent) {
-        val callId = intent.getStringExtra(EXTRA_CALL_ID)
+        val callId = intent.getStringExtra(EXTRA_CALL_ID) ?: ""
 
         val notification = notificationUtils.buildPendingCallNotification(
                 intent.getBooleanExtra(EXTRA_IS_VIDEO, false),
-                intent.getStringExtra(EXTRA_ROOM_NAME),
-                intent.getStringExtra(EXTRA_ROOM_ID),
-                intent.getStringExtra(EXTRA_MATRIX_ID),
+                intent.getStringExtra(EXTRA_ROOM_NAME) ?: "",
+                intent.getStringExtra(EXTRA_ROOM_ID) ?: "",
+                intent.getStringExtra(EXTRA_MATRIX_ID) ?: "",
                 callId)
 
         startForeground(NOTIFICATION_ID, notification)
diff --git a/vector/src/main/java/im/vector/riotx/core/ui/list/GenericButtonItem.kt b/vector/src/main/java/im/vector/riotx/core/ui/list/GenericButtonItem.kt
new file mode 100644
index 0000000000..c0fdb010a5
--- /dev/null
+++ b/vector/src/main/java/im/vector/riotx/core/ui/list/GenericButtonItem.kt
@@ -0,0 +1,65 @@
+/*
+ * 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.riotx.core.ui.list
+
+import android.view.View
+import androidx.annotation.ColorInt
+import androidx.annotation.DrawableRes
+import com.airbnb.epoxy.EpoxyAttribute
+import com.airbnb.epoxy.EpoxyModelClass
+import com.google.android.material.button.MaterialButton
+import im.vector.riotx.R
+import im.vector.riotx.core.epoxy.VectorEpoxyHolder
+import im.vector.riotx.core.epoxy.VectorEpoxyModel
+import im.vector.riotx.features.themes.ThemeUtils
+
+/**
+ * A generic button list item.
+ */
+@EpoxyModelClass(layout = R.layout.item_generic_button)
+abstract class GenericButtonItem : VectorEpoxyModel<GenericButtonItem.Holder>() {
+
+    @EpoxyAttribute
+    var text: String? = null
+
+    @EpoxyAttribute
+    var itemClickAction: View.OnClickListener? = null
+
+    @EpoxyAttribute
+    @ColorInt
+    var textColor: Int? = null
+
+    @EpoxyAttribute
+    @DrawableRes
+    var iconRes: Int? = null
+
+    override fun bind(holder: Holder) {
+        holder.button.text = text
+        val textColor = textColor ?: ThemeUtils.getColor(holder.view.context, R.attr.riotx_text_primary)
+        holder.button.setTextColor(textColor)
+        if (iconRes != null) {
+            holder.button.setIconResource(iconRes!!)
+        } else {
+            holder.button.icon = null
+        }
+
+        itemClickAction?.let { holder.view.setOnClickListener(it) }
+    }
+
+    class Holder : VectorEpoxyHolder() {
+        val button by bind<MaterialButton>(R.id.itemGenericItemButton)
+    }
+}
diff --git a/vector/src/main/java/im/vector/riotx/core/ui/views/KeysBackupBanner.kt b/vector/src/main/java/im/vector/riotx/core/ui/views/KeysBackupBanner.kt
index 8d314f9e58..817575d91a 100755
--- a/vector/src/main/java/im/vector/riotx/core/ui/views/KeysBackupBanner.kt
+++ b/vector/src/main/java/im/vector/riotx/core/ui/views/KeysBackupBanner.kt
@@ -17,7 +17,7 @@
 package im.vector.riotx.core.ui.views
 
 import android.content.Context
-import android.preference.PreferenceManager
+import androidx.preference.PreferenceManager
 import android.util.AttributeSet
 import android.view.View
 import android.view.ViewGroup
@@ -159,7 +159,7 @@ class KeysBackupBanner @JvmOverloads constructor(
         render(state, true)
     }
 
-    // PRIVATE METHODS *****************************************************************************************************************************************
+    // PRIVATE METHODS ****************************************************************************************************************************************
 
     private fun setupView() {
         inflate(context, R.layout.view_keys_backup_banner, this)
diff --git a/vector/src/main/java/im/vector/riotx/core/ui/views/NotificationAreaView.kt b/vector/src/main/java/im/vector/riotx/core/ui/views/NotificationAreaView.kt
index 145a26aed2..1c1f3fae1a 100644
--- a/vector/src/main/java/im/vector/riotx/core/ui/views/NotificationAreaView.kt
+++ b/vector/src/main/java/im/vector/riotx/core/ui/views/NotificationAreaView.kt
@@ -87,7 +87,7 @@ class NotificationAreaView @JvmOverloads constructor(
         }
     }
 
-    // PRIVATE METHODS *****************************************************************************************************************************************
+    // PRIVATE METHODS ****************************************************************************************************************************************
 
     private fun setupView() {
         inflate(context, R.layout.view_notification_area, this)
diff --git a/vector/src/main/java/im/vector/riotx/core/utils/Debouncer.kt b/vector/src/main/java/im/vector/riotx/core/utils/Debouncer.kt
index 627d757574..95035f6c96 100644
--- a/vector/src/main/java/im/vector/riotx/core/utils/Debouncer.kt
+++ b/vector/src/main/java/im/vector/riotx/core/utils/Debouncer.kt
@@ -37,9 +37,10 @@ class Debouncer(private val handler: Handler) {
 
     fun cancel(identifier: String) {
         if (runnables.containsKey(identifier)) {
-            val old = runnables[identifier]
-            handler.removeCallbacks(old)
-            runnables.remove(identifier)
+            runnables[identifier]?.let {
+                handler.removeCallbacks(it)
+                runnables.remove(identifier)
+            }
         }
     }
 
diff --git a/vector/src/main/java/im/vector/riotx/core/utils/EvenBetterLinkMovementMethod.kt b/vector/src/main/java/im/vector/riotx/core/utils/EvenBetterLinkMovementMethod.kt
new file mode 100644
index 0000000000..1e565c0f4b
--- /dev/null
+++ b/vector/src/main/java/im/vector/riotx/core/utils/EvenBetterLinkMovementMethod.kt
@@ -0,0 +1,48 @@
+/*
+ * 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.riotx.core.utils
+
+import android.text.Spanned
+import android.text.style.ClickableSpan
+import android.text.style.URLSpan
+import android.widget.TextView
+import me.saket.bettermovementmethod.BetterLinkMovementMethod
+
+class EvenBetterLinkMovementMethod(private val onLinkClickListener: OnLinkClickListener? = null) : BetterLinkMovementMethod() {
+
+    interface OnLinkClickListener {
+        /**
+         * @param textView   The TextView on which a click was registered.
+         * @param span       The ClickableSpan which is clicked on.
+         * @param url        The clicked URL.
+         * @param actualText The original text which is spanned. Can be used to compare actualText and target url to prevent misleading urls.
+         * @return true if this click was handled, false to let Android handle the URL.
+         */
+        fun onLinkClicked(textView: TextView, span: ClickableSpan, url: String, actualText: String): Boolean
+    }
+
+    override fun dispatchUrlClick(textView: TextView, clickableSpan: ClickableSpan) {
+        val spanned = textView.text as Spanned
+        val actualText = textView.text.subSequence(spanned.getSpanStart(clickableSpan), spanned.getSpanEnd(clickableSpan)).toString()
+        val url = (clickableSpan as? URLSpan)?.url ?: actualText
+
+        if (onLinkClickListener == null || !onLinkClickListener.onLinkClicked(textView, clickableSpan, url, actualText)) {
+            // Let Android handle this long click as a short-click.
+            clickableSpan.onClick(textView)
+        }
+    }
+}
diff --git a/vector/src/main/java/im/vector/riotx/core/utils/ExternalApplicationsUtil.kt b/vector/src/main/java/im/vector/riotx/core/utils/ExternalApplicationsUtil.kt
index 37f6df1379..afb7c4586a 100644
--- a/vector/src/main/java/im/vector/riotx/core/utils/ExternalApplicationsUtil.kt
+++ b/vector/src/main/java/im/vector/riotx/core/utils/ExternalApplicationsUtil.kt
@@ -29,6 +29,8 @@ import androidx.core.content.FileProvider
 import androidx.fragment.app.Fragment
 import im.vector.riotx.BuildConfig
 import im.vector.riotx.R
+import okio.buffer
+import okio.sink
 import timber.log.Timber
 import java.io.File
 import java.text.SimpleDateFormat
@@ -258,6 +260,61 @@ fun shareMedia(context: Context, file: File, mediaMimeType: String?) {
     }
 }
 
+fun saveMedia(context: Context, file: File, title: String, mediaMimeType: String?): Boolean {
+    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
+        val externalContentUri: Uri
+        val values = ContentValues()
+        when {
+            mediaMimeType?.startsWith("image/") == true -> {
+                externalContentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI
+                values.put(MediaStore.Images.Media.TITLE, title)
+                values.put(MediaStore.Images.Media.DISPLAY_NAME, title)
+                values.put(MediaStore.Images.Media.MIME_TYPE, mediaMimeType)
+                values.put(MediaStore.Images.Media.DATE_ADDED, System.currentTimeMillis())
+                values.put(MediaStore.Images.Media.DATE_TAKEN, System.currentTimeMillis())
+            }
+            mediaMimeType?.startsWith("video/") == true -> {
+                externalContentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI
+                values.put(MediaStore.Video.Media.TITLE, title)
+                values.put(MediaStore.Video.Media.DISPLAY_NAME, title)
+                values.put(MediaStore.Video.Media.MIME_TYPE, mediaMimeType)
+                values.put(MediaStore.Video.Media.DATE_ADDED, System.currentTimeMillis())
+                values.put(MediaStore.Video.Media.DATE_TAKEN, System.currentTimeMillis())
+            }
+            mediaMimeType?.startsWith("audio/") == true -> {
+                externalContentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
+                values.put(MediaStore.Audio.Media.TITLE, title)
+                values.put(MediaStore.Audio.Media.DISPLAY_NAME, title)
+                values.put(MediaStore.Audio.Media.MIME_TYPE, mediaMimeType)
+                values.put(MediaStore.Audio.Media.DATE_ADDED, System.currentTimeMillis())
+                values.put(MediaStore.Audio.Media.DATE_TAKEN, System.currentTimeMillis())
+            }
+            else                                        -> {
+                externalContentUri = MediaStore.Downloads.EXTERNAL_CONTENT_URI
+                values.put(MediaStore.Downloads.TITLE, title)
+                values.put(MediaStore.Downloads.DISPLAY_NAME, title)
+                values.put(MediaStore.Downloads.MIME_TYPE, mediaMimeType)
+                values.put(MediaStore.Downloads.DATE_ADDED, System.currentTimeMillis())
+                values.put(MediaStore.Downloads.DATE_TAKEN, System.currentTimeMillis())
+            }
+        }
+        context.contentResolver.insert(externalContentUri, values)?.let { uri ->
+            context.contentResolver.openOutputStream(uri)?.use { outputStream ->
+                outputStream.sink().buffer().write(file.inputStream().use { it.readBytes() })
+                return true
+            }
+        }
+    } else {
+        @Suppress("DEPRECATION")
+        Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE).also { mediaScanIntent ->
+            mediaScanIntent.data = Uri.fromFile(file)
+            context.sendBroadcast(mediaScanIntent)
+        }
+        return true
+    }
+    return false
+}
+
 /**
  * Open the play store to the provided application Id, default to this app
  */
diff --git a/vector/src/main/java/im/vector/riotx/core/utils/FileUtils.kt b/vector/src/main/java/im/vector/riotx/core/utils/FileUtils.kt
index 1a19b49872..839356a129 100644
--- a/vector/src/main/java/im/vector/riotx/core/utils/FileUtils.kt
+++ b/vector/src/main/java/im/vector/riotx/core/utils/FileUtils.kt
@@ -73,7 +73,7 @@ private fun logAction(file: File): Boolean {
  */
 private fun recursiveActionOnFile(file: File, action: ActionOnFile): Boolean {
     if (file.isDirectory) {
-        file.list().forEach {
+        file.list()?.forEach {
             val result = recursiveActionOnFile(File(file, it), action)
 
             if (!result) {
diff --git a/vector/src/main/java/im/vector/riotx/core/utils/RingtoneUtils.kt b/vector/src/main/java/im/vector/riotx/core/utils/RingtoneUtils.kt
index 1d2b97e27e..5345658207 100644
--- a/vector/src/main/java/im/vector/riotx/core/utils/RingtoneUtils.kt
+++ b/vector/src/main/java/im/vector/riotx/core/utils/RingtoneUtils.kt
@@ -20,7 +20,7 @@ import android.content.Context
 import android.media.Ringtone
 import android.media.RingtoneManager
 import android.net.Uri
-import android.preference.PreferenceManager
+import androidx.preference.PreferenceManager
 import androidx.core.content.edit
 import im.vector.riotx.features.settings.VectorPreferences
 
diff --git a/vector/src/main/java/im/vector/riotx/core/utils/SystemUtils.kt b/vector/src/main/java/im/vector/riotx/core/utils/SystemUtils.kt
index b77553a3d6..d82134caf5 100644
--- a/vector/src/main/java/im/vector/riotx/core/utils/SystemUtils.kt
+++ b/vector/src/main/java/im/vector/riotx/core/utils/SystemUtils.kt
@@ -84,7 +84,7 @@ fun requestDisablingBatteryOptimization(activity: Activity, fragment: Fragment?,
  */
 fun copyToClipboard(context: Context, text: CharSequence, showToast: Boolean = true, @StringRes toastMessage: Int = R.string.copied_to_clipboard) {
     val clipboard = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
-    clipboard.primaryClip = ClipData.newPlainText("", text)
+    clipboard.setPrimaryClip(ClipData.newPlainText("", text))
     if (showToast) {
         context.toast(toastMessage)
     }
diff --git a/vector/src/main/java/im/vector/riotx/core/utils/TextUtils.kt b/vector/src/main/java/im/vector/riotx/core/utils/TextUtils.kt
index 75f6893c7c..9519eb1f9d 100644
--- a/vector/src/main/java/im/vector/riotx/core/utils/TextUtils.kt
+++ b/vector/src/main/java/im/vector/riotx/core/utils/TextUtils.kt
@@ -35,8 +35,8 @@ object TextUtils {
             if (value < 1000) return value.toString() // deal with easy case
 
             val e = suffixes.floorEntry(value)
-            val divideBy = e.key
-            val suffix = e.value
+            val divideBy = e?.key
+            val suffix = e?.value
 
             val truncated = value / (divideBy!! / 10) // the number part of the output times 10
             val hasDecimal = truncated < 100 && truncated / 10.0 != (truncated / 10).toDouble()
diff --git a/vector/src/main/java/im/vector/riotx/features/MainActivity.kt b/vector/src/main/java/im/vector/riotx/features/MainActivity.kt
index bc5a1aff95..a9a0cee0d6 100644
--- a/vector/src/main/java/im/vector/riotx/features/MainActivity.kt
+++ b/vector/src/main/java/im/vector/riotx/features/MainActivity.kt
@@ -34,8 +34,10 @@ import im.vector.riotx.core.utils.deleteAllFiles
 import im.vector.riotx.features.home.HomeActivity
 import im.vector.riotx.features.login.LoginActivity
 import im.vector.riotx.features.notifications.NotificationDrawerManager
+import im.vector.riotx.features.settings.VectorPreferences
 import im.vector.riotx.features.signout.hard.SignedOutActivity
 import im.vector.riotx.features.signout.soft.SoftLogoutActivity
+import im.vector.riotx.features.ui.UiStateRepository
 import kotlinx.android.parcel.Parcelize
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.GlobalScope
@@ -49,6 +51,7 @@ data class MainActivityArgs(
         val clearCache: Boolean = false,
         val clearCredentials: Boolean = false,
         val isUserLoggedOut: Boolean = false,
+        val isAccountDeactivated: Boolean = false,
         val isSoftLogout: Boolean = false
 ) : Parcelable
 
@@ -77,6 +80,8 @@ class MainActivity : VectorBaseActivity() {
     @Inject lateinit var notificationDrawerManager: NotificationDrawerManager
     @Inject lateinit var sessionHolder: ActiveSessionHolder
     @Inject lateinit var errorFormatter: ErrorFormatter
+    @Inject lateinit var vectorPreferences: VectorPreferences
+    @Inject lateinit var uiStateRepository: UiStateRepository
 
     override fun injectWith(injector: ScreenComponent) {
         injector.inject(this)
@@ -110,6 +115,7 @@ class MainActivity : VectorBaseActivity() {
                 clearCache = argsFromIntent?.clearCache ?: false,
                 clearCredentials = argsFromIntent?.clearCredentials ?: false,
                 isUserLoggedOut = argsFromIntent?.isUserLoggedOut ?: false,
+                isAccountDeactivated = argsFromIntent?.isAccountDeactivated ?: false,
                 isSoftLogout = argsFromIntent?.isSoftLogout ?: false
         )
     }
@@ -121,13 +127,20 @@ class MainActivity : VectorBaseActivity() {
             return
         }
         when {
-            args.clearCredentials -> session.signOut(
+            args.isAccountDeactivated -> {
+                // Just do the local cleanup
+                Timber.w("Account deactivated, start app")
+                sessionHolder.clearActiveSession()
+                doLocalCleanup(clearPreferences = true)
+                startNextActivityAndFinish()
+            }
+            args.clearCredentials     -> session.signOut(
                     !args.isUserLoggedOut,
                     object : MatrixCallback<Unit> {
                         override fun onSuccess(data: Unit) {
                             Timber.w("SIGN_OUT: success, start app")
                             sessionHolder.clearActiveSession()
-                            doLocalCleanup()
+                            doLocalCleanup(clearPreferences = true)
                             startNextActivityAndFinish()
                         }
 
@@ -135,10 +148,10 @@ class MainActivity : VectorBaseActivity() {
                             displayError(failure)
                         }
                     })
-            args.clearCache       -> session.clearCache(
+            args.clearCache           -> session.clearCache(
                     object : MatrixCallback<Unit> {
                         override fun onSuccess(data: Unit) {
-                            doLocalCleanup()
+                            doLocalCleanup(clearPreferences = false)
                             session.startSyncing(applicationContext)
                             startNextActivityAndFinish()
                         }
@@ -155,10 +168,15 @@ class MainActivity : VectorBaseActivity() {
         Timber.w("Ignoring invalid token global error")
     }
 
-    private fun doLocalCleanup() {
+    private fun doLocalCleanup(clearPreferences: Boolean) {
         GlobalScope.launch(Dispatchers.Main) {
             // On UI Thread
             Glide.get(this@MainActivity).clearMemory()
+
+            if (clearPreferences) {
+                vectorPreferences.clearPreferences()
+                uiStateRepository.reset()
+            }
             withContext(Dispatchers.IO) {
                 // On BG thread
                 Glide.get(this@MainActivity).clearDiskCache()
@@ -182,16 +200,16 @@ class MainActivity : VectorBaseActivity() {
     private fun startNextActivityAndFinish() {
         val intent = when {
             args.clearCredentials
-                    && !args.isUserLoggedOut ->
-                // User has explicitly asked to log out
+                    && (!args.isUserLoggedOut || args.isAccountDeactivated) ->
+                // User has explicitly asked to log out or deactivated his account
                 LoginActivity.newIntent(this, null)
-            args.isSoftLogout                ->
+            args.isSoftLogout                                               ->
                 // The homeserver has invalidated the token, with a soft logout
                 SoftLogoutActivity.newIntent(this)
-            args.isUserLoggedOut             ->
+            args.isUserLoggedOut                                            ->
                 // the homeserver has invalidated the token (password changed, device deleted, other security reasons)
                 SignedOutActivity.newIntent(this)
-            sessionHolder.hasActiveSession() ->
+            sessionHolder.hasActiveSession()                                ->
                 // We have a session.
                 // Check it can be opened
                 if (sessionHolder.getActiveSession().isOpenable) {
@@ -200,7 +218,7 @@ class MainActivity : VectorBaseActivity() {
                     // The token is still invalid
                     SoftLogoutActivity.newIntent(this)
                 }
-            else                             ->
+            else                                                            ->
                 // First start, or no active session
                 LoginActivity.newIntent(this, null)
         }
diff --git a/vector/src/main/java/im/vector/riotx/features/attachments/preview/AttachmentsPreviewActivity.kt b/vector/src/main/java/im/vector/riotx/features/attachments/preview/AttachmentsPreviewActivity.kt
index 46a90803ca..6c91f70131 100644
--- a/vector/src/main/java/im/vector/riotx/features/attachments/preview/AttachmentsPreviewActivity.kt
+++ b/vector/src/main/java/im/vector/riotx/features/attachments/preview/AttachmentsPreviewActivity.kt
@@ -43,7 +43,7 @@ class AttachmentsPreviewActivity : VectorBaseActivity(), ToolbarConfigurable {
         }
 
         fun getOutput(intent: Intent): List<ContentAttachmentData> {
-            return intent.getParcelableArrayListExtra(ATTACHMENTS_PREVIEW_RESULT)
+            return intent.getParcelableArrayListExtra(ATTACHMENTS_PREVIEW_RESULT) ?: emptyList()
         }
 
         fun getKeepOriginalSize(intent: Intent): Boolean {
diff --git a/vector/src/main/java/im/vector/riotx/features/command/Command.kt b/vector/src/main/java/im/vector/riotx/features/command/Command.kt
index 72f686c2c8..d98ebcfa73 100644
--- a/vector/src/main/java/im/vector/riotx/features/command/Command.kt
+++ b/vector/src/main/java/im/vector/riotx/features/command/Command.kt
@@ -44,6 +44,7 @@ enum class Command(val command: String, val parameters: String, @StringRes val d
     POLL("/poll", "Question | Option 1 | Option 2 ...", R.string.command_description_poll),
     SHRUG("/shrug", "<message>", R.string.command_description_shrug),
     PLAIN("/plain", "<message>", R.string.command_description_plain),
+    DISCARD_SESSION("/discardsession", "", R.string.command_description_discard_session),
     // TODO temporary command
     VERIFY_USER("/verify", "<user-id>", R.string.command_description_verify);
 
diff --git a/vector/src/main/java/im/vector/riotx/features/command/CommandParser.kt b/vector/src/main/java/im/vector/riotx/features/command/CommandParser.kt
index 875fe92610..e7d2e9a62b 100644
--- a/vector/src/main/java/im/vector/riotx/features/command/CommandParser.kt
+++ b/vector/src/main/java/im/vector/riotx/features/command/CommandParser.kt
@@ -281,6 +281,9 @@ object CommandParser {
                         ParsedCommand.ErrorSyntax(Command.POLL)
                     }
                 }
+                Command.DISCARD_SESSION.command        -> {
+                    ParsedCommand.DiscardSession
+                }
                 else                                   -> {
                     // Unknown command
                     ParsedCommand.ErrorUnknownSlashCommand(slashCommand)
diff --git a/vector/src/main/java/im/vector/riotx/features/command/ParsedCommand.kt b/vector/src/main/java/im/vector/riotx/features/command/ParsedCommand.kt
index e4fee27ee6..63e016b0b6 100644
--- a/vector/src/main/java/im/vector/riotx/features/command/ParsedCommand.kt
+++ b/vector/src/main/java/im/vector/riotx/features/command/ParsedCommand.kt
@@ -52,4 +52,5 @@ sealed class ParsedCommand {
     class SendShrug(val message: CharSequence) : ParsedCommand()
     class VerifyUser(val userId: String) : ParsedCommand()
     class SendPoll(val question: String, val options: List<String>) : ParsedCommand()
+    object DiscardSession: ParsedCommand()
 }
diff --git a/vector/src/main/java/im/vector/riotx/features/createdirect/CreateDirectRoomActivity.kt b/vector/src/main/java/im/vector/riotx/features/createdirect/CreateDirectRoomActivity.kt
index 12674e5cd2..3ae206cd21 100644
--- a/vector/src/main/java/im/vector/riotx/features/createdirect/CreateDirectRoomActivity.kt
+++ b/vector/src/main/java/im/vector/riotx/features/createdirect/CreateDirectRoomActivity.kt
@@ -28,6 +28,7 @@ import com.airbnb.mvrx.Fail
 import com.airbnb.mvrx.Loading
 import com.airbnb.mvrx.Success
 import com.airbnb.mvrx.viewModel
+import im.vector.matrix.android.api.failure.Failure
 import im.vector.matrix.android.api.session.room.failure.CreateRoomFailure
 import im.vector.riotx.R
 import im.vector.riotx.core.di.ScreenComponent
@@ -37,6 +38,7 @@ import im.vector.riotx.core.extensions.addFragmentToBackstack
 import im.vector.riotx.core.platform.SimpleFragmentActivity
 import im.vector.riotx.core.platform.WaitingViewData
 import kotlinx.android.synthetic.main.activity.*
+import java.net.HttpURLConnection
 import javax.inject.Inject
 
 class CreateDirectRoomActivity : SimpleFragmentActivity() {
@@ -91,8 +93,14 @@ class CreateDirectRoomActivity : SimpleFragmentActivity() {
         if (error is CreateRoomFailure.CreatedWithTimeout) {
             finish()
         } else {
+            val message = if (error is Failure.ServerError && error.httpCode == HttpURLConnection.HTTP_INTERNAL_ERROR /*500*/) {
+                // This error happen if the invited userId does not exist.
+                getString(R.string.create_room_dm_failure)
+            } else {
+                errorFormatter.toHumanReadable(error)
+            }
             AlertDialog.Builder(this)
-                    .setMessage(errorFormatter.toHumanReadable(error))
+                    .setMessage(message)
                     .setPositiveButton(R.string.ok, null)
                     .show()
         }
diff --git a/vector/src/main/java/im/vector/riotx/features/createdirect/DirectoryUsersController.kt b/vector/src/main/java/im/vector/riotx/features/createdirect/DirectoryUsersController.kt
index 016806f319..1c38e6f723 100644
--- a/vector/src/main/java/im/vector/riotx/features/createdirect/DirectoryUsersController.kt
+++ b/vector/src/main/java/im/vector/riotx/features/createdirect/DirectoryUsersController.kt
@@ -23,6 +23,7 @@ import com.airbnb.mvrx.Fail
 import com.airbnb.mvrx.Loading
 import com.airbnb.mvrx.Success
 import com.airbnb.mvrx.Uninitialized
+import im.vector.matrix.android.api.MatrixPatterns
 import im.vector.matrix.android.api.session.Session
 import im.vector.matrix.android.api.session.user.model.User
 import im.vector.matrix.android.api.util.toMatrixItem
@@ -56,15 +57,29 @@ class DirectoryUsersController @Inject constructor(private val session: Session,
     override fun buildModels() {
         val currentState = state ?: return
         val hasSearch = currentState.directorySearchTerm.isNotBlank()
-        val asyncUsers = currentState.directoryUsers
-        when (asyncUsers) {
+        when (val asyncUsers = currentState.directoryUsers) {
             is Uninitialized -> renderEmptyState(false)
             is Loading       -> renderLoading()
-            is Success       -> renderSuccess(asyncUsers(), currentState.selectedUsers.map { it.userId }, hasSearch)
+            is Success       -> renderSuccess(
+                    computeUsersList(asyncUsers(), currentState.directorySearchTerm),
+                    currentState.selectedUsers.map { it.userId },
+                    hasSearch
+            )
             is Fail          -> renderFailure(asyncUsers.error)
         }
     }
 
+    /**
+     * Eventually add the searched terms, if it is a userId, and if not already present in the result
+     */
+    private fun computeUsersList(directoryUsers: List<User>, searchTerms: String): List<User> {
+        return directoryUsers +
+                searchTerms
+                        .takeIf { terms -> MatrixPatterns.isUserId(terms) && !directoryUsers.any { it.userId == terms } }
+                        ?.let { listOf(User(it)) }
+                        .orEmpty()
+    }
+
     private fun renderLoading() {
         loadingItem {
             id("loading")
diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/keys/KeysExporter.kt b/vector/src/main/java/im/vector/riotx/features/crypto/keys/KeysExporter.kt
index cae8b50523..b9b75588f1 100644
--- a/vector/src/main/java/im/vector/riotx/features/crypto/keys/KeysExporter.kt
+++ b/vector/src/main/java/im/vector/riotx/features/crypto/keys/KeysExporter.kt
@@ -40,7 +40,7 @@ class KeysExporter(private val session: Session) {
             runCatching {
                 val data = awaitCallback<ByteArray> { session.cryptoService().exportRoomKeys(password, it) }
                 withContext(Dispatchers.IO) {
-                    val parentDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
+                    val parentDir = context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS)
                     val file = File(parentDir, "riotx-keys-" + System.currentTimeMillis() + ".txt")
 
                     writeToFile(data, file)
diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreActivity.kt b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreActivity.kt
index e6d303b3aa..2b4e372166 100644
--- a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreActivity.kt
+++ b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreActivity.kt
@@ -20,16 +20,22 @@ import android.content.Context
 import android.content.Intent
 import androidx.appcompat.app.AlertDialog
 import androidx.lifecycle.Observer
+import im.vector.matrix.android.api.session.crypto.crosssigning.KEYBACKUP_SECRET_SSSS_NAME
 import im.vector.riotx.R
 import im.vector.riotx.core.extensions.addFragmentToBackstack
 import im.vector.riotx.core.extensions.observeEvent
 import im.vector.riotx.core.extensions.replaceFragment
 import im.vector.riotx.core.platform.SimpleFragmentActivity
+import im.vector.riotx.core.ui.views.KeysBackupBanner
+import im.vector.riotx.features.crypto.quads.SharedSecureStorageActivity
 
 class KeysBackupRestoreActivity : SimpleFragmentActivity() {
 
     companion object {
 
+        private const val REQUEST_4S_SECRET = 100
+        const val SECRET_ALIAS = SharedSecureStorageActivity.DEFAULT_RESULT_KEYSTORE_ALIAS
+
         fun intent(context: Context): Intent {
             return Intent(context, KeysBackupRestoreActivity::class.java)
         }
@@ -39,14 +45,20 @@ class KeysBackupRestoreActivity : SimpleFragmentActivity() {
 
     private lateinit var viewModel: KeysBackupRestoreSharedViewModel
 
+    override fun onBackPressed() {
+        hideWaitingView()
+        super.onBackPressed()
+    }
+
     override fun initUiAndData() {
         super.initUiAndData()
         viewModel = viewModelProvider.get(KeysBackupRestoreSharedViewModel::class.java)
         viewModel.initSession(session)
-        viewModel.keyVersionResult.observe(this, Observer { keyVersion ->
 
-            if (keyVersion != null && supportFragmentManager.fragments.isEmpty()) {
-                val isBackupCreatedFromPassphrase = keyVersion.getAuthDataAsMegolmBackupAuthData()?.privateKeySalt != null
+        viewModel.keySourceModel.observe(this, Observer { keySource ->
+            if (keySource != null && !keySource.isInQuadS && supportFragmentManager.fragments.isEmpty()) {
+                val isBackupCreatedFromPassphrase =
+                        viewModel.keyVersionResult.value?.getAuthDataAsMegolmBackupAuthData()?.privateKeySalt != null
                 if (isBackupCreatedFromPassphrase) {
                     replaceFragment(R.id.container, KeysBackupRestoreFromPassphraseFragment::class.java)
                 } else {
@@ -69,7 +81,7 @@ class KeysBackupRestoreActivity : SimpleFragmentActivity() {
 
         if (viewModel.keyVersionResult.value == null) {
             // We need to fetch from API
-            viewModel.getLatestVersion(this)
+            viewModel.getLatestVersion()
         }
 
         viewModel.navigateEvent.observeEvent(this) { uxStateEvent ->
@@ -78,8 +90,25 @@ class KeysBackupRestoreActivity : SimpleFragmentActivity() {
                     addFragmentToBackstack(R.id.container, KeysBackupRestoreFromKeyFragment::class.java)
                 }
                 KeysBackupRestoreSharedViewModel.NAVIGATE_TO_SUCCESS          -> {
+                    viewModel.keyVersionResult.value?.version?.let {
+                        KeysBackupBanner.onRecoverDoneForVersion(this, it)
+                    }
                     replaceFragment(R.id.container, KeysBackupRestoreSuccessFragment::class.java)
                 }
+                KeysBackupRestoreSharedViewModel.NAVIGATE_TO_4S               -> {
+                    launch4SActivity()
+                }
+                KeysBackupRestoreSharedViewModel.NAVIGATE_FAILED_TO_LOAD_4S   -> {
+                    AlertDialog.Builder(this)
+                            .setTitle(R.string.unknown_error)
+                            .setMessage(R.string.error_failed_to_import_keys)
+                            .setCancelable(false)
+                            .setPositiveButton(R.string.ok) { _, _ ->
+                                // nop
+                                launch4SActivity()
+                            }
+                            .show()
+                }
             }
         }
 
@@ -93,4 +122,30 @@ class KeysBackupRestoreActivity : SimpleFragmentActivity() {
             finish()
         }
     }
+
+    private fun launch4SActivity() {
+        SharedSecureStorageActivity.newIntent(
+                context = this,
+                keyId = null, // default key
+                requestedSecrets = listOf(KEYBACKUP_SECRET_SSSS_NAME),
+                resultKeyStoreAlias = SECRET_ALIAS
+        ).let {
+            startActivityForResult(it, REQUEST_4S_SECRET)
+        }
+    }
+
+    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
+        if (requestCode == REQUEST_4S_SECRET) {
+            val extraResult = data?.getStringExtra(SharedSecureStorageActivity.EXTRA_DATA_RESULT)
+            if (resultCode == Activity.RESULT_OK && extraResult != null) {
+                viewModel.handleGotSecretFromSSSS(
+                        extraResult,
+                        SECRET_ALIAS
+                )
+            } else {
+                finish()
+            }
+        }
+        super.onActivityResult(requestCode, resultCode, data)
+    }
 }
diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreFromKeyFragment.kt b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreFromKeyFragment.kt
index 730c92a319..9a6e65a885 100644
--- a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreFromKeyFragment.kt
+++ b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreFromKeyFragment.kt
@@ -82,7 +82,7 @@ class KeysBackupRestoreFromKeyFragment @Inject constructor()
         if (value.isNullOrBlank()) {
             viewModel.recoveryCodeErrorText.value = context?.getString(R.string.keys_backup_recovery_code_empty_error_message)
         } else {
-            viewModel.recoverKeys(requireContext(), sharedViewModel)
+            viewModel.recoverKeys(sharedViewModel)
         }
     }
 
diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreFromKeyViewModel.kt b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreFromKeyViewModel.kt
index 0cf297f7f1..c8406570d3 100644
--- a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreFromKeyViewModel.kt
+++ b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreFromKeyViewModel.kt
@@ -15,21 +15,19 @@
  */
 package im.vector.riotx.features.crypto.keysbackup.restore
 
-import android.content.Context
 import androidx.lifecycle.MutableLiveData
 import androidx.lifecycle.ViewModel
-import im.vector.matrix.android.api.MatrixCallback
-import im.vector.matrix.android.api.listeners.StepProgressListener
-import im.vector.matrix.android.api.session.crypto.keysbackup.KeysBackupService
-import im.vector.matrix.android.internal.crypto.keysbackup.model.rest.KeysVersionResult
-import im.vector.matrix.android.internal.crypto.model.ImportRoomKeysResult
+import androidx.lifecycle.viewModelScope
 import im.vector.riotx.R
 import im.vector.riotx.core.platform.WaitingViewData
-import im.vector.riotx.core.ui.views.KeysBackupBanner
-import timber.log.Timber
+import im.vector.riotx.core.resources.StringProvider
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
 import javax.inject.Inject
 
-class KeysBackupRestoreFromKeyViewModel @Inject constructor() : ViewModel() {
+class KeysBackupRestoreFromKeyViewModel @Inject constructor(
+        private val stringProvider: StringProvider
+) : ViewModel() {
 
     var recoveryCode: MutableLiveData<String> = MutableLiveData()
     var recoveryCodeErrorText: MutableLiveData<String> = MutableLiveData()
@@ -45,66 +43,16 @@ class KeysBackupRestoreFromKeyViewModel @Inject constructor() : ViewModel() {
         recoveryCodeErrorText.value = null
     }
 
-    fun recoverKeys(context: Context, sharedViewModel: KeysBackupRestoreSharedViewModel) {
-        val session = sharedViewModel.session
-        val keysBackup = session.cryptoService().keysBackupService()
-
+    fun recoverKeys(sharedViewModel: KeysBackupRestoreSharedViewModel) {
+        sharedViewModel.loadingEvent.postValue(WaitingViewData(stringProvider.getString(R.string.loading)))
         recoveryCodeErrorText.value = null
-        val recoveryKey = recoveryCode.value!!
-
-        val keysVersionResult = sharedViewModel.keyVersionResult.value!!
-
-        keysBackup.restoreKeysWithRecoveryKey(keysVersionResult,
-                recoveryKey,
-                null,
-                session.myUserId,
-                object : StepProgressListener {
-                    override fun onStepProgress(step: StepProgressListener.Step) {
-                        when (step) {
-                            is StepProgressListener.Step.DownloadingKey -> {
-                                sharedViewModel.loadingEvent.postValue(WaitingViewData(context.getString(R.string.keys_backup_restoring_waiting_message)
-                                        + "\n" + context.getString(R.string.keys_backup_restoring_downloading_backup_waiting_message),
-                                        isIndeterminate = true))
-                            }
-                            is StepProgressListener.Step.ImportingKey   -> {
-                                // Progress 0 can take a while, display an indeterminate progress in this case
-                                if (step.progress == 0) {
-                                    sharedViewModel.loadingEvent.postValue(WaitingViewData(context.getString(R.string.keys_backup_restoring_waiting_message)
-                                            + "\n" + context.getString(R.string.keys_backup_restoring_importing_keys_waiting_message),
-                                            isIndeterminate = true))
-                                } else {
-                                    sharedViewModel.loadingEvent.postValue(WaitingViewData(context.getString(R.string.keys_backup_restoring_waiting_message)
-                                            + "\n" + context.getString(R.string.keys_backup_restoring_importing_keys_waiting_message),
-                                            step.progress,
-                                            step.total))
-                                }
-                            }
-                        }
-                    }
-                },
-                object : MatrixCallback<ImportRoomKeysResult> {
-                    override fun onSuccess(data: ImportRoomKeysResult) {
-                        sharedViewModel.loadingEvent.value = null
-                        sharedViewModel.didRecoverSucceed(data)
-
-                        KeysBackupBanner.onRecoverDoneForVersion(context, keysVersionResult.version!!)
-                        trustOnDecrypt(keysBackup, keysVersionResult)
-                    }
-
-                    override fun onFailure(failure: Throwable) {
-                        sharedViewModel.loadingEvent.value = null
-                        recoveryCodeErrorText.value = context.getString(R.string.keys_backup_recovery_code_error_decrypt)
-                        Timber.e(failure, "## onUnexpectedError")
-                    }
-                })
-    }
-
-    private fun trustOnDecrypt(keysBackup: KeysBackupService, keysVersionResult: KeysVersionResult) {
-        keysBackup.trustKeysBackupVersion(keysVersionResult, true,
-                object : MatrixCallback<Unit> {
-                    override fun onSuccess(data: Unit) {
-                        Timber.v("##### trustKeysBackupVersion onSuccess")
-                    }
-                })
+        viewModelScope.launch(Dispatchers.IO) {
+            val recoveryKey = recoveryCode.value!!
+            try {
+                sharedViewModel.recoverUsingBackupPass(recoveryKey)
+            } catch (failure: Throwable) {
+                recoveryCodeErrorText.value = stringProvider.getString(R.string.keys_backup_recovery_code_error_decrypt)
+            }
+        }
     }
 }
diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreFromPassphraseFragment.kt b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreFromPassphraseFragment.kt
index a9bdeee2d6..e334603b74 100644
--- a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreFromPassphraseFragment.kt
+++ b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreFromPassphraseFragment.kt
@@ -15,7 +15,6 @@
  */
 package im.vector.riotx.features.crypto.keysbackup.restore
 
-import android.content.Context
 import android.os.Bundle
 import android.text.Editable
 import android.text.SpannableString
@@ -36,7 +35,7 @@ import im.vector.riotx.core.extensions.showPassword
 import im.vector.riotx.core.platform.VectorBaseFragment
 import javax.inject.Inject
 
-class KeysBackupRestoreFromPassphraseFragment @Inject constructor(): VectorBaseFragment() {
+class KeysBackupRestoreFromPassphraseFragment @Inject constructor() : VectorBaseFragment() {
 
     override fun getLayoutResId() = R.layout.fragment_keys_backup_restore_from_passphrase
 
@@ -70,7 +69,7 @@ class KeysBackupRestoreFromPassphraseFragment @Inject constructor(): VectorBaseF
             mPassphraseInputLayout.error = newValue
         })
 
-        helperTextWithLink.text = spannableStringForHelperText(context!!)
+        helperTextWithLink.text = spannableStringForHelperText()
 
         viewModel.showPasswordMode.observe(viewLifecycleOwner, Observer {
             val shouldBeVisible = it ?: false
@@ -87,15 +86,15 @@ class KeysBackupRestoreFromPassphraseFragment @Inject constructor(): VectorBaseF
         }
     }
 
-    private fun spannableStringForHelperText(context: Context): SpannableString {
-        val clickableText = context.getString(R.string.keys_backup_restore_use_recovery_key)
-        val helperText = context.getString(R.string.keys_backup_restore_with_passphrase_helper_with_link, clickableText)
+    private fun spannableStringForHelperText(): SpannableString {
+        val clickableText = getString(R.string.keys_backup_restore_use_recovery_key)
+        val helperText = getString(R.string.keys_backup_restore_with_passphrase_helper_with_link, clickableText)
 
         val spanString = SpannableString(helperText)
 
         // used just to have default link representation
         val clickableSpan = object : ClickableSpan() {
-            override fun onClick(widget: View?) {}
+            override fun onClick(widget: View) {}
         }
         val start = helperText.indexOf(clickableText)
         val end = start + clickableText.length
@@ -117,9 +116,9 @@ class KeysBackupRestoreFromPassphraseFragment @Inject constructor(): VectorBaseF
     fun onRestoreBackup() {
         val value = viewModel.passphrase.value
         if (value.isNullOrBlank()) {
-            viewModel.passphraseErrorText.value = context?.getString(R.string.passphrase_empty_error_message)
+            viewModel.passphraseErrorText.value = getString(R.string.passphrase_empty_error_message)
         } else {
-            viewModel.recoverKeys(context!!, sharedViewModel)
+            viewModel.recoverKeys(sharedViewModel)
         }
     }
 }
diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreFromPassphraseViewModel.kt b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreFromPassphraseViewModel.kt
index 69c5e70740..9c9c12b824 100644
--- a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreFromPassphraseViewModel.kt
+++ b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreFromPassphraseViewModel.kt
@@ -15,21 +15,18 @@
  */
 package im.vector.riotx.features.crypto.keysbackup.restore
 
-import android.content.Context
 import androidx.lifecycle.MutableLiveData
 import androidx.lifecycle.ViewModel
-import im.vector.matrix.android.api.MatrixCallback
-import im.vector.matrix.android.api.listeners.StepProgressListener
-import im.vector.matrix.android.api.session.crypto.keysbackup.KeysBackupService
-import im.vector.matrix.android.internal.crypto.keysbackup.model.rest.KeysVersionResult
-import im.vector.matrix.android.internal.crypto.model.ImportRoomKeysResult
+import androidx.lifecycle.viewModelScope
 import im.vector.riotx.R
-import im.vector.riotx.core.platform.WaitingViewData
-import im.vector.riotx.core.ui.views.KeysBackupBanner
-import timber.log.Timber
+import im.vector.riotx.core.resources.StringProvider
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
 import javax.inject.Inject
 
-class KeysBackupRestoreFromPassphraseViewModel @Inject constructor() : ViewModel() {
+class KeysBackupRestoreFromPassphraseViewModel @Inject constructor(
+        private val stringProvider: StringProvider
+) : ViewModel() {
 
     var passphrase: MutableLiveData<String> = MutableLiveData()
     var passphraseErrorText: MutableLiveData<String> = MutableLiveData()
@@ -48,71 +45,14 @@ class KeysBackupRestoreFromPassphraseViewModel @Inject constructor() : ViewModel
         passphraseErrorText.value = null
     }
 
-    fun recoverKeys(context: Context, sharedViewModel: KeysBackupRestoreSharedViewModel) {
-        val keysBackup = sharedViewModel.session.cryptoService().keysBackupService()
-
+    fun recoverKeys(sharedViewModel: KeysBackupRestoreSharedViewModel) {
         passphraseErrorText.value = null
-
-        val keysVersionResult = sharedViewModel.keyVersionResult.value!!
-
-        keysBackup.restoreKeyBackupWithPassword(keysVersionResult,
-                passphrase.value!!,
-                null,
-                sharedViewModel.session.myUserId,
-                object : StepProgressListener {
-                    override fun onStepProgress(step: StepProgressListener.Step) {
-                        when (step) {
-                            is StepProgressListener.Step.ComputingKey -> {
-                                sharedViewModel.loadingEvent.postValue(WaitingViewData(context.getString(R.string.keys_backup_restoring_waiting_message)
-                                        + "\n" + context.getString(R.string.keys_backup_restoring_computing_key_waiting_message),
-                                        step.progress,
-                                        step.total))
-                            }
-                            is StepProgressListener.Step.DownloadingKey -> {
-                                sharedViewModel.loadingEvent.postValue(WaitingViewData(context.getString(R.string.keys_backup_restoring_waiting_message)
-                                        + "\n" + context.getString(R.string.keys_backup_restoring_downloading_backup_waiting_message),
-                                        isIndeterminate = true))
-                            }
-                            is StepProgressListener.Step.ImportingKey -> {
-                                Timber.d("backupKeys.ImportingKey.progress: ${step.progress}")
-                                // Progress 0 can take a while, display an indeterminate progress in this case
-                                if (step.progress == 0) {
-                                    sharedViewModel.loadingEvent.postValue(WaitingViewData(context.getString(R.string.keys_backup_restoring_waiting_message)
-                                            + "\n" + context.getString(R.string.keys_backup_restoring_importing_keys_waiting_message),
-                                            isIndeterminate = true))
-                                } else {
-                                    sharedViewModel.loadingEvent.postValue(WaitingViewData(context.getString(R.string.keys_backup_restoring_waiting_message)
-                                            + "\n" + context.getString(R.string.keys_backup_restoring_importing_keys_waiting_message),
-                                            step.progress,
-                                            step.total))
-                                }
-                            }
-                        }
-                    }
-                },
-                object : MatrixCallback<ImportRoomKeysResult> {
-                    override fun onSuccess(data: ImportRoomKeysResult) {
-                        sharedViewModel.loadingEvent.value = null
-                        sharedViewModel.didRecoverSucceed(data)
-
-                        KeysBackupBanner.onRecoverDoneForVersion(context, keysVersionResult.version!!)
-                        trustOnDecrypt(keysBackup, keysVersionResult)
-                    }
-
-                    override fun onFailure(failure: Throwable) {
-                        sharedViewModel.loadingEvent.value = null
-                        passphraseErrorText.value = context.getString(R.string.keys_backup_passphrase_error_decrypt)
-                        Timber.e(failure, "## onUnexpectedError")
-                    }
-                })
-    }
-
-    private fun trustOnDecrypt(keysBackup: KeysBackupService, keysVersionResult: KeysVersionResult) {
-        keysBackup.trustKeysBackupVersion(keysVersionResult, true,
-                object : MatrixCallback<Unit> {
-                    override fun onSuccess(data: Unit) {
-                        Timber.v("##### trustKeysBackupVersion onSuccess")
-                    }
-                })
+        viewModelScope.launch(Dispatchers.IO) {
+            try {
+                sharedViewModel.recoverUsingBackupPass(passphrase.value!!)
+            } catch (failure: Throwable) {
+                passphraseErrorText.postValue(stringProvider.getString(R.string.keys_backup_passphrase_error_decrypt))
+            }
+        }
     }
 }
diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreSharedViewModel.kt b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreSharedViewModel.kt
index 5586d0cf05..24aa37b95c 100644
--- a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreSharedViewModel.kt
+++ b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreSharedViewModel.kt
@@ -15,30 +15,52 @@
  */
 package im.vector.riotx.features.crypto.keysbackup.restore
 
-import android.content.Context
 import androidx.lifecycle.LiveData
 import androidx.lifecycle.MutableLiveData
 import androidx.lifecycle.ViewModel
+import androidx.lifecycle.viewModelScope
 import im.vector.matrix.android.api.MatrixCallback
+import im.vector.matrix.android.api.listeners.StepProgressListener
 import im.vector.matrix.android.api.session.Session
+import im.vector.matrix.android.api.session.crypto.crosssigning.KEYBACKUP_SECRET_SSSS_NAME
+import im.vector.matrix.android.api.session.crypto.keysbackup.KeysBackupService
+import im.vector.matrix.android.api.session.securestorage.KeyInfoResult
+import im.vector.matrix.android.internal.crypto.crosssigning.fromBase64
 import im.vector.matrix.android.internal.crypto.keysbackup.model.rest.KeysVersionResult
+import im.vector.matrix.android.internal.crypto.keysbackup.util.computeRecoveryKey
 import im.vector.matrix.android.internal.crypto.model.ImportRoomKeysResult
+import im.vector.matrix.android.internal.util.awaitCallback
 import im.vector.riotx.R
 import im.vector.riotx.core.platform.WaitingViewData
+import im.vector.riotx.core.resources.StringProvider
 import im.vector.riotx.core.utils.LiveEvent
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+import timber.log.Timber
 import javax.inject.Inject
 
-class KeysBackupRestoreSharedViewModel @Inject constructor() : ViewModel() {
+class KeysBackupRestoreSharedViewModel @Inject constructor(
+        private val stringProvider: StringProvider
+) : ViewModel() {
+
+    data class KeySource(
+            val isInMemory: Boolean,
+            val isInQuadS: Boolean
+    )
 
     companion object {
         const val NAVIGATE_TO_RECOVER_WITH_KEY = "NAVIGATE_TO_RECOVER_WITH_KEY"
         const val NAVIGATE_TO_SUCCESS = "NAVIGATE_TO_SUCCESS"
+        const val NAVIGATE_TO_4S = "NAVIGATE_TO_4S"
+        const val NAVIGATE_FAILED_TO_LOAD_4S = "NAVIGATE_FAILED_TO_LOAD_4S"
     }
 
     lateinit var session: Session
 
     var keyVersionResult: MutableLiveData<KeysVersionResult> = MutableLiveData()
 
+    var keySourceModel: MutableLiveData<KeySource> = MutableLiveData()
+
     private var _keyVersionResultError: MutableLiveData<LiveEvent<String>> = MutableLiveData()
     val keyVersionResultError: LiveData<LiveEvent<String>>
         get() = _keyVersionResultError
@@ -62,30 +84,192 @@ class KeysBackupRestoreSharedViewModel @Inject constructor() : ViewModel() {
         this.session = session
     }
 
-    fun getLatestVersion(context: Context) {
-        val keysBackup = session.cryptoService().keysBackupService()
-
-        loadingEvent.value = WaitingViewData(context.getString(R.string.keys_backup_restore_is_getting_backup_version))
-
-        keysBackup.getCurrentVersion(object : MatrixCallback<KeysVersionResult?> {
-            override fun onSuccess(data: KeysVersionResult?) {
-                loadingEvent.value = null
-                if (data?.version.isNullOrBlank()) {
-                    // should not happen
-                    _keyVersionResultError.value = LiveEvent(context.getString(R.string.keys_backup_get_version_error, ""))
-                } else {
-                    keyVersionResult.value = data
+    val progressObserver = object : StepProgressListener {
+        override fun onStepProgress(step: StepProgressListener.Step) {
+            when (step) {
+                is StepProgressListener.Step.ComputingKey   -> {
+                    loadingEvent.postValue(WaitingViewData(stringProvider.getString(R.string.keys_backup_restoring_waiting_message)
+                            + "\n" + stringProvider.getString(R.string.keys_backup_restoring_computing_key_waiting_message),
+                            step.progress,
+                            step.total))
+                }
+                is StepProgressListener.Step.DownloadingKey -> {
+                    loadingEvent.postValue(WaitingViewData(stringProvider.getString(R.string.keys_backup_restoring_waiting_message)
+                            + "\n" + stringProvider.getString(R.string.keys_backup_restoring_downloading_backup_waiting_message),
+                            isIndeterminate = true))
+                }
+                is StepProgressListener.Step.ImportingKey   -> {
+                    Timber.d("backupKeys.ImportingKey.progress: ${step.progress}")
+                    // Progress 0 can take a while, display an indeterminate progress in this case
+                    if (step.progress == 0) {
+                        loadingEvent.postValue(WaitingViewData(stringProvider.getString(R.string.keys_backup_restoring_waiting_message)
+                                + "\n" + stringProvider.getString(R.string.keys_backup_restoring_importing_keys_waiting_message),
+                                isIndeterminate = true))
+                    } else {
+                        loadingEvent.postValue(WaitingViewData(stringProvider.getString(R.string.keys_backup_restoring_waiting_message)
+                                + "\n" + stringProvider.getString(R.string.keys_backup_restoring_importing_keys_waiting_message),
+                                step.progress,
+                                step.total))
+                    }
                 }
             }
+        }
+    }
 
-            override fun onFailure(failure: Throwable) {
-                loadingEvent.value = null
-                _keyVersionResultError.value = LiveEvent(context.getString(R.string.keys_backup_get_version_error, failure.localizedMessage))
+    fun getLatestVersion() {
+        val keysBackup = session.cryptoService().keysBackupService()
 
-                // TODO For network error
-                //  _keyVersionResultError.value = LiveEvent(context.getString(R.string.network_error_please_check_and_retry))
+        loadingEvent.value = WaitingViewData(stringProvider.getString(R.string.keys_backup_restore_is_getting_backup_version))
+
+        viewModelScope.launch(Dispatchers.IO) {
+            try {
+                val version = awaitCallback<KeysVersionResult?> {
+                    keysBackup.getCurrentVersion(it)
+                }
+                if (version?.version == null) {
+                    loadingEvent.postValue(null)
+                    _keyVersionResultError.postValue(LiveEvent(stringProvider.getString(R.string.keys_backup_get_version_error, "")))
+                    return@launch
+                }
+
+                keyVersionResult.postValue(version)
+                // Let's check if there is quads
+                val isBackupKeyInQuadS = isBackupKeyInQuadS()
+
+                val savedSecret = session.cryptoService().keysBackupService().getKeyBackupRecoveryKeyInfo()
+                if (savedSecret != null && savedSecret.version == version.version) {
+                    // key is in memory!
+                    keySourceModel.postValue(
+                            KeySource(isInMemory = true, isInQuadS = true)
+                    )
+                    // Go and use it!!
+                    try {
+                        recoverUsingBackupRecoveryKey(savedSecret.recoveryKey)
+                    } catch (failure: Throwable) {
+                        keySourceModel.postValue(
+                                KeySource(isInMemory = false, isInQuadS = true)
+                        )
+                    }
+                } else if (isBackupKeyInQuadS) {
+                    // key is in QuadS!
+                    keySourceModel.postValue(
+                            KeySource(isInMemory = false, isInQuadS = true)
+                    )
+                    _navigateEvent.postValue(LiveEvent(NAVIGATE_TO_4S))
+                } else {
+                    // we need to restore directly
+                    keySourceModel.postValue(
+                            KeySource(isInMemory = false, isInQuadS = false)
+                    )
+                }
+
+                loadingEvent.postValue(null)
+            } catch (failure: Throwable) {
+                loadingEvent.postValue(null)
+                _keyVersionResultError.postValue(LiveEvent(stringProvider.getString(R.string.keys_backup_get_version_error, failure.localizedMessage)))
             }
-        })
+        }
+    }
+
+    fun handleGotSecretFromSSSS(cipherData: String, alias: String) {
+        try {
+            cipherData.fromBase64().inputStream().use { ins ->
+                val res = session.loadSecureSecret<Map<String, String>>(ins, alias)
+                val secret = res?.get(KEYBACKUP_SECRET_SSSS_NAME)
+                if (secret == null) {
+                    _navigateEvent.postValue(
+                            LiveEvent(NAVIGATE_FAILED_TO_LOAD_4S)
+                    )
+                    return
+                }
+                loadingEvent.value = WaitingViewData(stringProvider.getString(R.string.keys_backup_restore_is_getting_backup_version))
+
+                viewModelScope.launch(Dispatchers.IO) {
+                    try {
+                        recoverUsingBackupRecoveryKey(computeRecoveryKey(secret.fromBase64()))
+                    } catch (failure: Throwable) {
+                        _navigateEvent.postValue(
+                                LiveEvent(NAVIGATE_FAILED_TO_LOAD_4S)
+                        )
+                    }
+                }
+            }
+        } catch (failure: Throwable) {
+            _navigateEvent.postValue(
+                    LiveEvent(NAVIGATE_FAILED_TO_LOAD_4S)
+            )
+        }
+    }
+
+    suspend fun recoverUsingBackupPass(passphrase: String) {
+        val keysBackup = session.cryptoService().keysBackupService()
+        val keyVersion = keyVersionResult.value ?: return
+
+        loadingEvent.postValue(WaitingViewData(stringProvider.getString(R.string.loading)))
+
+        try {
+            val result = awaitCallback<ImportRoomKeysResult> {
+                keysBackup.restoreKeyBackupWithPassword(keyVersion,
+                        passphrase,
+                        null,
+                        session.myUserId,
+                        progressObserver,
+                        it
+                )
+            }
+            loadingEvent.postValue(null)
+            didRecoverSucceed(result)
+            trustOnDecrypt(keysBackup, keyVersion)
+        } catch (failure: Throwable) {
+            loadingEvent.postValue(null)
+            throw failure
+        }
+    }
+
+    suspend fun recoverUsingBackupRecoveryKey(recoveryKey: String) {
+        val keysBackup = session.cryptoService().keysBackupService()
+        val keyVersion = keyVersionResult.value ?: return
+
+        loadingEvent.postValue(WaitingViewData(stringProvider.getString(R.string.loading)))
+
+        try {
+            val result = awaitCallback<ImportRoomKeysResult> {
+                keysBackup.restoreKeysWithRecoveryKey(keyVersion,
+                        recoveryKey,
+                        null,
+                        session.myUserId,
+                        progressObserver,
+                        it
+                )
+            }
+            loadingEvent.postValue(null)
+            didRecoverSucceed(result)
+            trustOnDecrypt(keysBackup, keyVersion)
+        } catch (failure: Throwable) {
+            loadingEvent.postValue(null)
+            throw failure
+        }
+    }
+
+    private fun isBackupKeyInQuadS(): Boolean {
+        val sssBackupSecret = session.getAccountDataEvent(KEYBACKUP_SECRET_SSSS_NAME)
+                ?: return false
+
+        // Some sanity ?
+        val defaultKeyResult = session.sharedSecretStorageService.getDefaultKey()
+        val keyInfo = (defaultKeyResult as? KeyInfoResult.Success)?.keyInfo
+                ?: return false
+
+        return (sssBackupSecret.content["encrypted"] as? Map<*, *>)?.containsKey(keyInfo.id) == true
+    }
+
+    private fun trustOnDecrypt(keysBackup: KeysBackupService, keysVersionResult: KeysVersionResult) {
+        keysBackup.trustKeysBackupVersion(keysVersionResult, true,
+                object : MatrixCallback<Unit> {
+                    override fun onSuccess(data: Unit) {
+                        Timber.v("##### trustKeysBackupVersion onSuccess")
+                    }
+                })
     }
 
     fun moveToRecoverWithKey() {
@@ -94,6 +278,6 @@ class KeysBackupRestoreSharedViewModel @Inject constructor() : ViewModel() {
 
     fun didRecoverSucceed(result: ImportRoomKeysResult) {
         importKeyResult = result
-        _navigateEvent.value = LiveEvent(NAVIGATE_TO_SUCCESS)
+        _navigateEvent.postValue(LiveEvent(NAVIGATE_TO_SUCCESS))
     }
 }
diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupActivity.kt b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupActivity.kt
index 924e25a4d7..c7d3da30ea 100644
--- a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupActivity.kt
+++ b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupActivity.kt
@@ -128,7 +128,10 @@ class KeysBackupSetupActivity : SimpleFragmentActivity() {
     }
 
     private fun exportKeysManually() {
-        if (checkPermissions(PERMISSIONS_FOR_WRITING_FILES, this, PERMISSION_REQUEST_CODE_EXPORT_KEYS, R.string.permissions_rationale_msg_keys_backup_export)) {
+        if (checkPermissions(PERMISSIONS_FOR_WRITING_FILES,
+                        this,
+                        PERMISSION_REQUEST_CODE_EXPORT_KEYS,
+                        R.string.permissions_rationale_msg_keys_backup_export)) {
             ExportKeysDialog().show(this, object : ExportKeysDialog.ExportKeyDialogListener {
                 override fun onPassphrase(passphrase: String) {
                     showWaitingView()
@@ -153,7 +156,7 @@ class KeysBackupSetupActivity : SimpleFragmentActivity() {
                                         }
 
                                         override fun onFailure(failure: Throwable) {
-                                            toast(failure.localizedMessage)
+                                            toast(failure.localizedMessage ?: getString(R.string.unexpected_error))
                                             hideWaitingView()
                                         }
                                     })
diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupStep3Fragment.kt b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupStep3Fragment.kt
index a224cfb387..9175d6c081 100644
--- a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupStep3Fragment.kt
+++ b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupStep3Fragment.kt
@@ -167,7 +167,7 @@ class KeysBackupSetupStep3Fragment @Inject constructor() : VectorBaseFragment()
         GlobalScope.launch(Dispatchers.Main) {
             Try {
                 withContext(Dispatchers.IO) {
-                    val parentDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
+                    val parentDir = context?.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS)
                     val file = File(parentDir, "recovery-key-" + System.currentTimeMillis() + ".txt")
 
                     writeToFile(data, file)
diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/keysrequest/KeyRequestHandler.kt b/vector/src/main/java/im/vector/riotx/features/crypto/keysrequest/KeyRequestHandler.kt
index ddb50628d6..0159dc7c3a 100644
--- a/vector/src/main/java/im/vector/riotx/features/crypto/keysrequest/KeyRequestHandler.kt
+++ b/vector/src/main/java/im/vector/riotx/features/crypto/keysrequest/KeyRequestHandler.kt
@@ -27,14 +27,13 @@ import im.vector.matrix.android.api.session.crypto.verification.SasVerificationT
 import im.vector.matrix.android.api.session.crypto.verification.VerificationService
 import im.vector.matrix.android.api.session.crypto.verification.VerificationTransaction
 import im.vector.matrix.android.api.session.crypto.verification.VerificationTxState
-import im.vector.matrix.android.internal.crypto.IncomingRoomKeyRequest
 import im.vector.matrix.android.internal.crypto.IncomingRequestCancellation
+import im.vector.matrix.android.internal.crypto.IncomingRoomKeyRequest
 import im.vector.matrix.android.internal.crypto.IncomingSecretShareRequest
 import im.vector.matrix.android.internal.crypto.crosssigning.DeviceTrustLevel
 import im.vector.matrix.android.internal.crypto.model.CryptoDeviceInfo
 import im.vector.matrix.android.internal.crypto.model.MXUsersDevicesMap
 import im.vector.matrix.android.internal.crypto.model.rest.DeviceInfo
-import im.vector.matrix.android.internal.crypto.model.rest.DevicesListResponse
 import im.vector.riotx.R
 import im.vector.riotx.features.popup.DefaultVectorAlert
 import im.vector.riotx.features.popup.PopupAlertManager
@@ -75,7 +74,7 @@ class KeyRequestHandler @Inject constructor(private val context: Context, privat
         session = null
     }
 
-    override fun onSecretShareRequest(request: IncomingSecretShareRequest) : Boolean {
+    override fun onSecretShareRequest(request: IncomingSecretShareRequest): Boolean {
         // By default riotX will not prompt if the SDK has decided that the request should not be fulfilled
         Timber.v("## onSecretShareRequest() : Ignoring $request")
         request.ignore?.run()
@@ -124,19 +123,11 @@ class KeyRequestHandler @Inject constructor(private val context: Context, privat
                     deviceInfo.trustLevel = DeviceTrustLevel(crossSigningVerified = false, locallyVerified = false)
 
                     // can we get more info on this device?
-                    session?.cryptoService()?.getDevicesList(object : MatrixCallback<DevicesListResponse> {
-                        override fun onSuccess(data: DevicesListResponse) {
-                            data.devices?.find { it.deviceId == deviceId }?.let {
-                                postAlert(context, userId, deviceId, true, deviceInfo, it)
-                            } ?: run {
-                                postAlert(context, userId, deviceId, true, deviceInfo)
-                            }
-                        }
-
-                        override fun onFailure(failure: Throwable) {
-                            postAlert(context, userId, deviceId, true, deviceInfo)
-                        }
-                    })
+                    session?.cryptoService()?.getMyDevicesInfo()?.firstOrNull { it.deviceId == deviceId }?.let {
+                        postAlert(context, userId, deviceId, true, deviceInfo, it)
+                    } ?: kotlin.run {
+                        postAlert(context, userId, deviceId, true, deviceInfo)
+                    }
                 } else {
                     postAlert(context, userId, deviceId, false, deviceInfo)
                 }
diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/quads/SharedSecureStorageAction.kt b/vector/src/main/java/im/vector/riotx/features/crypto/quads/SharedSecureStorageAction.kt
index c2c2b9c42a..876c758864 100644
--- a/vector/src/main/java/im/vector/riotx/features/crypto/quads/SharedSecureStorageAction.kt
+++ b/vector/src/main/java/im/vector/riotx/features/crypto/quads/SharedSecureStorageAction.kt
@@ -23,8 +23,11 @@ import im.vector.riotx.core.platform.WaitingViewData
 sealed class SharedSecureStorageAction : VectorViewModelAction {
 
     object TogglePasswordVisibility : SharedSecureStorageAction()
+    object UseKey : SharedSecureStorageAction()
+    object Back : SharedSecureStorageAction()
     object Cancel : SharedSecureStorageAction()
     data class SubmitPassphrase(val passphrase: String) : SharedSecureStorageAction()
+    data class SubmitKey(val recoveryKey: String) : SharedSecureStorageAction()
 }
 
 sealed class SharedSecureStorageViewEvent : VectorViewEvents {
@@ -33,6 +36,7 @@ sealed class SharedSecureStorageViewEvent : VectorViewEvents {
     data class FinishSuccess(val cypherResult: String) : SharedSecureStorageViewEvent()
     data class Error(val message: String, val dismiss: Boolean = false) : SharedSecureStorageViewEvent()
     data class InlineError(val message: String) : SharedSecureStorageViewEvent()
+    data class KeyInlineError(val message: String) : SharedSecureStorageViewEvent()
     object ShowModalLoading : SharedSecureStorageViewEvent()
     object HideModalLoading : SharedSecureStorageViewEvent()
     data class UpdateLoadingState(val waitingData: WaitingViewData) : SharedSecureStorageViewEvent()
diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/quads/SharedSecureStorageActivity.kt b/vector/src/main/java/im/vector/riotx/features/crypto/quads/SharedSecureStorageActivity.kt
index 1347b6ca19..db37107dd6 100644
--- a/vector/src/main/java/im/vector/riotx/features/crypto/quads/SharedSecureStorageActivity.kt
+++ b/vector/src/main/java/im/vector/riotx/features/crypto/quads/SharedSecureStorageActivity.kt
@@ -23,17 +23,19 @@ import android.os.Bundle
 import android.os.Parcelable
 import android.view.View
 import androidx.appcompat.app.AlertDialog
+import androidx.fragment.app.Fragment
 import com.airbnb.mvrx.MvRx
 import com.airbnb.mvrx.viewModel
 import im.vector.riotx.R
 import im.vector.riotx.core.di.ScreenComponent
 import im.vector.riotx.core.error.ErrorFormatter
-import im.vector.riotx.core.extensions.addFragment
+import im.vector.riotx.core.extensions.commitTransaction
 import im.vector.riotx.core.platform.SimpleFragmentActivity
 import io.reactivex.android.schedulers.AndroidSchedulers
 import kotlinx.android.parcel.Parcelize
 import kotlinx.android.synthetic.main.activity.*
 import javax.inject.Inject
+import kotlin.reflect.KClass
 
 class SharedSecureStorageActivity : SimpleFragmentActivity() {
 
@@ -56,9 +58,6 @@ class SharedSecureStorageActivity : SimpleFragmentActivity() {
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
         toolbar.visibility = View.GONE
-        if (isFirstCreation()) {
-            addFragment(R.id.container, SharedSecuredStoragePassphraseFragment::class.java)
-        }
 
         viewModel.viewEvents
                 .observe()
@@ -69,10 +68,22 @@ class SharedSecureStorageActivity : SimpleFragmentActivity() {
                 .disposeOnDestroy()
 
         viewModel.subscribe(this) {
-            //            renderState(it)
+            renderState(it)
         }
     }
 
+    override fun onBackPressed() {
+        viewModel.handle(SharedSecureStorageAction.Back)
+    }
+
+    private fun renderState(state: SharedSecureStorageViewState) {
+        if (!state.ready) return
+        val fragment = if (state.hasPassphrase) {
+            if (state.useKey) SharedSecuredStorageKeyFragment::class else SharedSecuredStoragePassphraseFragment::class
+        } else SharedSecuredStorageKeyFragment::class
+        showFragment(fragment, Bundle())
+    }
+
     private fun observeViewEvents(it: SharedSecureStorageViewEvent?) {
         when (it) {
             is SharedSecureStorageViewEvent.Dismiss            -> {
@@ -108,6 +119,18 @@ class SharedSecureStorageActivity : SimpleFragmentActivity() {
         }
     }
 
+    private fun showFragment(fragmentClass: KClass<out Fragment>, bundle: Bundle) {
+        if (supportFragmentManager.findFragmentByTag(fragmentClass.simpleName) == null) {
+            supportFragmentManager.commitTransaction {
+                replace(R.id.container,
+                        fragmentClass.java,
+                        bundle,
+                        fragmentClass.simpleName
+                )
+            }
+        }
+    }
+
     companion object {
         const val EXTRA_DATA_RESULT = "EXTRA_DATA_RESULT"
         const val DEFAULT_RESULT_KEYSTORE_ALIAS = "SharedSecureStorageActivity"
diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/quads/SharedSecureStorageViewModel.kt b/vector/src/main/java/im/vector/riotx/features/crypto/quads/SharedSecureStorageViewModel.kt
index 9cd60eba43..314f187ab9 100644
--- a/vector/src/main/java/im/vector/riotx/features/crypto/quads/SharedSecureStorageViewModel.kt
+++ b/vector/src/main/java/im/vector/riotx/features/crypto/quads/SharedSecureStorageViewModel.kt
@@ -17,9 +17,14 @@
 package im.vector.riotx.features.crypto.quads
 
 import androidx.lifecycle.viewModelScope
+import com.airbnb.mvrx.Async
+import com.airbnb.mvrx.Fail
+import com.airbnb.mvrx.Loading
 import com.airbnb.mvrx.MvRx
 import com.airbnb.mvrx.MvRxState
 import com.airbnb.mvrx.MvRxViewModelFactory
+import com.airbnb.mvrx.Success
+import com.airbnb.mvrx.Uninitialized
 import com.airbnb.mvrx.ViewModelContext
 import com.squareup.inject.assisted.Assisted
 import com.squareup.inject.assisted.AssistedInject
@@ -31,6 +36,7 @@ import im.vector.matrix.android.api.session.securestorage.RawBytesKeySpec
 import im.vector.matrix.android.internal.crypto.crosssigning.toBase64NoPadding
 import im.vector.matrix.android.internal.util.awaitCallback
 import im.vector.riotx.R
+import im.vector.riotx.core.extensions.exhaustive
 import im.vector.riotx.core.platform.VectorViewModel
 import im.vector.riotx.core.platform.WaitingViewData
 import im.vector.riotx.core.resources.StringProvider
@@ -41,7 +47,11 @@ import timber.log.Timber
 import java.io.ByteArrayOutputStream
 
 data class SharedSecureStorageViewState(
-        val passphraseVisible: Boolean = false
+        val ready: Boolean = false,
+        val hasPassphrase: Boolean = true,
+        val useKey: Boolean = false,
+        val passphraseVisible: Boolean = false,
+        val checkingSSSSAction: Async<Unit> = Uninitialized
 ) : MvRxState
 
 class SharedSecureStorageViewModel @AssistedInject constructor(
@@ -66,6 +76,30 @@ class SharedSecureStorageViewModel @AssistedInject constructor(
                     )
             )
         }
+        val keyResult = args.keyId?.let { session.sharedSecretStorageService.getKey(it) }
+                ?: session.sharedSecretStorageService.getDefaultKey()
+
+        if (!keyResult.isSuccess()) {
+            _viewEvents.post(SharedSecureStorageViewEvent.Dismiss)
+        } else {
+            val info = (keyResult as KeyInfoResult.Success).keyInfo
+            if (info.content.passphrase != null) {
+                setState {
+                    copy(
+                            ready = true,
+                            hasPassphrase = true,
+                            useKey = false
+                    )
+                }
+            } else {
+                setState {
+                    copy(
+                            ready = true,
+                            hasPassphrase = false
+                    )
+                }
+            }
+        }
     }
 
     override fun handle(action: SharedSecureStorageAction) = withState {
@@ -73,14 +107,98 @@ class SharedSecureStorageViewModel @AssistedInject constructor(
             is SharedSecureStorageAction.TogglePasswordVisibility -> handleTogglePasswordVisibility()
             is SharedSecureStorageAction.Cancel                   -> handleCancel()
             is SharedSecureStorageAction.SubmitPassphrase         -> handleSubmitPassphrase(action)
+            SharedSecureStorageAction.UseKey                      -> handleUseKey()
+            is SharedSecureStorageAction.SubmitKey                -> handleSubmitKey(action)
+            SharedSecureStorageAction.Back                        -> handleBack()
+        }.exhaustive
+    }
+
+    private fun handleUseKey() {
+        setState {
+            copy(
+                    useKey = true
+            )
+        }
+    }
+
+    private fun handleBack() = withState { state ->
+        if (state.checkingSSSSAction is Loading) return@withState // ignore
+        if (state.hasPassphrase && state.useKey) {
+            setState {
+                copy(
+                        useKey = false
+                )
+            }
+        } else {
+            _viewEvents.post(SharedSecureStorageViewEvent.Dismiss)
+        }
+    }
+
+    private fun handleSubmitKey(action: SharedSecureStorageAction.SubmitKey) {
+        _viewEvents.post(SharedSecureStorageViewEvent.ShowModalLoading)
+        val decryptedSecretMap = HashMap<String, String>()
+        setState { copy(checkingSSSSAction = Loading()) }
+        viewModelScope.launch(Dispatchers.IO) {
+            runCatching {
+                val recoveryKey = action.recoveryKey
+                val keyInfoResult = session.sharedSecretStorageService.getDefaultKey()
+                if (!keyInfoResult.isSuccess()) {
+                    _viewEvents.post(SharedSecureStorageViewEvent.HideModalLoading)
+                    _viewEvents.post(SharedSecureStorageViewEvent.Error(stringProvider.getString(R.string.failed_to_access_secure_storage)))
+                    return@launch
+                }
+                val keyInfo = (keyInfoResult as KeyInfoResult.Success).keyInfo
+
+                _viewEvents.post(SharedSecureStorageViewEvent.UpdateLoadingState(
+                        WaitingViewData(
+                                message = stringProvider.getString(R.string.keys_backup_restoring_computing_key_waiting_message),
+                                isIndeterminate = true
+                        )
+                ))
+                val keySpec = RawBytesKeySpec.fromRecoveryKey(recoveryKey) ?: return@launch Unit.also {
+                    _viewEvents.post(SharedSecureStorageViewEvent.KeyInlineError(stringProvider.getString(R.string.bootstrap_invalid_recovery_key)))
+                    _viewEvents.post(SharedSecureStorageViewEvent.HideModalLoading)
+                }
+
+                withContext(Dispatchers.IO) {
+                    args.requestedSecrets.forEach {
+                        if (session.getAccountDataEvent(it) != null) {
+                            val res = awaitCallback<String> { callback ->
+                                session.sharedSecretStorageService.getSecret(
+                                        name = it,
+                                        keyId = keyInfo.id,
+                                        secretKey = keySpec,
+                                        callback = callback)
+                            }
+                            decryptedSecretMap[it] = res
+                        } else {
+                            Timber.w("## Cannot find secret $it in SSSS, skip")
+                        }
+                    }
+                }
+            }.fold({
+                setState { copy(checkingSSSSAction = Success(Unit)) }
+                _viewEvents.post(SharedSecureStorageViewEvent.HideModalLoading)
+                val safeForIntentCypher = ByteArrayOutputStream().also {
+                    it.use {
+                        session.securelyStoreObject(decryptedSecretMap as Map<String, String>, args.resultKeyStoreAlias, it)
+                    }
+                }.toByteArray().toBase64NoPadding()
+                _viewEvents.post(SharedSecureStorageViewEvent.FinishSuccess(safeForIntentCypher))
+            }, {
+                setState { copy(checkingSSSSAction = Fail(it)) }
+                _viewEvents.post(SharedSecureStorageViewEvent.HideModalLoading)
+                _viewEvents.post(SharedSecureStorageViewEvent.KeyInlineError(stringProvider.getString(R.string.keys_backup_passphrase_error_decrypt)))
+            })
         }
     }
 
     private fun handleSubmitPassphrase(action: SharedSecureStorageAction.SubmitPassphrase) {
+        _viewEvents.post(SharedSecureStorageViewEvent.ShowModalLoading)
         val decryptedSecretMap = HashMap<String, String>()
+        setState { copy(checkingSSSSAction = Loading()) }
         viewModelScope.launch(Dispatchers.IO) {
             runCatching {
-                _viewEvents.post(SharedSecureStorageViewEvent.ShowModalLoading)
                 val passphrase = action.passphrase
                 val keyInfoResult = session.sharedSecretStorageService.getDefaultKey()
                 if (!keyInfoResult.isSuccess()) {
@@ -100,7 +218,6 @@ class SharedSecureStorageViewModel @AssistedInject constructor(
                         passphrase,
                         keyInfo.content.passphrase?.salt ?: "",
                         keyInfo.content.passphrase?.iterations ?: 0,
-                        // TODO
                         object : ProgressListener {
                             override fun onProgress(progress: Int, total: Int) {
                                 _viewEvents.post(SharedSecureStorageViewEvent.UpdateLoadingState(
@@ -132,6 +249,7 @@ class SharedSecureStorageViewModel @AssistedInject constructor(
                     }
                 }
             }.fold({
+                setState { copy(checkingSSSSAction = Success(Unit)) }
                 _viewEvents.post(SharedSecureStorageViewEvent.HideModalLoading)
                 val safeForIntentCypher = ByteArrayOutputStream().also {
                     it.use {
@@ -140,6 +258,7 @@ class SharedSecureStorageViewModel @AssistedInject constructor(
                 }.toByteArray().toBase64NoPadding()
                 _viewEvents.post(SharedSecureStorageViewEvent.FinishSuccess(safeForIntentCypher))
             }, {
+                setState { copy(checkingSSSSAction = Fail(it)) }
                 _viewEvents.post(SharedSecureStorageViewEvent.HideModalLoading)
                 _viewEvents.post(SharedSecureStorageViewEvent.InlineError(stringProvider.getString(R.string.keys_backup_passphrase_error_decrypt)))
             })
@@ -163,8 +282,8 @@ class SharedSecureStorageViewModel @AssistedInject constructor(
         @JvmStatic
         override fun create(viewModelContext: ViewModelContext, state: SharedSecureStorageViewState): SharedSecureStorageViewModel? {
             val activity: SharedSecureStorageActivity = viewModelContext.activity()
-            val args: SharedSecureStorageActivity.Args = activity.intent.getParcelableExtra(MvRx.KEY_ARG)
-            return activity.viewModelFactory.create(state, args)
+            val args: SharedSecureStorageActivity.Args? = activity.intent.getParcelableExtra(MvRx.KEY_ARG)
+            return args?.let { activity.viewModelFactory.create(state, it) }
         }
     }
 }
diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/quads/SharedSecuredStorageKeyFragment.kt b/vector/src/main/java/im/vector/riotx/features/crypto/quads/SharedSecuredStorageKeyFragment.kt
new file mode 100644
index 0000000000..db4c5230fd
--- /dev/null
+++ b/vector/src/main/java/im/vector/riotx/features/crypto/quads/SharedSecuredStorageKeyFragment.kt
@@ -0,0 +1,125 @@
+/*
+ * 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.riotx.features.crypto.quads
+
+import android.app.Activity
+import android.content.Intent
+import android.os.Bundle
+import android.view.View
+import android.view.inputmethod.EditorInfo
+import com.airbnb.mvrx.activityViewModel
+import com.airbnb.mvrx.withState
+import com.jakewharton.rxbinding3.view.clicks
+import com.jakewharton.rxbinding3.widget.editorActionEvents
+import com.jakewharton.rxbinding3.widget.textChanges
+import im.vector.matrix.android.api.extensions.tryThis
+import im.vector.riotx.R
+import im.vector.riotx.core.platform.VectorBaseFragment
+import im.vector.riotx.core.resources.ColorProvider
+import im.vector.riotx.core.utils.startImportTextFromFileIntent
+import io.reactivex.android.schedulers.AndroidSchedulers
+import kotlinx.android.synthetic.main.fragment_ssss_access_from_key.*
+import kotlinx.android.synthetic.main.fragment_ssss_access_from_passphrase.*
+import java.util.concurrent.TimeUnit
+import javax.inject.Inject
+
+class SharedSecuredStorageKeyFragment @Inject constructor(
+        private val colorProvider: ColorProvider
+) : VectorBaseFragment() {
+
+    override fun getLayoutResId() = R.layout.fragment_ssss_access_from_key
+
+    val sharedViewModel: SharedSecureStorageViewModel by activityViewModel()
+
+    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+        super.onViewCreated(view, savedInstanceState)
+        ssss_restore_with_key_text.text = getString(R.string.enter_secret_storage_input_key)
+
+        ssss_key_enter_edittext.editorActionEvents()
+                .debounce(300, TimeUnit.MILLISECONDS)
+                .observeOn(AndroidSchedulers.mainThread())
+                .subscribe {
+                    if (it.actionId == EditorInfo.IME_ACTION_DONE) {
+                        submit()
+                    }
+                }
+                .disposeOnDestroyView()
+
+        ssss_key_enter_edittext.textChanges()
+                .skipInitialValue()
+                .subscribe {
+                    ssss_key_enter_til.error = null
+                    ssss_key_submit.isEnabled = it.isNotBlank()
+                }
+                .disposeOnDestroyView()
+
+        ssss_key_use_file.clicks()
+                .debounce(300, TimeUnit.MILLISECONDS)
+                .observeOn(AndroidSchedulers.mainThread())
+                .subscribe {
+                    startImportTextFromFileIntent(this, IMPORT_FILE_REQ)
+                }
+                .disposeOnDestroyView()
+
+        sharedViewModel.observeViewEvents {
+            when (it) {
+                is SharedSecureStorageViewEvent.KeyInlineError -> {
+                    ssss_key_enter_til.error = it.message
+                }
+            }
+        }
+
+        ssss_key_submit.clicks()
+                .debounce(300, TimeUnit.MILLISECONDS)
+                .observeOn(AndroidSchedulers.mainThread())
+                .subscribe {
+                    submit()
+                }
+                .disposeOnDestroyView()
+    }
+
+    fun submit() {
+        val text = ssss_key_enter_edittext.text.toString()
+        if (text.isBlank()) return // Should not reach this point as button disabled
+        ssss_key_submit.isEnabled = false
+        sharedViewModel.handle(SharedSecureStorageAction.SubmitKey(text))
+    }
+
+    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
+        if (requestCode == IMPORT_FILE_REQ && resultCode == Activity.RESULT_OK) {
+            data?.data?.let { dataURI ->
+                tryThis {
+                    activity?.contentResolver?.openInputStream(dataURI)
+                            ?.bufferedReader()
+                            ?.use { it.readText() }
+                            ?.let {
+                                ssss_key_enter_edittext.setText(it)
+                            }
+                }
+            }
+            return
+        }
+        super.onActivityResult(requestCode, resultCode, data)
+    }
+
+    override fun invalidate() = withState(sharedViewModel) { _ ->
+    }
+
+    companion object {
+        private const val IMPORT_FILE_REQ = 0
+    }
+}
diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/quads/SharedSecuredStoragePassphraseFragment.kt b/vector/src/main/java/im/vector/riotx/features/crypto/quads/SharedSecuredStoragePassphraseFragment.kt
index f7a5e7c1bc..82d27aea1b 100644
--- a/vector/src/main/java/im/vector/riotx/features/crypto/quads/SharedSecuredStoragePassphraseFragment.kt
+++ b/vector/src/main/java/im/vector/riotx/features/crypto/quads/SharedSecuredStoragePassphraseFragment.kt
@@ -19,6 +19,7 @@ package im.vector.riotx.features.crypto.quads
 import android.os.Bundle
 import android.view.View
 import android.view.inputmethod.EditorInfo
+import androidx.core.text.toSpannable
 import com.airbnb.mvrx.activityViewModel
 import com.airbnb.mvrx.withState
 import com.jakewharton.rxbinding3.view.clicks
@@ -27,12 +28,16 @@ import com.jakewharton.rxbinding3.widget.textChanges
 import im.vector.riotx.R
 import im.vector.riotx.core.extensions.showPassword
 import im.vector.riotx.core.platform.VectorBaseFragment
+import im.vector.riotx.core.resources.ColorProvider
+import im.vector.riotx.core.utils.colorizeMatchingText
 import io.reactivex.android.schedulers.AndroidSchedulers
 import kotlinx.android.synthetic.main.fragment_ssss_access_from_passphrase.*
-import me.gujun.android.span.span
 import java.util.concurrent.TimeUnit
+import javax.inject.Inject
 
-class SharedSecuredStoragePassphraseFragment : VectorBaseFragment() {
+class SharedSecuredStoragePassphraseFragment @Inject constructor(
+        private val colorProvider: ColorProvider
+): VectorBaseFragment() {
 
     override fun getLayoutResId() = R.layout.fragment_ssss_access_from_passphrase
 
@@ -41,15 +46,17 @@ class SharedSecuredStoragePassphraseFragment : VectorBaseFragment() {
     override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
         super.onViewCreated(view, savedInstanceState)
 
-        ssss_restore_with_passphrase_warning_text.text = span {
-            span(getString(R.string.enter_secret_storage_passphrase_warning)) {
-                textStyle = "bold"
-            }
-            +" "
-            +getString(R.string.enter_secret_storage_passphrase_warning_text)
-        }
-
-        ssss_restore_with_passphrase_warning_reason.text = getString(R.string.enter_secret_storage_passphrase_reason_verify)
+        // If has passphrase
+        val pass = getString(R.string.recovery_passphrase)
+        val key = getString(R.string.recovery_key)
+        ssss_restore_with_passphrase_warning_text.text = getString(
+                R.string.enter_secret_storage_passphrase_or_key,
+                pass,
+                key
+        )
+                .toSpannable()
+                .colorizeMatchingText(pass, colorProvider.getColorFromAttribute(android.R.attr.textColorLink))
+                .colorizeMatchingText(key, colorProvider.getColorFromAttribute(android.R.attr.textColorLink))
 
         ssss_passphrase_enter_edittext.editorActionEvents()
                 .debounce(300, TimeUnit.MILLISECONDS)
@@ -84,11 +91,11 @@ class SharedSecuredStoragePassphraseFragment : VectorBaseFragment() {
                 }
                 .disposeOnDestroyView()
 
-        ssss_passphrase_cancel.clicks()
+        ssss_passphrase_use_key.clicks()
                 .debounce(300, TimeUnit.MILLISECONDS)
                 .observeOn(AndroidSchedulers.mainThread())
                 .subscribe {
-                    sharedViewModel.handle(SharedSecureStorageAction.Cancel)
+                    sharedViewModel.handle(SharedSecureStorageAction.UseKey)
                 }
                 .disposeOnDestroyView()
 
diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/recover/BackupToQuadSMigrationTask.kt b/vector/src/main/java/im/vector/riotx/features/crypto/recover/BackupToQuadSMigrationTask.kt
new file mode 100644
index 0000000000..e29d0d636d
--- /dev/null
+++ b/vector/src/main/java/im/vector/riotx/features/crypto/recover/BackupToQuadSMigrationTask.kt
@@ -0,0 +1,172 @@
+/*
+ * 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.riotx.features.crypto.recover
+
+import im.vector.matrix.android.api.NoOpMatrixCallback
+import im.vector.matrix.android.api.listeners.ProgressListener
+import im.vector.matrix.android.api.session.Session
+import im.vector.matrix.android.api.session.crypto.crosssigning.KEYBACKUP_SECRET_SSSS_NAME
+import im.vector.matrix.android.api.session.securestorage.EmptyKeySigner
+import im.vector.matrix.android.api.session.securestorage.RawBytesKeySpec
+import im.vector.matrix.android.api.session.securestorage.SharedSecretStorageService
+import im.vector.matrix.android.api.session.securestorage.SsssKeyCreationInfo
+import im.vector.matrix.android.internal.crypto.crosssigning.toBase64NoPadding
+import im.vector.matrix.android.internal.crypto.keysbackup.deriveKey
+import im.vector.matrix.android.internal.crypto.keysbackup.util.computeRecoveryKey
+import im.vector.matrix.android.internal.crypto.keysbackup.util.extractCurveKeyFromRecoveryKey
+import im.vector.matrix.android.internal.util.awaitCallback
+import im.vector.riotx.R
+import im.vector.riotx.core.platform.ViewModelTask
+import im.vector.riotx.core.platform.WaitingViewData
+import im.vector.riotx.core.resources.StringProvider
+import timber.log.Timber
+import java.util.UUID
+import javax.inject.Inject
+
+class BackupToQuadSMigrationTask @Inject constructor(
+        val session: Session,
+        val stringProvider: StringProvider
+) : ViewModelTask<BackupToQuadSMigrationTask.Params, BackupToQuadSMigrationTask.Result> {
+
+    sealed class Result {
+        object Success : Result()
+        abstract class Failure(val error: String?) : Result()
+        object InvalidRecoverySecret : Failure(null)
+        object NoKeyBackupVersion : Failure(null)
+        object IllegalParams : Failure(null)
+        class ErrorFailure(throwable: Throwable) : Failure(throwable.localizedMessage)
+    }
+
+    data class Params(
+            val passphrase: String?,
+            val recoveryKey: String?,
+            val progressListener: BootstrapProgressListener? = null
+    )
+
+    override suspend fun execute(params: Params): Result {
+        try {
+            // We need to use the current secret for keybackup and use it as the new master key for SSSS
+            // Then we need to put back the backup key in sss
+            val keysBackupService = session.cryptoService().keysBackupService()
+            val quadS = session.sharedSecretStorageService
+
+            val version = keysBackupService.keysBackupVersion ?: return Result.NoKeyBackupVersion
+
+            reportProgress(params, R.string.bootstrap_progress_checking_backup)
+            val curveKey =
+                    (if (params.recoveryKey != null) {
+                        extractCurveKeyFromRecoveryKey(params.recoveryKey)
+                    } else if (!params.passphrase.isNullOrEmpty() && version.getAuthDataAsMegolmBackupAuthData()?.privateKeySalt != null) {
+                        version.getAuthDataAsMegolmBackupAuthData()?.let { authData ->
+                            deriveKey(params.passphrase, authData.privateKeySalt!!, authData.privateKeyIterations!!, object : ProgressListener {
+                                override fun onProgress(progress: Int, total: Int) {
+                                    params.progressListener?.onProgress(WaitingViewData(
+                                            stringProvider.getString(R.string.bootstrap_progress_checking_backup_with_info,
+                                                    "$progress/$total")
+                                    ))
+                                }
+                            })
+                        }
+                    } else null)
+                            ?: return Result.IllegalParams
+
+            reportProgress(params, R.string.bootstrap_progress_compute_curve_key)
+            val recoveryKey = computeRecoveryKey(curveKey)
+
+            val isValid = awaitCallback<Boolean> {
+                keysBackupService.isValidRecoveryKeyForCurrentVersion(recoveryKey, it)
+            }
+
+            if (!isValid) return Result.InvalidRecoverySecret
+
+            val info: SsssKeyCreationInfo =
+                    when {
+                        params.passphrase?.isNotEmpty() == true -> {
+                            reportProgress(params, R.string.bootstrap_progress_generating_ssss)
+                            awaitCallback {
+                                quadS.generateKeyWithPassphrase(
+                                        UUID.randomUUID().toString(),
+                                        "ssss_key",
+                                        params.passphrase,
+                                        EmptyKeySigner(),
+                                        object : ProgressListener {
+                                            override fun onProgress(progress: Int, total: Int) {
+                                                params.progressListener?.onProgress(
+                                                        WaitingViewData(
+                                                                stringProvider.getString(
+                                                                        R.string.bootstrap_progress_generating_ssss_with_info,
+                                                                        "$progress/$total")
+                                                        ))
+                                            }
+                                        },
+                                        it
+                                )
+                            }
+                        }
+                        params.recoveryKey != null              -> {
+                            reportProgress(params, R.string.bootstrap_progress_generating_ssss_recovery)
+                            awaitCallback {
+                                quadS.generateKey(
+                                        UUID.randomUUID().toString(),
+                                        extractCurveKeyFromRecoveryKey(params.recoveryKey)?.let { RawBytesKeySpec(it) },
+                                        "ssss_key",
+                                        EmptyKeySigner(),
+                                        it
+                                )
+                            }
+                        }
+                        else                                    -> {
+                            return Result.IllegalParams
+                        }
+                    }
+
+            // Ok, so now we have migrated the old keybackup secret as the quadS key
+            // Now we need to store the keybackup key in SSSS in a compatible way
+            reportProgress(params, R.string.bootstrap_progress_storing_in_sss)
+            awaitCallback<Unit> {
+                quadS.storeSecret(
+                        KEYBACKUP_SECRET_SSSS_NAME,
+                        curveKey.toBase64NoPadding(),
+                        listOf(SharedSecretStorageService.KeyRef(info.keyId, info.keySpec)),
+                        it
+                )
+            }
+
+            // save for gossiping
+            keysBackupService.saveBackupRecoveryKey(recoveryKey, version.version)
+
+            // while we are there let's restore, but do not block
+            session.cryptoService().keysBackupService().restoreKeysWithRecoveryKey(
+                    version,
+                    recoveryKey,
+                    null,
+                    null,
+                    null,
+                    NoOpMatrixCallback()
+            )
+
+            return Result.Success
+        } catch (failure: Throwable) {
+            Timber.e(failure, "## BackupToQuadSMigrationTask - Failed to migrate backup")
+            return Result.ErrorFailure(failure)
+        }
+    }
+
+    private fun reportProgress(params: Params, stringRes: Int) {
+        params.progressListener?.onProgress(WaitingViewData(stringProvider.getString(stringRes)))
+    }
+}
diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/recover/BootstrapActions.kt b/vector/src/main/java/im/vector/riotx/features/crypto/recover/BootstrapActions.kt
index 7c0f2c1c46..2d9440a77d 100644
--- a/vector/src/main/java/im/vector/riotx/features/crypto/recover/BootstrapActions.kt
+++ b/vector/src/main/java/im/vector/riotx/features/crypto/recover/BootstrapActions.kt
@@ -40,4 +40,8 @@ sealed class BootstrapActions : VectorViewModelAction {
     object SaveReqQueryStarted : BootstrapActions()
     data class SaveKeyToUri(val os: OutputStream) : BootstrapActions()
     object SaveReqFailed : BootstrapActions()
+
+    object HandleForgotBackupPassphrase : BootstrapActions()
+    data class DoMigrateWithPassphrase(val passphrase: String) : BootstrapActions()
+    data class DoMigrateWithRecoveryKey(val recoveryKey: String) : BootstrapActions()
 }
diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/recover/BootstrapBottomSheet.kt b/vector/src/main/java/im/vector/riotx/features/crypto/recover/BootstrapBottomSheet.kt
index 6305f161e3..e48c674159 100644
--- a/vector/src/main/java/im/vector/riotx/features/crypto/recover/BootstrapBottomSheet.kt
+++ b/vector/src/main/java/im/vector/riotx/features/crypto/recover/BootstrapBottomSheet.kt
@@ -18,6 +18,7 @@ package im.vector.riotx.features.crypto.recover
 
 import android.app.Dialog
 import android.os.Bundle
+import android.os.Parcelable
 import android.view.KeyEvent
 import android.view.LayoutInflater
 import android.view.View
@@ -26,18 +27,26 @@ import android.view.WindowManager
 import androidx.appcompat.app.AlertDialog
 import androidx.core.content.ContextCompat
 import androidx.fragment.app.Fragment
+import androidx.fragment.app.FragmentManager
 import com.airbnb.mvrx.fragmentViewModel
 import com.airbnb.mvrx.withState
 import im.vector.riotx.R
 import im.vector.riotx.core.di.ScreenComponent
 import im.vector.riotx.core.extensions.commitTransaction
+import im.vector.riotx.core.extensions.exhaustive
 import im.vector.riotx.core.platform.VectorBaseBottomSheetDialogFragment
+import kotlinx.android.parcel.Parcelize
 import kotlinx.android.synthetic.main.bottom_sheet_bootstrap.*
 import javax.inject.Inject
 import kotlin.reflect.KClass
 
 class BootstrapBottomSheet : VectorBaseBottomSheetDialogFragment() {
 
+    @Parcelize
+    data class Args(
+            val isNewAccount: Boolean
+    ) : Parcelable
+
     override val showExpanded = true
 
     @Inject
@@ -113,40 +122,70 @@ class BootstrapBottomSheet : VectorBaseBottomSheetDialogFragment() {
     override fun invalidate() = withState(viewModel) { state ->
 
         when (state.step) {
-            is BootstrapStep.SetupPassphrase   -> {
+            is BootstrapStep.CheckingMigration           -> {
+                bootstrapIcon.setImageDrawable(ContextCompat.getDrawable(requireContext(), R.drawable.ic_message_password))
+                bootstrapTitleText.text = getString(R.string.upgrade_security)
+                showFragment(BootstrapWaitingFragment::class, Bundle())
+            }
+            is BootstrapStep.SetupPassphrase             -> {
                 bootstrapIcon.setImageDrawable(ContextCompat.getDrawable(requireContext(), R.drawable.ic_message_password))
                 bootstrapTitleText.text = getString(R.string.set_recovery_passphrase, getString(R.string.recovery_passphrase))
                 showFragment(BootstrapEnterPassphraseFragment::class, Bundle())
             }
-            is BootstrapStep.ConfirmPassphrase -> {
+            is BootstrapStep.ConfirmPassphrase           -> {
                 bootstrapIcon.setImageDrawable(ContextCompat.getDrawable(requireContext(), R.drawable.ic_message_password))
                 bootstrapTitleText.text = getString(R.string.confirm_recovery_passphrase, getString(R.string.recovery_passphrase))
                 showFragment(BootstrapConfirmPassphraseFragment::class, Bundle())
             }
-            is BootstrapStep.AccountPassword   -> {
+            is BootstrapStep.AccountPassword             -> {
                 bootstrapIcon.setImageDrawable(ContextCompat.getDrawable(requireContext(), R.drawable.ic_user))
                 bootstrapTitleText.text = getString(R.string.account_password)
                 showFragment(BootstrapAccountPasswordFragment::class, Bundle())
             }
-            is BootstrapStep.Initializing      -> {
+            is BootstrapStep.Initializing                -> {
                 bootstrapIcon.setImageDrawable(ContextCompat.getDrawable(requireContext(), R.drawable.ic_message_key))
                 bootstrapTitleText.text = getString(R.string.bootstrap_loading_title)
                 showFragment(BootstrapWaitingFragment::class, Bundle())
             }
-            is BootstrapStep.SaveRecoveryKey   -> {
+            is BootstrapStep.SaveRecoveryKey             -> {
                 bootstrapIcon.setImageDrawable(ContextCompat.getDrawable(requireContext(), R.drawable.ic_message_key))
                 bootstrapTitleText.text = getString(R.string.keys_backup_setup_step3_please_make_copy)
                 showFragment(BootstrapSaveRecoveryKeyFragment::class, Bundle())
             }
-            is BootstrapStep.DoneSuccess       -> {
+            is BootstrapStep.DoneSuccess                 -> {
                 bootstrapIcon.setImageDrawable(ContextCompat.getDrawable(requireContext(), R.drawable.ic_message_key))
                 bootstrapTitleText.text = getString(R.string.bootstrap_finish_title)
                 showFragment(BootstrapConclusionFragment::class, Bundle())
             }
-        }
+            is BootstrapStep.GetBackupSecretForMigration -> {
+                val isKey = when (state.step) {
+                    is BootstrapStep.GetBackupSecretPassForMigration -> state.step.useKey
+                    else                                             -> true
+                }
+                val drawableRes = if (isKey) R.drawable.ic_message_key else R.drawable.ic_message_password
+                bootstrapIcon.setImageDrawable(ContextCompat.getDrawable(
+                        requireContext(),
+                        drawableRes)
+                )
+                bootstrapTitleText.text = getString(R.string.upgrade_security)
+                showFragment(BootstrapMigrateBackupFragment::class, Bundle())
+            }
+        }.exhaustive
         super.invalidate()
     }
 
+    companion object {
+
+        const val EXTRA_ARGS = "EXTRA_ARGS"
+
+        fun show(fragmentManager: FragmentManager, isAccountCreation: Boolean) {
+            BootstrapBottomSheet().apply {
+                isCancelable = false
+                arguments = Bundle().apply { this.putParcelable(EXTRA_ARGS, Args(isAccountCreation)) }
+            }.show(fragmentManager, "BootstrapBottomSheet")
+        }
+    }
+
     private fun showFragment(fragmentClass: KClass<out Fragment>, bundle: Bundle) {
         if (childFragmentManager.findFragmentByTag(fragmentClass.simpleName) == null) {
             childFragmentManager.commitTransaction {
diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/recover/BootstrapConfirmPassphraseFragment.kt b/vector/src/main/java/im/vector/riotx/features/crypto/recover/BootstrapConfirmPassphraseFragment.kt
index 34a49e852e..d09eafee58 100644
--- a/vector/src/main/java/im/vector/riotx/features/crypto/recover/BootstrapConfirmPassphraseFragment.kt
+++ b/vector/src/main/java/im/vector/riotx/features/crypto/recover/BootstrapConfirmPassphraseFragment.kt
@@ -95,6 +95,14 @@ class BootstrapConfirmPassphraseFragment @Inject constructor(
                     sharedViewModel.handle(BootstrapActions.TogglePasswordVisibility)
                 }
                 .disposeOnDestroyView()
+
+        bootstrapSubmit.clicks()
+                .debounce(300, TimeUnit.MILLISECONDS)
+                .observeOn(AndroidSchedulers.mainThread())
+                .subscribe {
+                    submit()
+                }
+                .disposeOnDestroyView()
     }
 
     private fun submit() = withState(sharedViewModel) { state ->
@@ -113,8 +121,6 @@ class BootstrapConfirmPassphraseFragment @Inject constructor(
     }
 
     override fun invalidate() = withState(sharedViewModel) { state ->
-        super.invalidate()
-
         if (state.step is BootstrapStep.ConfirmPassphrase) {
             val isPasswordVisible = state.step.isPasswordVisible
             ssss_passphrase_enter_edittext.showPassword(isPasswordVisible, updateCursor = false)
diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/recover/BootstrapCrossSigningTask.kt b/vector/src/main/java/im/vector/riotx/features/crypto/recover/BootstrapCrossSigningTask.kt
index a19604d78e..b70902631a 100644
--- a/vector/src/main/java/im/vector/riotx/features/crypto/recover/BootstrapCrossSigningTask.kt
+++ b/vector/src/main/java/im/vector/riotx/features/crypto/recover/BootstrapCrossSigningTask.kt
@@ -18,26 +18,27 @@ package im.vector.riotx.features.crypto.recover
 
 import im.vector.matrix.android.api.failure.Failure
 import im.vector.matrix.android.api.failure.MatrixError
+import im.vector.matrix.android.api.failure.toRegistrationFlowResponse
 import im.vector.matrix.android.api.session.Session
+import im.vector.matrix.android.api.session.crypto.crosssigning.KEYBACKUP_SECRET_SSSS_NAME
 import im.vector.matrix.android.api.session.crypto.crosssigning.MASTER_KEY_SSSS_NAME
 import im.vector.matrix.android.api.session.crypto.crosssigning.SELF_SIGNING_KEY_SSSS_NAME
 import im.vector.matrix.android.api.session.crypto.crosssigning.USER_SIGNING_KEY_SSSS_NAME
 import im.vector.matrix.android.api.session.securestorage.EmptyKeySigner
 import im.vector.matrix.android.api.session.securestorage.SharedSecretStorageService
 import im.vector.matrix.android.api.session.securestorage.SsssKeyCreationInfo
+import im.vector.matrix.android.api.session.securestorage.SsssKeySpec
 import im.vector.matrix.android.internal.auth.data.LoginFlowTypes
-import im.vector.matrix.android.internal.auth.registration.RegistrationFlowResponse
+import im.vector.matrix.android.internal.crypto.crosssigning.toBase64NoPadding
 import im.vector.matrix.android.internal.crypto.keysbackup.model.MegolmBackupCreationInfo
 import im.vector.matrix.android.internal.crypto.keysbackup.model.rest.KeysVersion
+import im.vector.matrix.android.internal.crypto.keysbackup.util.extractCurveKeyFromRecoveryKey
 import im.vector.matrix.android.internal.crypto.model.rest.UserPasswordAuth
-import im.vector.matrix.android.internal.di.MoshiProvider
 import im.vector.matrix.android.internal.util.awaitCallback
 import im.vector.riotx.R
+import im.vector.riotx.core.platform.ViewModelTask
 import im.vector.riotx.core.platform.WaitingViewData
 import im.vector.riotx.core.resources.StringProvider
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.async
-import kotlinx.coroutines.launch
 import timber.log.Timber
 import java.util.UUID
 import javax.inject.Inject
@@ -67,24 +68,16 @@ interface BootstrapProgressListener {
 data class Params(
         val userPasswordAuth: UserPasswordAuth? = null,
         val progressListener: BootstrapProgressListener? = null,
-        val passphrase: String?
+        val passphrase: String?,
+        val keySpec: SsssKeySpec? = null
 )
 
 class BootstrapCrossSigningTask @Inject constructor(
         private val session: Session,
         private val stringProvider: StringProvider
-) {
+) : ViewModelTask<Params, BootstrapResult> {
 
-    operator fun invoke(
-            scope: CoroutineScope,
-            params: Params,
-            onResult: (BootstrapResult) -> Unit = {}
-    ) {
-        val backgroundJob = scope.async { execute(params) }
-        scope.launch { onResult(backgroundJob.await()) }
-    }
-
-    suspend fun execute(params: Params): BootstrapResult {
+    override suspend fun execute(params: Params): BootstrapResult {
         params.progressListener?.onProgress(
                 WaitingViewData(
                         stringProvider.getString(R.string.bootstrap_crosssigning_progress_initializing),
@@ -124,6 +117,7 @@ class BootstrapCrossSigningTask @Inject constructor(
                 } ?: kotlin.run {
                     ssssService.generateKey(
                             UUID.randomUUID().toString(),
+                            params.keySpec,
                             "ssss_key",
                             EmptyKeySigner(),
                             it
@@ -205,14 +199,26 @@ class BootstrapCrossSigningTask @Inject constructor(
                 )
         )
         try {
-            val creationInfo = awaitCallback<MegolmBackupCreationInfo> {
-                session.cryptoService().keysBackupService().prepareKeysBackupVersion(null, null, it)
+            if (session.cryptoService().keysBackupService().keysBackupVersion == null) {
+                val creationInfo = awaitCallback<MegolmBackupCreationInfo> {
+                    session.cryptoService().keysBackupService().prepareKeysBackupVersion(null, null, it)
+                }
+                val version = awaitCallback<KeysVersion> {
+                    session.cryptoService().keysBackupService().createKeysBackupVersion(creationInfo, it)
+                }
+                // Save it for gossiping
+                session.cryptoService().keysBackupService().saveBackupRecoveryKey(creationInfo.recoveryKey, version = version.version)
+
+                awaitCallback<Unit> {
+                    extractCurveKeyFromRecoveryKey(creationInfo.recoveryKey)?.toBase64NoPadding()?.let { secret ->
+                        ssssService.storeSecret(
+                                KEYBACKUP_SECRET_SSSS_NAME,
+                                secret,
+                                listOf(SharedSecretStorageService.KeyRef(keyInfo.keyId, keyInfo.keySpec)), it
+                        )
+                    }
+                }
             }
-            val version = awaitCallback<KeysVersion> {
-                session.cryptoService().keysBackupService().createKeysBackupVersion(creationInfo, it)
-            }
-            // Save it for gossiping
-            session.cryptoService().keysBackupService().saveBackupRecoveryKey(creationInfo.recoveryKey, version = version.version)
         } catch (failure: Throwable) {
             Timber.e("## BootstrapCrossSigningTask: Failed to init keybackup")
         }
@@ -223,15 +229,10 @@ class BootstrapCrossSigningTask @Inject constructor(
     private fun handleInitializeXSigningError(failure: Throwable): BootstrapResult {
         if (failure is Failure.ServerError && failure.error.code == MatrixError.M_FORBIDDEN) {
             return BootstrapResult.InvalidPasswordError(failure.error)
-        } else if (failure is Failure.OtherServerError && failure.httpCode == 401) {
-            try {
-                MoshiProvider.providesMoshi()
-                        .adapter(RegistrationFlowResponse::class.java)
-                        .fromJson(failure.errorBody)
-            } catch (e: Exception) {
-                null
-            }?.let { flowResponse ->
-                if (flowResponse.flows?.any { it.stages?.contains(LoginFlowTypes.PASSWORD) == true } != true) {
+        } else {
+            val registrationFlowResponse = failure.toRegistrationFlowResponse()
+            if (registrationFlowResponse != null) {
+                if (registrationFlowResponse.flows?.any { it.stages?.contains(LoginFlowTypes.PASSWORD) == true } != true) {
                     // can't do this from here
                     return BootstrapResult.UnsupportedAuthFlow()
                 }
diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/recover/BootstrapEnterPassphraseFragment.kt b/vector/src/main/java/im/vector/riotx/features/crypto/recover/BootstrapEnterPassphraseFragment.kt
index 35e2e1373c..952b0e5d03 100644
--- a/vector/src/main/java/im/vector/riotx/features/crypto/recover/BootstrapEnterPassphraseFragment.kt
+++ b/vector/src/main/java/im/vector/riotx/features/crypto/recover/BootstrapEnterPassphraseFragment.kt
@@ -90,6 +90,14 @@ class BootstrapEnterPassphraseFragment @Inject constructor(
                     sharedViewModel.handle(BootstrapActions.TogglePasswordVisibility)
                 }
                 .disposeOnDestroyView()
+
+        bootstrapSubmit.clicks()
+                .debounce(300, TimeUnit.MILLISECONDS)
+                .observeOn(AndroidSchedulers.mainThread())
+                .subscribe {
+                    submit()
+                }
+                .disposeOnDestroyView()
     }
 
     private fun submit() = withState(sharedViewModel) { state ->
@@ -108,8 +116,6 @@ class BootstrapEnterPassphraseFragment @Inject constructor(
     }
 
     override fun invalidate() = withState(sharedViewModel) { state ->
-        super.invalidate()
-
         if (state.step is BootstrapStep.SetupPassphrase) {
             val isPasswordVisible = state.step.isPasswordVisible
             ssss_passphrase_enter_edittext.showPassword(isPasswordVisible, updateCursor = false)
diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/recover/BootstrapMigrateBackupFragment.kt b/vector/src/main/java/im/vector/riotx/features/crypto/recover/BootstrapMigrateBackupFragment.kt
new file mode 100644
index 0000000000..f1847e5ab5
--- /dev/null
+++ b/vector/src/main/java/im/vector/riotx/features/crypto/recover/BootstrapMigrateBackupFragment.kt
@@ -0,0 +1,211 @@
+/*
+ * 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.riotx.features.crypto.recover
+
+import android.app.Activity
+import android.content.Intent
+import android.os.Bundle
+import android.text.InputType.TYPE_CLASS_TEXT
+import android.text.InputType.TYPE_TEXT_FLAG_MULTI_LINE
+import android.text.InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD
+import android.view.View
+import android.view.inputmethod.EditorInfo
+import androidx.core.text.toSpannable
+import androidx.core.view.isVisible
+import com.airbnb.mvrx.parentFragmentViewModel
+import com.airbnb.mvrx.withState
+import com.jakewharton.rxbinding3.view.clicks
+import com.jakewharton.rxbinding3.widget.editorActionEvents
+import com.jakewharton.rxbinding3.widget.textChanges
+import im.vector.matrix.android.api.extensions.tryThis
+import im.vector.matrix.android.internal.crypto.keysbackup.util.isValidRecoveryKey
+import im.vector.riotx.R
+import im.vector.riotx.core.extensions.hideKeyboard
+import im.vector.riotx.core.extensions.showPassword
+import im.vector.riotx.core.platform.VectorBaseFragment
+import im.vector.riotx.core.resources.ColorProvider
+import im.vector.riotx.core.utils.colorizeMatchingText
+import im.vector.riotx.core.utils.startImportTextFromFileIntent
+import io.reactivex.android.schedulers.AndroidSchedulers
+import kotlinx.android.synthetic.main.fragment_bootstrap_enter_passphrase.bootstrapDescriptionText
+import kotlinx.android.synthetic.main.fragment_bootstrap_migrate_backup.*
+import java.util.concurrent.TimeUnit
+import javax.inject.Inject
+
+class BootstrapMigrateBackupFragment @Inject constructor(
+        private val colorProvider: ColorProvider
+) : VectorBaseFragment() {
+
+    override fun getLayoutResId() = R.layout.fragment_bootstrap_migrate_backup
+
+    val sharedViewModel: BootstrapSharedViewModel by parentFragmentViewModel()
+
+    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+        super.onViewCreated(view, savedInstanceState)
+
+        withState(sharedViewModel) {
+            // set initial value (usefull when coming back)
+            bootstrapMigrateEditText.setText(it.passphrase ?: "")
+        }
+        bootstrapMigrateEditText.editorActionEvents()
+                .debounce(300, TimeUnit.MILLISECONDS)
+                .observeOn(AndroidSchedulers.mainThread())
+                .subscribe {
+                    if (it.actionId == EditorInfo.IME_ACTION_DONE) {
+                        submit()
+                    }
+                }
+                .disposeOnDestroyView()
+
+        bootstrapMigrateEditText.textChanges()
+                .skipInitialValue()
+                .subscribe {
+                    bootstrapRecoveryKeyEnterTil.error = null
+                    // sharedViewModel.handle(BootstrapActions.UpdateCandidatePassphrase(it?.toString() ?: ""))
+                }
+                .disposeOnDestroyView()
+
+        // sharedViewModel.observeViewEvents {}
+        bootstrapMigrateContinueButton.clicks()
+                .debounce(300, TimeUnit.MILLISECONDS)
+                .observeOn(AndroidSchedulers.mainThread())
+                .subscribe {
+                    submit()
+                }
+                .disposeOnDestroyView()
+
+        bootstrapMigrateShowPassword.clicks()
+                .debounce(300, TimeUnit.MILLISECONDS)
+                .observeOn(AndroidSchedulers.mainThread())
+                .subscribe {
+                    sharedViewModel.handle(BootstrapActions.TogglePasswordVisibility)
+                }
+                .disposeOnDestroyView()
+
+        bootstrapMigrateForgotPassphrase.clicks()
+                .debounce(300, TimeUnit.MILLISECONDS)
+                .observeOn(AndroidSchedulers.mainThread())
+                .subscribe {
+                    sharedViewModel.handle(BootstrapActions.HandleForgotBackupPassphrase)
+                }
+                .disposeOnDestroyView()
+
+        bootstrapMigrateUseFile.clicks()
+                .debounce(300, TimeUnit.MILLISECONDS)
+                .observeOn(AndroidSchedulers.mainThread())
+                .subscribe {
+                    startImportTextFromFileIntent(this, IMPORT_FILE_REQ)
+                }
+                .disposeOnDestroyView()
+    }
+
+    private fun submit() = withState(sharedViewModel) { state ->
+        if (state.step !is BootstrapStep.GetBackupSecretForMigration) {
+            return@withState
+        }
+        val isEnteringKey =
+                when (state.step) {
+                    is BootstrapStep.GetBackupSecretPassForMigration -> state.step.useKey
+                    else                                             -> true
+                }
+
+        val secret = bootstrapMigrateEditText.text?.toString()
+        if (secret.isNullOrBlank()) {
+            val errRes = if (isEnteringKey) R.string.recovery_key_empty_error_message else R.string.passphrase_empty_error_message
+            bootstrapRecoveryKeyEnterTil.error = getString(errRes)
+        } else if (isEnteringKey && !isValidRecoveryKey(secret)) {
+            bootstrapRecoveryKeyEnterTil.error = getString(R.string.bootstrap_invalid_recovery_key)
+        } else {
+            view?.hideKeyboard()
+            if (isEnteringKey) {
+                sharedViewModel.handle(BootstrapActions.DoMigrateWithRecoveryKey(secret))
+            } else {
+                sharedViewModel.handle(BootstrapActions.DoMigrateWithPassphrase(secret))
+            }
+        }
+    }
+
+    override fun invalidate() = withState(sharedViewModel) { state ->
+        if (state.step !is BootstrapStep.GetBackupSecretForMigration) {
+            return@withState
+        }
+
+        val isEnteringKey =
+                when (state.step) {
+                    is BootstrapStep.GetBackupSecretPassForMigration -> state.step.useKey
+                    else                                             -> true
+                }
+
+        if (isEnteringKey) {
+            bootstrapMigrateShowPassword.isVisible = false
+            bootstrapMigrateEditText.inputType = TYPE_CLASS_TEXT or TYPE_TEXT_VARIATION_VISIBLE_PASSWORD or TYPE_TEXT_FLAG_MULTI_LINE
+
+            val recKey = getString(R.string.bootstrap_migration_backup_recovery_key)
+            bootstrapDescriptionText.text = getString(R.string.enter_account_password, recKey)
+                    .toSpannable()
+                    .colorizeMatchingText(recKey, colorProvider.getColorFromAttribute(android.R.attr.textColorLink))
+
+            bootstrapMigrateEditText.hint = recKey
+
+            bootstrapMigrateEditText.hint = recKey
+            bootstrapMigrateForgotPassphrase.isVisible = false
+            bootstrapMigrateUseFile.isVisible = true
+        } else {
+            bootstrapMigrateShowPassword.isVisible = true
+
+            if (state.step is BootstrapStep.GetBackupSecretPassForMigration) {
+                val isPasswordVisible = state.step.isPasswordVisible
+                bootstrapMigrateEditText.showPassword(isPasswordVisible, updateCursor = false)
+                bootstrapMigrateShowPassword.setImageResource(if (isPasswordVisible) R.drawable.ic_eye_closed_black else R.drawable.ic_eye_black)
+            }
+
+            bootstrapDescriptionText.text = getString(R.string.bootstrap_migration_enter_backup_password)
+
+            bootstrapMigrateEditText.hint = getString(R.string.passphrase_enter_passphrase)
+
+            bootstrapMigrateForgotPassphrase.isVisible = true
+
+            val recKey = getString(R.string.bootstrap_migration_use_recovery_key)
+            bootstrapMigrateForgotPassphrase.text = getString(R.string.bootstrap_migration_with_passphrase_helper_with_link, recKey)
+                    .toSpannable()
+                    .colorizeMatchingText(recKey, colorProvider.getColorFromAttribute(android.R.attr.textColorLink))
+
+            bootstrapMigrateUseFile.isVisible = false
+        }
+    }
+
+    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
+        if (requestCode == IMPORT_FILE_REQ && resultCode == Activity.RESULT_OK) {
+            data?.data?.let { dataURI ->
+                tryThis {
+                    activity?.contentResolver?.openInputStream(dataURI)
+                            ?.bufferedReader()
+                            ?.use { it.readText() }
+                            ?.let {
+                                bootstrapMigrateEditText.setText(it)
+                            }
+                }
+            }
+            return
+        }
+        super.onActivityResult(requestCode, resultCode, data)
+    }
+
+    companion object {
+        private const val IMPORT_FILE_REQ = 0
+    }
+}
diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/recover/BootstrapSharedViewModel.kt b/vector/src/main/java/im/vector/riotx/features/crypto/recover/BootstrapSharedViewModel.kt
index 998899374c..6d96d9038e 100644
--- a/vector/src/main/java/im/vector/riotx/features/crypto/recover/BootstrapSharedViewModel.kt
+++ b/vector/src/main/java/im/vector/riotx/features/crypto/recover/BootstrapSharedViewModel.kt
@@ -31,20 +31,26 @@ import com.nulabinc.zxcvbn.Zxcvbn
 import com.squareup.inject.assisted.Assisted
 import com.squareup.inject.assisted.AssistedInject
 import im.vector.matrix.android.api.session.Session
+import im.vector.matrix.android.api.session.securestorage.RawBytesKeySpec
 import im.vector.matrix.android.api.session.securestorage.SsssKeyCreationInfo
+import im.vector.matrix.android.internal.crypto.keysbackup.model.rest.KeysVersionResult
+import im.vector.matrix.android.internal.crypto.keysbackup.util.extractCurveKeyFromRecoveryKey
 import im.vector.matrix.android.internal.crypto.model.rest.UserPasswordAuth
+import im.vector.matrix.android.internal.util.awaitCallback
 import im.vector.riotx.R
 import im.vector.riotx.core.extensions.exhaustive
 import im.vector.riotx.core.platform.VectorViewModel
 import im.vector.riotx.core.platform.WaitingViewData
 import im.vector.riotx.core.resources.StringProvider
 import im.vector.riotx.features.login.ReAuthHelper
+import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.launch
 import java.io.OutputStream
 
 data class BootstrapViewState(
         val step: BootstrapStep = BootstrapStep.SetupPassphrase(false),
         val passphrase: String? = null,
+        val migrationRecoveryKey: String? = null,
         val passphraseRepeat: String? = null,
         val crossSigningInitialization: Async<Unit> = Uninitialized,
         val passphraseStrength: Async<Strength> = Uninitialized,
@@ -55,20 +61,13 @@ data class BootstrapViewState(
         val recoverySaveFileProcess: Async<Unit> = Uninitialized
 ) : MvRxState
 
-sealed class BootstrapStep {
-    data class SetupPassphrase(val isPasswordVisible: Boolean) : BootstrapStep()
-    data class ConfirmPassphrase(val isPasswordVisible: Boolean) : BootstrapStep()
-    data class AccountPassword(val isPasswordVisible: Boolean, val failure: String? = null) : BootstrapStep()
-    object Initializing : BootstrapStep()
-    data class SaveRecoveryKey(val isSaved: Boolean) : BootstrapStep()
-    object DoneSuccess : BootstrapStep()
-}
-
 class BootstrapSharedViewModel @AssistedInject constructor(
         @Assisted initialState: BootstrapViewState,
+        @Assisted val args: BootstrapBottomSheet.Args,
         private val stringProvider: StringProvider,
         private val session: Session,
         private val bootstrapTask: BootstrapCrossSigningTask,
+        private val migrationTask: BackupToQuadSMigrationTask,
         private val reAuthHelper: ReAuthHelper
 ) : VectorViewModel<BootstrapViewState, BootstrapActions, BootstrapViewEvents>(initialState) {
 
@@ -76,7 +75,53 @@ class BootstrapSharedViewModel @AssistedInject constructor(
 
     @AssistedInject.Factory
     interface Factory {
-        fun create(initialState: BootstrapViewState): BootstrapSharedViewModel
+        fun create(initialState: BootstrapViewState, args: BootstrapBottomSheet.Args): BootstrapSharedViewModel
+    }
+
+    init {
+        // need to check if user have an existing keybackup
+        if (args.isNewAccount) {
+            setState {
+                copy(step = BootstrapStep.SetupPassphrase(false))
+            }
+        } else {
+            setState {
+                copy(step = BootstrapStep.CheckingMigration)
+            }
+
+            // We need to check if there is an existing backup
+            viewModelScope.launch(Dispatchers.IO) {
+                val version = awaitCallback<KeysVersionResult?> {
+                    session.cryptoService().keysBackupService().getCurrentVersion(it)
+                }
+                if (version == null) {
+                    // we just resume plain bootstrap
+                    setState {
+                        copy(step = BootstrapStep.SetupPassphrase(false))
+                    }
+                } else {
+                    // we need to get existing backup passphrase/key and convert to SSSS
+                    val keyVersion = awaitCallback<KeysVersionResult?> {
+                        session.cryptoService().keysBackupService().getVersion(version.version ?: "", it)
+                    }
+                    if (keyVersion == null) {
+                        // strange case... just finish?
+                        _viewEvents.post(BootstrapViewEvents.Dismiss)
+                    } else {
+                        val isBackupCreatedFromPassphrase = keyVersion.getAuthDataAsMegolmBackupAuthData()?.privateKeySalt != null
+                        if (isBackupCreatedFromPassphrase) {
+                            setState {
+                                copy(step = BootstrapStep.GetBackupSecretPassForMigration(isPasswordVisible = false, useKey = false))
+                            }
+                        } else {
+                            setState {
+                                copy(step = BootstrapStep.GetBackupSecretKeyForMigration)
+                            }
+                        }
+                    }
+                }
+            }
+        }
     }
 
     override fun handle(action: BootstrapActions) = withState { state ->
@@ -84,23 +129,27 @@ class BootstrapSharedViewModel @AssistedInject constructor(
             is BootstrapActions.GoBack                           -> queryBack()
             BootstrapActions.TogglePasswordVisibility            -> {
                 when (state.step) {
-                    is BootstrapStep.SetupPassphrase   -> {
+                    is BootstrapStep.SetupPassphrase                 -> {
                         setState {
                             copy(step = state.step.copy(isPasswordVisible = !state.step.isPasswordVisible))
                         }
                     }
-                    is BootstrapStep.ConfirmPassphrase -> {
+                    is BootstrapStep.ConfirmPassphrase               -> {
                         setState {
                             copy(step = state.step.copy(isPasswordVisible = !state.step.isPasswordVisible))
                         }
                     }
-
-                    is BootstrapStep.AccountPassword   -> {
+                    is BootstrapStep.AccountPassword                 -> {
                         setState {
                             copy(step = state.step.copy(isPasswordVisible = !state.step.isPasswordVisible))
                         }
                     }
-                    else                               -> {
+                    is BootstrapStep.GetBackupSecretPassForMigration -> {
+                        setState {
+                            copy(step = state.step.copy(isPasswordVisible = !state.step.isPasswordVisible))
+                        }
+                    }
+                    else                                             -> {
                     }
                 }
             }
@@ -162,6 +211,12 @@ class BootstrapSharedViewModel @AssistedInject constructor(
                         )
                     }
                 } else {
+                    setState {
+                        copy(
+                                passphrase = null,
+                                passphraseRepeat = null
+                        )
+                    }
                     startInitializeFlow(action.auth)
                 }
             }
@@ -197,12 +252,25 @@ class BootstrapSharedViewModel @AssistedInject constructor(
                     copy(step = BootstrapStep.AccountPassword(false))
                 }
             }
+            BootstrapActions.HandleForgotBackupPassphrase        -> {
+                if (state.step is BootstrapStep.GetBackupSecretPassForMigration) {
+                    setState {
+                        copy(step = BootstrapStep.GetBackupSecretPassForMigration(state.step.isPasswordVisible, true))
+                    }
+                } else return@withState
+            }
             is BootstrapActions.ReAuth                           -> {
                 startInitializeFlow(
                         state.currentReAuth?.copy(password = action.pass)
                                 ?: UserPasswordAuth(user = session.myUserId, password = action.pass)
                 )
             }
+            is BootstrapActions.DoMigrateWithPassphrase          -> {
+                startMigrationFlow(state.step, action.passphrase, null)
+            }
+            is BootstrapActions.DoMigrateWithRecoveryKey         -> {
+                startMigrationFlow(state.step, null, action.recoveryKey)
+            }
         }.exhaustive
     }
 
@@ -210,7 +278,7 @@ class BootstrapSharedViewModel @AssistedInject constructor(
     // Business Logic
     // =======================================
     private fun saveRecoveryKeyToUri(os: OutputStream) = withState { state ->
-        viewModelScope.launch {
+        viewModelScope.launch(Dispatchers.IO) {
             kotlin.runCatching {
                 os.use {
                     os.write((state.recoveryKeyCreationInfo?.recoveryKey?.formatRecoveryKey() ?: "").toByteArray())
@@ -231,6 +299,57 @@ class BootstrapSharedViewModel @AssistedInject constructor(
         }
     }
 
+    private fun startMigrationFlow(prevState: BootstrapStep, passphrase: String?, recoveryKey: String?) {
+        setState {
+            copy(step = BootstrapStep.Initializing)
+        }
+        viewModelScope.launch(Dispatchers.IO) {
+            val progressListener = object : BootstrapProgressListener {
+                override fun onProgress(data: WaitingViewData) {
+                    setState {
+                        copy(
+                                initializationWaitingViewData = data
+                        )
+                    }
+                }
+            }
+            migrationTask.invoke(this, BackupToQuadSMigrationTask.Params(passphrase, recoveryKey, progressListener)) {
+                if (it is BackupToQuadSMigrationTask.Result.Success) {
+                    setState {
+                        copy(
+                                passphrase = passphrase,
+                                passphraseRepeat = passphrase,
+                                migrationRecoveryKey = recoveryKey
+                        )
+                    }
+                    val auth = reAuthHelper.rememberedAuth()
+                    if (auth == null) {
+                        setState {
+                            copy(
+                                    step = BootstrapStep.AccountPassword(false)
+                            )
+                        }
+                    } else {
+                        startInitializeFlow(auth)
+                    }
+                } else {
+                    _viewEvents.post(
+                            BootstrapViewEvents.ModalError(
+                                    (it as? BackupToQuadSMigrationTask.Result.Failure)?.error
+                                            ?: stringProvider.getString(R.string.matrix_error
+                                            )
+                            )
+                    )
+                    setState {
+                        copy(
+                                step = prevState
+                        )
+                    }
+                }
+            }
+        }
+    }
+
     private fun startInitializeFlow(auth: UserPasswordAuth?) {
         setState {
             copy(step = BootstrapStep.Initializing)
@@ -247,11 +366,12 @@ class BootstrapSharedViewModel @AssistedInject constructor(
         }
 
         withState { state ->
-            viewModelScope.launch {
+            viewModelScope.launch(Dispatchers.IO) {
                 bootstrapTask.invoke(this, Params(
                         userPasswordAuth = auth ?: reAuthHelper.rememberedAuth(),
                         progressListener = progressListener,
-                        passphrase = state.passphrase
+                        passphrase = state.passphrase,
+                        keySpec = state.migrationRecoveryKey?.let { extractCurveKeyFromRecoveryKey(it)?.let { RawBytesKeySpec(it) } }
                 )) {
                     when (it) {
                         is BootstrapResult.Success                 -> {
@@ -309,11 +429,30 @@ class BootstrapSharedViewModel @AssistedInject constructor(
 
     private fun queryBack() = withState { state ->
         when (state.step) {
-            is BootstrapStep.SetupPassphrase   -> {
+            is BootstrapStep.GetBackupSecretPassForMigration -> {
+                if (state.step.useKey) {
+                    // go back to passphrase
+                    setState {
+                        copy(
+                                step = BootstrapStep.GetBackupSecretPassForMigration(
+                                        isPasswordVisible = state.step.isPasswordVisible,
+                                        useKey = false
+                                )
+                        )
+                    }
+                } else {
+                    _viewEvents.post(BootstrapViewEvents.SkipBootstrap())
+                }
+            }
+            is BootstrapStep.GetBackupSecretKeyForMigration  -> {
                 // do we let you cancel from here?
                 _viewEvents.post(BootstrapViewEvents.SkipBootstrap())
             }
-            is BootstrapStep.ConfirmPassphrase -> {
+            is BootstrapStep.SetupPassphrase                 -> {
+                // do we let you cancel from here?
+                _viewEvents.post(BootstrapViewEvents.SkipBootstrap())
+            }
+            is BootstrapStep.ConfirmPassphrase               -> {
                 setState {
                     copy(
                             step = BootstrapStep.SetupPassphrase(
@@ -322,15 +461,15 @@ class BootstrapSharedViewModel @AssistedInject constructor(
                     )
                 }
             }
-            is BootstrapStep.AccountPassword   -> {
+            is BootstrapStep.AccountPassword                 -> {
                 _viewEvents.post(BootstrapViewEvents.SkipBootstrap(state.passphrase != null))
             }
-            BootstrapStep.Initializing         -> {
+            BootstrapStep.Initializing                       -> {
                 // do we let you cancel from here?
                 _viewEvents.post(BootstrapViewEvents.SkipBootstrap(state.passphrase != null))
             }
             is BootstrapStep.SaveRecoveryKey,
-            BootstrapStep.DoneSuccess          -> {
+            BootstrapStep.DoneSuccess                        -> {
                 // nop
             }
         }
@@ -344,7 +483,9 @@ class BootstrapSharedViewModel @AssistedInject constructor(
 
         override fun create(viewModelContext: ViewModelContext, state: BootstrapViewState): BootstrapSharedViewModel? {
             val fragment: BootstrapBottomSheet = (viewModelContext as FragmentViewModelContext).fragment()
-            return fragment.bootstrapViewModelFactory.create(state)
+            val args: BootstrapBottomSheet.Args = fragment.arguments?.getParcelable(BootstrapBottomSheet.EXTRA_ARGS)
+                    ?: BootstrapBottomSheet.Args(true)
+            return fragment.bootstrapViewModelFactory.create(state, args)
         }
     }
 }
diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/recover/BootstrapStep.kt b/vector/src/main/java/im/vector/riotx/features/crypto/recover/BootstrapStep.kt
new file mode 100644
index 0000000000..2c649ae99c
--- /dev/null
+++ b/vector/src/main/java/im/vector/riotx/features/crypto/recover/BootstrapStep.kt
@@ -0,0 +1,92 @@
+/*
+ * 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.riotx.features.crypto.recover
+
+/**
+ *                             ┌─────────────────────────┐
+ *                             │ User has signing keys?  │──────────── Account
+ *                             └─────────────────────────┘            Creation ?
+ *                                          │                              │
+ *                                          No                             │
+ *                                          │                              │
+ *                                          │                              │
+ *                                          ▼                              │
+ *                        ┌───────────────────────────────────┐            │
+ *                        │  BootstrapStep.CheckingMigration  │            │
+ *                        └───────────────────────────────────┘            │
+ *                                          │                              │
+ *                                          │                              │
+ *                           Existing       ├─────────No ───────┐          │
+ *                     ┌────Keybackup───────┘     KeyBackup     │          │
+ *                     │                                        │          │
+ *                     │                                        ▼          ▼
+ *                     ▼                                    ┌────────────────────────────────────┐
+ *     ┌─────────────────────────────────────────┐          │   BootstrapStep.SetupPassphrase    │◀─┐
+ *     │BootstrapStep.GetBackupSecretForMigration│          └────────────────────────────────────┘  │
+ *     └─────────────────────────────────────────┘                             │                    │
+ *                             │                                               │                 ┌Back
+ *                             │                                               ▼                 │
+ *                             │                            ┌────────────────────────────────────┤
+ *                             │                            │  BootstrapStep.ConfirmPassphrase   │──┐
+ *                             │                            └────────────────────────────────────┘  │
+ *                             │                                               │                    │
+ *                             │                                      is password needed?           │
+ *                             │                                               │                    │
+ *                             │                                               ▼                    │
+ *                             │                            ┌────────────────────────────────────┐  │
+ *                             │                            │   BootstrapStep.AccountPassword    │  │
+ *                             │                            └────────────────────────────────────┘  │
+ *                             │                                               │                    │
+ *                             │                                               │                    │
+ *                             │                            ┌──────────────────┘         password not needed (in
+ *                             │                            │                                    memory)
+ *                             │                            │                                       │
+ *                             │                            ▼                                       │
+ *                             │         ┌────────────────────────────────────┐                     │
+ *                             └────────▶│     BootstrapStep.Initializing     │◀────────────────────┘
+ *                                       └────────────────────────────────────┘
+ *                                                          │
+ *                                                          │
+ *                                                          │
+ *                                                          ▼
+ *                                        ┌────────────────────────────────────┐
+ *                                        │   BootstrapStep.SaveRecoveryKey    │
+ *                                        └────────────────────────────────────┘
+ *                                                          │
+ *                                                          │
+ *                                                          │
+ *                                                          ▼
+ *                                       ┌────────────────────────────────────────┐
+ *                                       │       BootstrapStep.DoneSuccess        │
+ *                                       └────────────────────────────────────────┘
+ *
+ */
+
+sealed class BootstrapStep {
+    data class SetupPassphrase(val isPasswordVisible: Boolean) : BootstrapStep()
+    data class ConfirmPassphrase(val isPasswordVisible: Boolean) : BootstrapStep()
+    data class AccountPassword(val isPasswordVisible: Boolean, val failure: String? = null) : BootstrapStep()
+    object CheckingMigration : BootstrapStep()
+
+    abstract class GetBackupSecretForMigration : BootstrapStep()
+    data class GetBackupSecretPassForMigration(val isPasswordVisible: Boolean, val useKey: Boolean) : GetBackupSecretForMigration()
+    object GetBackupSecretKeyForMigration : GetBackupSecretForMigration()
+
+    object Initializing : BootstrapStep()
+    data class SaveRecoveryKey(val isSaved: Boolean) : BootstrapStep()
+    object DoneSuccess : BootstrapStep()
+}
diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/recover/BootstrapWaitingFragment.kt b/vector/src/main/java/im/vector/riotx/features/crypto/recover/BootstrapWaitingFragment.kt
index ff79fa6a4b..1c6c9e6d9b 100644
--- a/vector/src/main/java/im/vector/riotx/features/crypto/recover/BootstrapWaitingFragment.kt
+++ b/vector/src/main/java/im/vector/riotx/features/crypto/recover/BootstrapWaitingFragment.kt
@@ -16,8 +16,7 @@
 
 package im.vector.riotx.features.crypto.recover
 
-import android.os.Bundle
-import android.view.View
+import androidx.core.view.isVisible
 import com.airbnb.mvrx.parentFragmentViewModel
 import com.airbnb.mvrx.withState
 import im.vector.riotx.R
@@ -31,12 +30,22 @@ class BootstrapWaitingFragment @Inject constructor() : VectorBaseFragment() {
 
     val sharedViewModel: BootstrapSharedViewModel by parentFragmentViewModel()
 
-    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
-        super.onViewCreated(view, savedInstanceState)
-    }
-
     override fun invalidate() = withState(sharedViewModel) { state ->
-        if (state.step !is BootstrapStep.Initializing) return@withState
-        bootstrapLoadingStatusText.text = state.initializationWaitingViewData?.message
+        when (state.step) {
+            is BootstrapStep.Initializing -> {
+                bootstrapLoadingStatusText.isVisible = true
+                bootstrapDescriptionText.isVisible = true
+                bootstrapLoadingStatusText.text = state.initializationWaitingViewData?.message
+            }
+//            is BootstrapStep.CheckingMigration -> {
+//                bootstrapLoadingStatusText.isVisible = false
+//                bootstrapDescriptionText.isVisible = false
+//            }
+            else                          -> {
+                // just show the spinner
+                bootstrapLoadingStatusText.isVisible = false
+                bootstrapDescriptionText.isVisible = false
+            }
+        }
     }
 }
diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/verification/IncomingVerificationRequestHandler.kt b/vector/src/main/java/im/vector/riotx/features/crypto/verification/IncomingVerificationRequestHandler.kt
index ccd3e6578a..2bd815b6df 100644
--- a/vector/src/main/java/im/vector/riotx/features/crypto/verification/IncomingVerificationRequestHandler.kt
+++ b/vector/src/main/java/im/vector/riotx/features/crypto/verification/IncomingVerificationRequestHandler.kt
@@ -66,7 +66,7 @@ class IncomingVerificationRequestHandler @Inject constructor(
                         uid,
                         context.getString(R.string.sas_incoming_request_notif_title),
                         context.getString(R.string.sas_incoming_request_notif_content, name),
-                        R.drawable.shield,
+                        R.drawable.ic_shield_black,
                         shouldBeDisplayedIn = { activity ->
                             if (activity is VectorBaseActivity) {
                                 // TODO a bit too hugly :/
diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/verification/VerificationBottomSheet.kt b/vector/src/main/java/im/vector/riotx/features/crypto/verification/VerificationBottomSheet.kt
index 695716d386..7a3d38f649 100644
--- a/vector/src/main/java/im/vector/riotx/features/crypto/verification/VerificationBottomSheet.kt
+++ b/vector/src/main/java/im/vector/riotx/features/crypto/verification/VerificationBottomSheet.kt
@@ -165,7 +165,9 @@ class VerificationBottomSheet : VectorBaseBottomSheetDialogFragment() {
                 } else {
                     otherUserShield.setImageResource(R.drawable.ic_shield_warning)
                 }
-                otherUserNameText.text = getString(R.string.complete_security)
+                otherUserNameText.text = getString(
+                        if (state.selfVerificationMode) R.string.crosssigning_verify_this_session else R.string.crosssigning_verify_session
+                )
                 otherUserShield.isVisible = true
             } else {
                 avatarRenderer.render(matrixItem, otherUserAvatarImageView)
@@ -241,7 +243,7 @@ class VerificationBottomSheet : VectorBaseBottomSheetDialogFragment() {
         }
 
         when (state.qrTransactionState) {
-            is VerificationTxState.QrScannedByOther -> {
+            is VerificationTxState.QrScannedByOther               -> {
                 showFragment(VerificationQrScannedByOtherFragment::class, Bundle())
                 return@withState
             }
@@ -252,19 +254,19 @@ class VerificationBottomSheet : VectorBaseBottomSheetDialogFragment() {
                 })
                 return@withState
             }
-            is VerificationTxState.Verified         -> {
+            is VerificationTxState.Verified                       -> {
                 showFragment(VerificationConclusionFragment::class, Bundle().apply {
                     putParcelable(MvRx.KEY_ARG, VerificationConclusionFragment.Args(true, null, state.isMe))
                 })
                 return@withState
             }
-            is VerificationTxState.Cancelled        -> {
+            is VerificationTxState.Cancelled                      -> {
                 showFragment(VerificationConclusionFragment::class, Bundle().apply {
                     putParcelable(MvRx.KEY_ARG, VerificationConclusionFragment.Args(false, state.qrTransactionState.cancelCode.value, state.isMe))
                 })
                 return@withState
             }
-            else                                    -> Unit
+            else                                                  -> Unit
         }
 
         // At this point there is no SAS transaction for this request
@@ -324,10 +326,6 @@ class VerificationBottomSheet : VectorBaseBottomSheetDialogFragment() {
         }
     }
 
-    override fun dismiss() {
-        super.dismiss()
-    }
-
     companion object {
 
         const val SECRET_REQUEST_CODE = 101
diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/verification/VerificationBottomSheetViewModel.kt b/vector/src/main/java/im/vector/riotx/features/crypto/verification/VerificationBottomSheetViewModel.kt
index c7a5b3a011..7a003c3722 100644
--- a/vector/src/main/java/im/vector/riotx/features/crypto/verification/VerificationBottomSheetViewModel.kt
+++ b/vector/src/main/java/im/vector/riotx/features/crypto/verification/VerificationBottomSheetViewModel.kt
@@ -44,6 +44,7 @@ import im.vector.matrix.android.api.session.crypto.verification.VerificationTran
 import im.vector.matrix.android.api.session.crypto.verification.VerificationTxState
 import im.vector.matrix.android.api.session.events.model.LocalEcho
 import im.vector.matrix.android.api.session.room.model.create.CreateRoomParams
+import im.vector.matrix.android.api.session.securestorage.IntegrityResult
 import im.vector.matrix.android.api.util.MatrixItem
 import im.vector.matrix.android.api.util.toMatrixItem
 import im.vector.matrix.android.internal.crypto.crosssigning.fromBase64
@@ -73,7 +74,8 @@ data class VerificationBottomSheetViewState(
         val isMe: Boolean = false,
         val currentDeviceCanCrossSign: Boolean = false,
         val userWantsToCancel: Boolean = false,
-        val userThinkItsNotHim: Boolean = false
+        val userThinkItsNotHim: Boolean = false,
+        val quadSContainsSecrets: Boolean = true
 ) : MvRxState
 
 class VerificationBottomSheetViewModel @AssistedInject constructor(
@@ -116,6 +118,10 @@ class VerificationBottomSheetViewModel @AssistedInject constructor(
             session.cryptoService().verificationService().getExistingTransaction(args.otherUserId, it) as? QrCodeVerificationTransaction
         }
 
+        val ssssOk = session.sharedSecretStorageService.checkShouldBeAbleToAccessSecrets(
+                listOf(MASTER_KEY_SSSS_NAME, USER_SIGNING_KEY_SSSS_NAME, SELF_SIGNING_KEY_SSSS_NAME),
+                null // default key
+        ) is IntegrityResult.Success
         setState {
             copy(
                     otherUserMxItem = userItem?.toMatrixItem(),
@@ -126,7 +132,8 @@ class VerificationBottomSheetViewModel @AssistedInject constructor(
                     selfVerificationMode = selfVerificationMode,
                     roomId = args.roomId,
                     isMe = args.otherUserId == session.myUserId,
-                    currentDeviceCanCrossSign = session.cryptoService().crossSigningService().canCrossSign()
+                    currentDeviceCanCrossSign = session.cryptoService().crossSigningService().canCrossSign(),
+                    quadSContainsSecrets = ssssOk
             )
         }
 
@@ -384,7 +391,8 @@ class VerificationBottomSheetViewModel @AssistedInject constructor(
                 Unit
             }
         } catch (failure: Throwable) {
-            _viewEvents.post(VerificationBottomSheetViewEvents.ModalError(failure.localizedMessage))
+            _viewEvents.post(
+                    VerificationBottomSheetViewEvents.ModalError(failure.localizedMessage ?: stringProvider.getString(R.string.unexpected_error)))
         }
     }
 
@@ -415,7 +423,7 @@ class VerificationBottomSheetViewModel @AssistedInject constructor(
                 }
             } catch (failure: Throwable) {
                 // Just ignore for now
-                Timber.v("## Failed to restore backup after SSSS recovery")
+                Timber.e(failure, "## Failed to restore backup after SSSS recovery")
             }
         }
     }
diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/verification/cancel/VerificationCancelController.kt b/vector/src/main/java/im/vector/riotx/features/crypto/verification/cancel/VerificationCancelController.kt
index 49b2f7dce1..73f449a3c3 100644
--- a/vector/src/main/java/im/vector/riotx/features/crypto/verification/cancel/VerificationCancelController.kt
+++ b/vector/src/main/java/im/vector/riotx/features/crypto/verification/cancel/VerificationCancelController.kt
@@ -76,7 +76,7 @@ class VerificationCancelController @Inject constructor(
 
         bottomSheetVerificationActionItem {
             id("cancel")
-            title(stringProvider.getString(R.string.cancel))
+            title(stringProvider.getString(R.string.skip))
             titleColor(colorProvider.getColor(R.color.riotx_destructive_accent))
             iconRes(R.drawable.ic_arrow_right)
             iconColor(colorProvider.getColor(R.color.riotx_destructive_accent))
diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/verification/epoxy/BottomSheetSelfWaitItem.kt b/vector/src/main/java/im/vector/riotx/features/crypto/verification/epoxy/BottomSheetSelfWaitItem.kt
new file mode 100644
index 0000000000..6afc330f62
--- /dev/null
+++ b/vector/src/main/java/im/vector/riotx/features/crypto/verification/epoxy/BottomSheetSelfWaitItem.kt
@@ -0,0 +1,30 @@
+/*
+ * Copyright 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.riotx.features.crypto.verification.epoxy
+
+import com.airbnb.epoxy.EpoxyModelClass
+import im.vector.riotx.R
+import im.vector.riotx.core.epoxy.VectorEpoxyHolder
+import im.vector.riotx.core.epoxy.VectorEpoxyModel
+
+/**
+ * A action for bottom sheet.
+ */
+@EpoxyModelClass(layout = R.layout.item_verification_wait)
+abstract class BottomSheetSelfWaitItem : VectorEpoxyModel<BottomSheetSelfWaitItem.Holder>() {
+    class Holder : VectorEpoxyHolder()
+}
diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/verification/request/VerificationRequestController.kt b/vector/src/main/java/im/vector/riotx/features/crypto/verification/request/VerificationRequestController.kt
index 56c76bc2b0..88f6607a41 100644
--- a/vector/src/main/java/im/vector/riotx/features/crypto/verification/request/VerificationRequestController.kt
+++ b/vector/src/main/java/im/vector/riotx/features/crypto/verification/request/VerificationRequestController.kt
@@ -27,6 +27,7 @@ import im.vector.riotx.core.resources.ColorProvider
 import im.vector.riotx.core.resources.StringProvider
 import im.vector.riotx.core.utils.colorizeMatchingText
 import im.vector.riotx.features.crypto.verification.VerificationBottomSheetViewState
+import im.vector.riotx.features.crypto.verification.epoxy.bottomSheetSelfWaitItem
 import im.vector.riotx.features.crypto.verification.epoxy.bottomSheetVerificationActionItem
 import im.vector.riotx.features.crypto.verification.epoxy.bottomSheetVerificationNoticeItem
 import im.vector.riotx.features.crypto.verification.epoxy.bottomSheetVerificationWaitingItem
@@ -56,23 +57,37 @@ class VerificationRequestController @Inject constructor(
                 notice(stringProvider.getString(R.string.verification_open_other_to_verify))
             }
 
+            bottomSheetSelfWaitItem {
+                id("waiting")
+            }
+
             dividerItem {
                 id("sep")
             }
 
-            bottomSheetVerificationWaitingItem {
-                id("waiting")
-                title(stringProvider.getString(R.string.verification_request_waiting, matrixItem.getBestName()))
+            if (state.quadSContainsSecrets) {
+                bottomSheetVerificationActionItem {
+                    id("passphrase")
+                    title(stringProvider.getString(R.string.verification_cannot_access_other_session))
+                    titleColor(colorProvider.getColorFromAttribute(R.attr.riotx_text_primary))
+                    subTitle(stringProvider.getString(R.string.verification_use_passphrase))
+                    iconRes(R.drawable.ic_arrow_right)
+                    iconColor(colorProvider.getColorFromAttribute(R.attr.riotx_text_primary))
+                    listener { listener?.onClickRecoverFromPassphrase() }
+                }
+            }
+
+            dividerItem {
+                id("sep1")
             }
 
             bottomSheetVerificationActionItem {
-                id("passphrase")
-                title(stringProvider.getString(R.string.verification_cannot_access_other_session))
-                titleColor(colorProvider.getColorFromAttribute(R.attr.riotx_text_primary))
-                subTitle(stringProvider.getString(R.string.verification_use_passphrase))
+                id("skip")
+                title(stringProvider.getString(R.string.skip))
+                titleColor(colorProvider.getColor(R.color.riotx_destructive_accent))
                 iconRes(R.drawable.ic_arrow_right)
-                iconColor(colorProvider.getColorFromAttribute(R.attr.riotx_text_primary))
-                listener { listener?.onClickRecoverFromPassphrase() }
+                iconColor(colorProvider.getColor(R.color.riotx_destructive_accent))
+                listener { listener?.onClickSkip() }
             }
         } else {
             val styledText =
@@ -153,5 +168,6 @@ class VerificationRequestController @Inject constructor(
         fun onClickOnWasNotMe()
         fun onClickRecoverFromPassphrase()
         fun onClickDismiss()
+        fun onClickSkip()
     }
 }
diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/verification/request/VerificationRequestFragment.kt b/vector/src/main/java/im/vector/riotx/features/crypto/verification/request/VerificationRequestFragment.kt
index b6c3659988..967f2946c1 100644
--- a/vector/src/main/java/im/vector/riotx/features/crypto/verification/request/VerificationRequestFragment.kt
+++ b/vector/src/main/java/im/vector/riotx/features/crypto/verification/request/VerificationRequestFragment.kt
@@ -70,6 +70,10 @@ class VerificationRequestFragment @Inject constructor(
         viewModel.handle(VerificationAction.SkipVerification)
     }
 
+    override fun onClickSkip() {
+        viewModel.queryCancel()
+    }
+
     override fun onClickOnWasNotMe() {
         viewModel.itWasNotMe()
     }
diff --git a/vector/src/main/java/im/vector/riotx/features/disclaimer/DisclaimerDialog.kt b/vector/src/main/java/im/vector/riotx/features/disclaimer/DisclaimerDialog.kt
index ac6b23a109..86b7fd9fc8 100644
--- a/vector/src/main/java/im/vector/riotx/features/disclaimer/DisclaimerDialog.kt
+++ b/vector/src/main/java/im/vector/riotx/features/disclaimer/DisclaimerDialog.kt
@@ -17,7 +17,7 @@
 package im.vector.riotx.features.disclaimer
 
 import android.app.Activity
-import android.preference.PreferenceManager
+import androidx.preference.PreferenceManager
 import android.view.ViewGroup
 import android.widget.TextView
 import androidx.appcompat.app.AlertDialog
diff --git a/vector/src/main/java/im/vector/riotx/features/home/HomeActivity.kt b/vector/src/main/java/im/vector/riotx/features/home/HomeActivity.kt
index e286c82532..60c974c291 100644
--- a/vector/src/main/java/im/vector/riotx/features/home/HomeActivity.kt
+++ b/vector/src/main/java/im/vector/riotx/features/home/HomeActivity.kt
@@ -35,6 +35,7 @@ import im.vector.matrix.android.internal.crypto.model.MXUsersDevicesMap
 import im.vector.riotx.R
 import im.vector.riotx.core.di.ActiveSessionHolder
 import im.vector.riotx.core.di.ScreenComponent
+import im.vector.riotx.core.extensions.exhaustive
 import im.vector.riotx.core.extensions.hideKeyboard
 import im.vector.riotx.core.extensions.replaceFragment
 import im.vector.riotx.core.platform.ToolbarConfigurable
@@ -91,15 +92,16 @@ class HomeActivity : VectorBaseActivity(), ToolbarConfigurable {
                 .observe()
                 .subscribe { sharedAction ->
                     when (sharedAction) {
-                        is HomeActivitySharedAction.OpenDrawer -> drawerLayout.openDrawer(GravityCompat.START)
-                        is HomeActivitySharedAction.OpenGroup  -> {
+                        is HomeActivitySharedAction.OpenDrawer                 -> drawerLayout.openDrawer(GravityCompat.START)
+                        is HomeActivitySharedAction.CloseDrawer                -> drawerLayout.closeDrawer(GravityCompat.START)
+                        is HomeActivitySharedAction.OpenGroup                  -> {
                             drawerLayout.closeDrawer(GravityCompat.START)
                             replaceFragment(R.id.homeDetailFragmentContainer, HomeDetailFragment::class.java)
                         }
                         is HomeActivitySharedAction.PromptForSecurityBootstrap -> {
-                            BootstrapBottomSheet().apply { isCancelable = false }.show(supportFragmentManager, "BootstrapBottomSheet")
+                            BootstrapBottomSheet.show(supportFragmentManager, true)
                         }
-                    }
+                    }.exhaustive
                 }
                 .disposeOnDestroy()
 
@@ -109,6 +111,7 @@ class HomeActivity : VectorBaseActivity(), ToolbarConfigurable {
         }
         if (intent.getBooleanExtra(EXTRA_ACCOUNT_CREATION, false)) {
             sharedActionViewModel.post(HomeActivitySharedAction.PromptForSecurityBootstrap)
+            sharedActionViewModel.isAccountCreation = true
             intent.removeExtra(EXTRA_ACCOUNT_CREATION)
         }
 
@@ -163,29 +166,54 @@ class HomeActivity : VectorBaseActivity(), ToolbarConfigurable {
                 .getMyCrossSigningKeys()
         val crossSigningEnabledOnAccount = myCrossSigningKeys != null
 
-        if (crossSigningEnabledOnAccount && myCrossSigningKeys?.isTrusted() == false) {
+        if (!crossSigningEnabledOnAccount && !sharedActionViewModel.isAccountCreation) {
+            // Do not propose for SSO accounts, because we do not support yet confirming account credentials using SSO
+            if (session.getHomeServerCapabilities().canChangePassword) {
+                // We need to ask
+                promptSecurityEvent(
+                        session,
+                        R.string.upgrade_security,
+                        R.string.security_prompt_text
+                ) {
+                    it.navigator.upgradeSessionSecurity(it)
+                }
+            } else {
+                // Do not do it again
+                sharedActionViewModel.hasDisplayedCompleteSecurityPrompt = true
+            }
+        } else if (myCrossSigningKeys?.isTrusted() == false) {
             // We need to ask
-            sharedActionViewModel.hasDisplayedCompleteSecurityPrompt = true
-            popupAlertManager.postVectorAlert(
-                    VerificationVectorAlert(
-                            uid = "completeSecurity",
-                            title = getString(R.string.complete_security),
-                            description = getString(R.string.crosssigning_verify_this_session),
-                            iconId = R.drawable.ic_shield_warning
-                    ).apply {
-                        matrixItem = session.getUser(session.myUserId)?.toMatrixItem()
-                        colorInt = ContextCompat.getColor(this@HomeActivity, R.color.riotx_positive_accent)
-                        contentAction = Runnable {
-                            (weakCurrentActivity?.get() as? VectorBaseActivity)?.let {
-                                it.navigator.waitSessionVerification(it)
-                            }
-                        }
-                        dismissedAction = Runnable {}
-                    }
-            )
+            promptSecurityEvent(
+                    session,
+                    R.string.crosssigning_verify_this_session,
+                    R.string.confirm_your_identity
+            ) {
+                it.navigator.waitSessionVerification(it)
+            }
         }
     }
 
+    private fun promptSecurityEvent(session: Session, titleRes: Int, descRes: Int, action: ((VectorBaseActivity) -> Unit)) {
+        sharedActionViewModel.hasDisplayedCompleteSecurityPrompt = true
+        popupAlertManager.postVectorAlert(
+                VerificationVectorAlert(
+                        uid = "upgradeSecurity",
+                        title = getString(titleRes),
+                        description = getString(descRes),
+                        iconId = R.drawable.ic_shield_warning
+                ).apply {
+                    matrixItem = session.getUser(session.myUserId)?.toMatrixItem()
+                    colorInt = ContextCompat.getColor(this@HomeActivity, R.color.riotx_positive_accent)
+                    contentAction = Runnable {
+                        (weakCurrentActivity?.get() as? VectorBaseActivity)?.let {
+                            action(it)
+                        }
+                    }
+                    dismissedAction = Runnable {}
+                }
+        )
+    }
+
     override fun onNewIntent(intent: Intent?) {
         super.onNewIntent(intent)
         if (intent?.hasExtra(EXTRA_CLEAR_EXISTING_NOTIFICATION) == true) {
diff --git a/vector/src/main/java/im/vector/riotx/features/home/HomeActivitySharedAction.kt b/vector/src/main/java/im/vector/riotx/features/home/HomeActivitySharedAction.kt
index 902ea93588..a074c0e879 100644
--- a/vector/src/main/java/im/vector/riotx/features/home/HomeActivitySharedAction.kt
+++ b/vector/src/main/java/im/vector/riotx/features/home/HomeActivitySharedAction.kt
@@ -23,6 +23,7 @@ import im.vector.riotx.core.platform.VectorSharedAction
  */
 sealed class HomeActivitySharedAction : VectorSharedAction {
     object OpenDrawer : HomeActivitySharedAction()
+    object CloseDrawer : HomeActivitySharedAction()
     object OpenGroup : HomeActivitySharedAction()
     object PromptForSecurityBootstrap : HomeActivitySharedAction()
 }
diff --git a/vector/src/main/java/im/vector/riotx/features/home/HomeDetailFragment.kt b/vector/src/main/java/im/vector/riotx/features/home/HomeDetailFragment.kt
index 47338f6335..1357b30413 100644
--- a/vector/src/main/java/im/vector/riotx/features/home/HomeDetailFragment.kt
+++ b/vector/src/main/java/im/vector/riotx/features/home/HomeDetailFragment.kt
@@ -1,4 +1,3 @@
-
 /*
  * Copyright 2019 New Vector Ltd
  *
@@ -31,6 +30,7 @@ import com.google.android.material.bottomnavigation.BottomNavigationMenuView
 import im.vector.matrix.android.api.session.crypto.keysbackup.KeysBackupState
 import im.vector.matrix.android.api.session.group.model.GroupSummary
 import im.vector.matrix.android.api.util.toMatrixItem
+import im.vector.matrix.android.internal.crypto.model.rest.DeviceInfo
 import im.vector.riotx.R
 import im.vector.riotx.core.extensions.commitTransactionNow
 import im.vector.riotx.core.glide.GlideApp
@@ -43,6 +43,7 @@ import im.vector.riotx.features.home.room.list.RoomListParams
 import im.vector.riotx.features.home.room.list.UnreadCounterBadgeView
 import im.vector.riotx.features.popup.PopupAlertManager
 import im.vector.riotx.features.popup.VerificationVectorAlert
+import im.vector.riotx.features.settings.VectorSettingsActivity.Companion.EXTRA_DIRECT_ACCESS_SECURITY_PRIVACY_MANAGE_SESSIONS
 import im.vector.riotx.features.workers.signout.SignOutViewModel
 import kotlinx.android.synthetic.main.fragment_home_detail.*
 import timber.log.Timber
@@ -61,7 +62,7 @@ class HomeDetailFragment @Inject constructor(
     private val unreadCounterBadgeViews = arrayListOf<UnreadCounterBadgeView>()
 
     private val viewModel: HomeDetailViewModel by fragmentViewModel()
-    private val unknownDeviceDetectorSharedViewModel : UnknownDeviceDetectorSharedViewModel by activityViewModel()
+    private val unknownDeviceDetectorSharedViewModel: UnknownDeviceDetectorSharedViewModel by activityViewModel()
 
     private lateinit var sharedActionViewModel: HomeSharedActionViewModel
 
@@ -87,39 +88,82 @@ class HomeDetailFragment @Inject constructor(
             switchDisplayMode(displayMode)
         }
 
-        unknownDeviceDetectorSharedViewModel.subscribe {
-            it.unknownSessions.invoke()?.let { unknownDevices ->
-                Timber.v("## Detector - ${unknownDevices.size} Unknown sessions")
-                unknownDevices.forEachIndexed { index, deviceInfo ->
-                    Timber.v("## Detector - #$index deviceId:${deviceInfo.second.deviceId} lastSeenTs:${deviceInfo.second.lastSeenTs}")
-                }
-                val uid = "Newest_Device"
-                alertManager.cancelAlert(uid)
-                if (it.canCrossSign && unknownDevices.isNotEmpty()) {
-                    val newest = unknownDevices.first().second
-                    val user = unknownDevices.first().first
-                    alertManager.postVectorAlert(
-                            VerificationVectorAlert(
-                                    uid = uid,
-                                    title = getString(R.string.new_session),
-                                    description = getString(R.string.new_session_review),
-                                    iconId = R.drawable.ic_shield_warning
-                            ).apply {
-                                matrixItem = user
-                                colorInt = ContextCompat.getColor(requireActivity(), R.color.riotx_accent)
-                                contentAction = Runnable {
-                                    (weakCurrentActivity?.get() as? VectorBaseActivity)
-                                            ?.navigator
-                                            ?.requestSessionVerification(requireContext(), newest.deviceId ?: "")
-                                }
-                                dismissedAction = Runnable {}
-                            }
-                    )
+        unknownDeviceDetectorSharedViewModel.subscribe { state ->
+            state.unknownSessions.invoke()?.let { unknownDevices ->
+//                Timber.v("## Detector Triggerred in fragment - ${unknownDevices.firstOrNull()}")
+                if (unknownDevices.firstOrNull()?.currentSessionTrust == true) {
+                    val uid = "review_login"
+                    alertManager.cancelAlert(uid)
+                    val olderUnverified = unknownDevices.filter { !it.isNew }
+                    val newest = unknownDevices.firstOrNull { it.isNew }?.deviceInfo
+                    if (newest != null) {
+                        promptForNewUnknownDevices(uid, state, newest)
+                    } else if (olderUnverified.isNotEmpty()) {
+                        // In this case we prompt to go to settings to review logins
+                        promptToReviewChanges(uid, state, olderUnverified.map { it.deviceInfo })
+                    }
                 }
             }
         }
     }
 
+    private fun promptForNewUnknownDevices(uid: String, state: UnknownDevicesState, newest: DeviceInfo) {
+        val user = state.myMatrixItem
+        alertManager.postVectorAlert(
+                VerificationVectorAlert(
+                        uid = uid,
+                        title = getString(R.string.new_session),
+                        description = getString(R.string.verify_this_session, newest.displayName ?: newest.deviceId ?: ""),
+                        iconId = R.drawable.ic_shield_warning
+                ).apply {
+                    matrixItem = user
+                    colorInt = ContextCompat.getColor(requireActivity(), R.color.riotx_accent)
+                    contentAction = Runnable {
+                        (weakCurrentActivity?.get() as? VectorBaseActivity)
+                                ?.navigator
+                                ?.requestSessionVerification(requireContext(), newest.deviceId ?: "")
+                        unknownDeviceDetectorSharedViewModel.handle(
+                                UnknownDeviceDetectorSharedViewModel.Action.IgnoreDevice(newest.deviceId?.let { listOf(it) } ?: emptyList())
+                        )
+                    }
+                    dismissedAction = Runnable {
+                        unknownDeviceDetectorSharedViewModel.handle(
+                                UnknownDeviceDetectorSharedViewModel.Action.IgnoreDevice(newest.deviceId?.let { listOf(it) } ?: emptyList())
+                        )
+                    }
+                }
+        )
+    }
+
+    private fun promptToReviewChanges(uid: String, state: UnknownDevicesState, oldUnverified: List<DeviceInfo>) {
+        val user = state.myMatrixItem
+        alertManager.postVectorAlert(
+                VerificationVectorAlert(
+                        uid = uid,
+                        title = getString(R.string.review_logins),
+                        description = getString(R.string.verify_other_sessions),
+                        iconId = R.drawable.ic_shield_warning
+                ).apply {
+                    matrixItem = user
+                    colorInt = ContextCompat.getColor(requireActivity(), R.color.riotx_accent)
+                    contentAction = Runnable {
+                        (weakCurrentActivity?.get() as? VectorBaseActivity)?.let {
+                            // mark as ignored to avoid showing it again
+                            unknownDeviceDetectorSharedViewModel.handle(
+                                    UnknownDeviceDetectorSharedViewModel.Action.IgnoreDevice(oldUnverified.mapNotNull { it.deviceId })
+                            )
+                            it.navigator.openSettings(it, EXTRA_DIRECT_ACCESS_SECURITY_PRIVACY_MANAGE_SESSIONS)
+                        }
+                    }
+                    dismissedAction = Runnable {
+                        unknownDeviceDetectorSharedViewModel.handle(
+                                UnknownDeviceDetectorSharedViewModel.Action.IgnoreDevice(oldUnverified.mapNotNull { it.deviceId })
+                        )
+                    }
+                }
+        )
+    }
+
     private fun onGroupChange(groupSummary: GroupSummary?) {
         groupSummary?.let {
             // Use GlideApp with activity context to avoid the glideRequests to be paused
diff --git a/vector/src/main/java/im/vector/riotx/features/home/HomeDetailViewModel.kt b/vector/src/main/java/im/vector/riotx/features/home/HomeDetailViewModel.kt
index 6b322a2b48..3824ba7922 100644
--- a/vector/src/main/java/im/vector/riotx/features/home/HomeDetailViewModel.kt
+++ b/vector/src/main/java/im/vector/riotx/features/home/HomeDetailViewModel.kt
@@ -22,6 +22,7 @@ import com.airbnb.mvrx.ViewModelContext
 import com.squareup.inject.assisted.Assisted
 import com.squareup.inject.assisted.AssistedInject
 import im.vector.matrix.android.api.session.Session
+import im.vector.matrix.android.api.session.room.model.Membership
 import im.vector.matrix.rx.rx
 import im.vector.riotx.core.di.HasScreenInjector
 import im.vector.riotx.core.platform.EmptyViewEvents
@@ -116,10 +117,14 @@ class HomeDetailViewModel @AssistedInject constructor(@Assisted initialState: Ho
                 .observeOn(Schedulers.computation())
                 .map { it.asSequence() }
                 .subscribe { summaries ->
+                    val invites = summaries
+                            .filter { it.membership == Membership.INVITE }
+                            .count()
+
                     val peopleNotifications = summaries
                             .filter { it.isDirect }
                             .map { it.notificationCount }
-                            .sumBy { i -> i }
+                            .sum()
                     val peopleHasHighlight = summaries
                             .filter { it.isDirect }
                             .any { it.highlightCount > 0 }
@@ -127,14 +132,14 @@ class HomeDetailViewModel @AssistedInject constructor(@Assisted initialState: Ho
                     val roomsNotifications = summaries
                             .filter { !it.isDirect }
                             .map { it.notificationCount }
-                            .sumBy { i -> i }
+                            .sum()
                     val roomsHasHighlight = summaries
                             .filter { !it.isDirect }
                             .any { it.highlightCount > 0 }
 
                     setState {
                         copy(
-                                notificationCountCatchup = peopleNotifications + roomsNotifications,
+                                notificationCountCatchup = peopleNotifications + roomsNotifications + invites,
                                 notificationHighlightCatchup = peopleHasHighlight || roomsHasHighlight,
                                 notificationCountPeople = peopleNotifications,
                                 notificationHighlightPeople = peopleHasHighlight,
diff --git a/vector/src/main/java/im/vector/riotx/features/home/HomeDrawerFragment.kt b/vector/src/main/java/im/vector/riotx/features/home/HomeDrawerFragment.kt
index 9aa9313ad2..a8373797c6 100644
--- a/vector/src/main/java/im/vector/riotx/features/home/HomeDrawerFragment.kt
+++ b/vector/src/main/java/im/vector/riotx/features/home/HomeDrawerFragment.kt
@@ -33,10 +33,15 @@ class HomeDrawerFragment @Inject constructor(
         private val avatarRenderer: AvatarRenderer
 ) : VectorBaseFragment() {
 
+    private lateinit var sharedActionViewModel: HomeSharedActionViewModel
+
     override fun getLayoutResId() = R.layout.fragment_home_drawer
 
     override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
         super.onViewCreated(view, savedInstanceState)
+
+        sharedActionViewModel = activityViewModelProvider.get(HomeSharedActionViewModel::class.java)
+
         if (savedInstanceState == null) {
             replaceChildFragment(R.id.homeDrawerGroupListContainer, GroupListFragment::class.java)
         }
@@ -49,11 +54,13 @@ class HomeDrawerFragment @Inject constructor(
             }
         }
         homeDrawerHeaderSettingsView.setOnClickListener {
+            sharedActionViewModel.post(HomeActivitySharedAction.CloseDrawer)
             navigator.openSettings(requireActivity())
         }
 
         // Debug menu
         homeDrawerHeaderDebugView.setOnClickListener {
+            sharedActionViewModel.post(HomeActivitySharedAction.CloseDrawer)
             navigator.openDebug(requireActivity())
         }
     }
diff --git a/vector/src/main/java/im/vector/riotx/features/home/HomeSharedActionViewModel.kt b/vector/src/main/java/im/vector/riotx/features/home/HomeSharedActionViewModel.kt
index ecbe460b90..4af9262d05 100644
--- a/vector/src/main/java/im/vector/riotx/features/home/HomeSharedActionViewModel.kt
+++ b/vector/src/main/java/im/vector/riotx/features/home/HomeSharedActionViewModel.kt
@@ -21,4 +21,5 @@ import javax.inject.Inject
 
 class HomeSharedActionViewModel @Inject constructor() : VectorSharedActionViewModel<HomeActivitySharedAction>() {
     var hasDisplayedCompleteSecurityPrompt : Boolean = false
+    var isAccountCreation : Boolean = false
 }
diff --git a/vector/src/main/java/im/vector/riotx/features/home/UnknownDeviceDetectorSharedViewModel.kt b/vector/src/main/java/im/vector/riotx/features/home/UnknownDeviceDetectorSharedViewModel.kt
new file mode 100644
index 0000000000..a05e9ee985
--- /dev/null
+++ b/vector/src/main/java/im/vector/riotx/features/home/UnknownDeviceDetectorSharedViewModel.kt
@@ -0,0 +1,156 @@
+/*
+ * 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.riotx.features.home
+
+import com.airbnb.mvrx.Async
+import com.airbnb.mvrx.MvRxState
+import com.airbnb.mvrx.MvRxViewModelFactory
+import com.airbnb.mvrx.Success
+import com.airbnb.mvrx.Uninitialized
+import com.airbnb.mvrx.ViewModelContext
+import im.vector.matrix.android.api.NoOpMatrixCallback
+import im.vector.matrix.android.api.extensions.orFalse
+import im.vector.matrix.android.api.session.Session
+import im.vector.matrix.android.api.util.MatrixItem
+import im.vector.matrix.android.api.util.Optional
+import im.vector.matrix.android.api.util.toMatrixItem
+import im.vector.matrix.android.internal.crypto.model.CryptoDeviceInfo
+import im.vector.matrix.android.internal.crypto.model.rest.DeviceInfo
+import im.vector.matrix.android.internal.crypto.store.PrivateKeysInfo
+import im.vector.matrix.rx.rx
+import im.vector.riotx.core.di.HasScreenInjector
+import im.vector.riotx.core.platform.EmptyViewEvents
+import im.vector.riotx.core.platform.VectorViewModel
+import im.vector.riotx.core.platform.VectorViewModelAction
+import im.vector.riotx.features.settings.VectorPreferences
+import io.reactivex.Observable
+import io.reactivex.functions.Function3
+import timber.log.Timber
+import java.util.concurrent.TimeUnit
+
+data class UnknownDevicesState(
+        val myMatrixItem: MatrixItem.UserItem? = null,
+        val unknownSessions: Async<List<DeviceDetectionInfo>> = Uninitialized
+) : MvRxState
+
+data class DeviceDetectionInfo(
+        val deviceInfo: DeviceInfo,
+        val isNew: Boolean,
+        val currentSessionTrust: Boolean
+)
+
+class UnknownDeviceDetectorSharedViewModel(
+        session: Session,
+        private val vectorPreferences: VectorPreferences,
+        initialState: UnknownDevicesState)
+    : VectorViewModel<UnknownDevicesState, UnknownDeviceDetectorSharedViewModel.Action, EmptyViewEvents>(initialState) {
+
+    sealed class Action : VectorViewModelAction {
+        data class IgnoreDevice(val deviceIds: List<String>) : Action()
+    }
+
+    private val ignoredDeviceList = ArrayList<String>()
+
+    init {
+
+        val currentSessionTs = session.cryptoService().getCryptoDeviceInfo(session.myUserId).firstOrNull {
+            it.deviceId == session.sessionParams.credentials.deviceId
+        }?.firstTimeSeenLocalTs ?: System.currentTimeMillis()
+        Timber.v("## Detector - Current Session first time seen $currentSessionTs")
+
+        ignoredDeviceList.addAll(
+                vectorPreferences.getUnknownDeviceDismissedList().also {
+                    Timber.v("## Detector - Remembered ignored list $it")
+                }
+        )
+
+        Observable.combineLatest<List<CryptoDeviceInfo>, List<DeviceInfo>, Optional<PrivateKeysInfo>, List<DeviceDetectionInfo>>(
+                session.rx().liveUserCryptoDevices(session.myUserId),
+                session.rx().liveMyDeviceInfo(),
+                session.rx().liveCrossSigningPrivateKeys(),
+                Function3 { cryptoList, infoList, pInfo ->
+//                    Timber.v("## Detector trigger ${cryptoList.map { "${it.deviceId} ${it.trustLevel}" }}")
+//                    Timber.v("## Detector trigger canCrossSign ${pInfo.get().selfSigned != null}")
+                    infoList
+                            .filter { info ->
+                                // filter verified session, by checking the crypto device info
+                                cryptoList.firstOrNull { info.deviceId == it.deviceId }?.isVerified?.not().orFalse()
+                            }
+                            // filter out ignored devices
+                            .filter { !ignoredDeviceList.contains(it.deviceId) }
+                            .sortedByDescending { it.lastSeenTs }
+                            .map { deviceInfo ->
+                                val deviceKnownSince = cryptoList.firstOrNull { it.deviceId == deviceInfo.deviceId }?.firstTimeSeenLocalTs ?: 0
+                                DeviceDetectionInfo(
+                                        deviceInfo,
+                                        deviceKnownSince > currentSessionTs + 60_000, // short window to avoid false positive,
+                                        pInfo.getOrNull()?.selfSigned != null // adding this to pass distinct when cross sign change
+                                )
+                            }
+                }
+        )
+                .distinctUntilChanged()
+                .execute { async ->
+//                    Timber.v("## Detector trigger passed distinct")
+                    copy(
+                            myMatrixItem = session.getUser(session.myUserId)?.toMatrixItem(),
+                            unknownSessions = async
+                    )
+                }
+
+        session.rx().liveUserCryptoDevices(session.myUserId)
+                .distinct()
+                .throttleLast(5_000, TimeUnit.MILLISECONDS)
+                .subscribe {
+                    // If we have a new crypto device change, we might want to trigger refresh of device info
+                    session.cryptoService().fetchDevicesList(NoOpMatrixCallback())
+                }.disposeOnClear()
+
+        // trigger a refresh of lastSeen / last Ip
+        session.cryptoService().fetchDevicesList(NoOpMatrixCallback())
+    }
+
+    override fun handle(action: Action) {
+        when (action) {
+            is Action.IgnoreDevice -> {
+                ignoredDeviceList.addAll(action.deviceIds)
+                // local echo
+                withState { state ->
+                    state.unknownSessions.invoke()?.let { detectedSessions ->
+                        val updated = detectedSessions.filter { !action.deviceIds.contains(it.deviceInfo.deviceId) }
+                        setState {
+                            copy(unknownSessions = Success(updated))
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    override fun onCleared() {
+        vectorPreferences.storeUnknownDeviceDismissedList(ignoredDeviceList)
+        super.onCleared()
+    }
+
+    companion object : MvRxViewModelFactory<UnknownDeviceDetectorSharedViewModel, UnknownDevicesState> {
+
+        override fun create(viewModelContext: ViewModelContext, state: UnknownDevicesState): UnknownDeviceDetectorSharedViewModel? {
+            val session = (viewModelContext.activity as HasScreenInjector).injector().activeSessionHolder().getActiveSession()
+            return UnknownDeviceDetectorSharedViewModel(session, VectorPreferences(viewModelContext.activity()), state)
+        }
+    }
+}
diff --git a/vector/src/main/java/im/vector/riotx/features/home/UnknwonDeviceDetectorSharedViewModel.kt b/vector/src/main/java/im/vector/riotx/features/home/UnknwonDeviceDetectorSharedViewModel.kt
deleted file mode 100644
index 180a989858..0000000000
--- a/vector/src/main/java/im/vector/riotx/features/home/UnknwonDeviceDetectorSharedViewModel.kt
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * 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.riotx.features.home
-
-import com.airbnb.mvrx.Async
-import com.airbnb.mvrx.MvRxState
-import com.airbnb.mvrx.MvRxViewModelFactory
-import com.airbnb.mvrx.Uninitialized
-import com.airbnb.mvrx.ViewModelContext
-import im.vector.matrix.android.api.session.Session
-import im.vector.matrix.android.api.util.MatrixItem
-import im.vector.matrix.android.api.util.NoOpCancellable
-import im.vector.matrix.android.api.util.toMatrixItem
-import im.vector.matrix.android.internal.crypto.model.rest.DeviceInfo
-import im.vector.matrix.android.internal.crypto.model.rest.DevicesListResponse
-import im.vector.matrix.rx.rx
-import im.vector.matrix.rx.singleBuilder
-import im.vector.riotx.core.di.HasScreenInjector
-import im.vector.riotx.core.platform.EmptyAction
-import im.vector.riotx.core.platform.EmptyViewEvents
-import im.vector.riotx.core.platform.VectorViewModel
-import io.reactivex.android.schedulers.AndroidSchedulers
-
-data class UnknownDevicesState(
-        val unknownSessions: Async<List<Pair<MatrixItem?, DeviceInfo>>> = Uninitialized,
-        val canCrossSign: Boolean = false
-) : MvRxState
-
-class UnknownDeviceDetectorSharedViewModel(session: Session, initialState: UnknownDevicesState)
-    : VectorViewModel<UnknownDevicesState, EmptyAction, EmptyViewEvents>(initialState) {
-
-    init {
-        session.rx().liveUserCryptoDevices(session.myUserId)
-                .observeOn(AndroidSchedulers.mainThread())
-                .switchMap { deviceList ->
-                    //                    Timber.v("## Detector - ============================")
-//                    Timber.v("## Detector - Crypto device update  ${deviceList.map { "${it.deviceId} : ${it.isVerified}" }}")
-                    singleBuilder<DevicesListResponse> {
-                        session.cryptoService().getDevicesList(it)
-                        NoOpCancellable
-                    }.map { resp ->
-                        //                        Timber.v("## Detector - Device Infos  ${resp.devices?.map { "${it.deviceId} : lastSeen:${it.lastSeenTs}" }}")
-                        resp.devices?.filter { info ->
-                            deviceList.firstOrNull { info.deviceId == it.deviceId }?.let {
-                                !it.isVerified
-                            } ?: false
-                        }?.sortedByDescending { it.lastSeenTs }
-                                ?.map {
-                                    session.getUser(it.user_id ?: "")?.toMatrixItem() to it
-                                } ?: emptyList()
-                    }
-                            .toObservable()
-                }
-                .execute { async ->
-                    copy(unknownSessions = async)
-                }
-
-        session.rx().liveCrossSigningInfo(session.myUserId)
-                .execute {
-                    copy(canCrossSign = session.cryptoService().crossSigningService().canCrossSign())
-                }
-    }
-
-    override fun handle(action: EmptyAction) {}
-
-    companion object : MvRxViewModelFactory<UnknownDeviceDetectorSharedViewModel, UnknownDevicesState> {
-        override fun create(viewModelContext: ViewModelContext, state: UnknownDevicesState): UnknownDeviceDetectorSharedViewModel? {
-            val session = (viewModelContext.activity as HasScreenInjector).injector().activeSessionHolder().getActiveSession()
-            return UnknownDeviceDetectorSharedViewModel(session, state)
-        }
-    }
-}
diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailFragment.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailFragment.kt
index f58d7be718..f348e0612a 100644
--- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailFragment.kt
+++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailFragment.kt
@@ -39,6 +39,7 @@ import androidx.core.app.ActivityOptionsCompat
 import androidx.core.content.ContextCompat
 import androidx.core.net.toUri
 import androidx.core.text.buildSpannedString
+import androidx.core.text.toSpannable
 import androidx.core.util.Pair
 import androidx.core.view.ViewCompat
 import androidx.core.view.forEach
@@ -110,11 +111,14 @@ import im.vector.riotx.core.utils.PERMISSION_REQUEST_CODE_PICK_ATTACHMENT
 import im.vector.riotx.core.utils.TextUtils
 import im.vector.riotx.core.utils.allGranted
 import im.vector.riotx.core.utils.checkPermissions
+import im.vector.riotx.core.utils.colorizeMatchingText
 import im.vector.riotx.core.utils.copyToClipboard
 import im.vector.riotx.core.utils.createUIHandler
 import im.vector.riotx.core.utils.getColorFromUserId
+import im.vector.riotx.core.utils.isValidUrl
 import im.vector.riotx.core.utils.jsonViewerStyler
 import im.vector.riotx.core.utils.openUrlInExternalBrowser
+import im.vector.riotx.core.utils.saveMedia
 import im.vector.riotx.core.utils.shareMedia
 import im.vector.riotx.core.utils.toast
 import im.vector.riotx.features.attachments.AttachmentTypeSelectorView
@@ -166,6 +170,7 @@ import org.billcarsonfr.jsonviewer.JSonViewerDialog
 import org.commonmark.parser.Parser
 import timber.log.Timber
 import java.io.File
+import java.net.URL
 import java.util.concurrent.TimeUnit
 import javax.inject.Inject
 
@@ -700,7 +705,7 @@ class RoomDetailFragment @Inject constructor(
         val isRoomEncrypted = summary?.isEncrypted ?: false
         if (state.tombstoneEvent == null) {
             composerLayout.visibility = View.VISIBLE
-            composerLayout.setRoomEncrypted(isRoomEncrypted)
+            composerLayout.setRoomEncrypted(isRoomEncrypted, state.asyncRoomSummary.invoke()?.roomEncryptionTrustLevel)
             notificationAreaView.render(NotificationAreaView.State.Hidden)
         } else {
             composerLayout.visibility = View.GONE
@@ -782,7 +787,7 @@ class RoomDetailFragment @Inject constructor(
                 updateComposerText("")
             }
             is RoomDetailViewEvents.SlashCommandResultError    -> {
-                displayCommandError(sendMessageResult.throwable.localizedMessage)
+                displayCommandError(sendMessageResult.throwable.localizedMessage ?: getString(R.string.unexpected_error))
             }
             is RoomDetailViewEvents.SlashCommandNotImplemented -> {
                 displayCommandError(getString(R.string.not_implemented))
@@ -918,7 +923,7 @@ class RoomDetailFragment @Inject constructor(
 
     // TimelineEventController.Callback ************************************************************
 
-    override fun onUrlClicked(url: String): Boolean {
+    override fun onUrlClicked(url: String, title: String): Boolean {
         permalinkHandler
                 .launch(requireActivity(), url, object : NavigationInterceptor {
                     override fun navToRoom(roomId: String?, eventId: String?): Boolean {
@@ -946,8 +951,25 @@ class RoomDetailFragment @Inject constructor(
                 .observeOn(AndroidSchedulers.mainThread())
                 .subscribe { managed ->
                     if (!managed) {
-                        // Open in external browser, in a new Tab
-                        openUrlInExternalBrowser(requireContext(), url)
+                        if (title.isValidUrl() && url.isValidUrl() && URL(title).host != URL(url).host) {
+                            AlertDialog.Builder(requireActivity())
+                                    .setTitle(R.string.external_link_confirmation_title)
+                                    .setMessage(
+                                            getString(R.string.external_link_confirmation_message, title, url)
+                                                    .toSpannable()
+                                                    .colorizeMatchingText(url, colorProvider.getColorFromAttribute(R.attr.riotx_text_primary_body_contrast))
+                                                    .colorizeMatchingText(title, colorProvider.getColorFromAttribute(R.attr.riotx_text_primary_body_contrast))
+                                    )
+                                    .setPositiveButton(R.string._continue) { _, _ ->
+                                        openUrlInExternalBrowser(requireContext(), url)
+                                    }
+                                    .setNegativeButton(R.string.cancel, null)
+                                    .show()
+                                    .withColoredButton(DialogInterface.BUTTON_NEGATIVE)
+                        } else {
+                            // Open in external browser, in a new Tab
+                            openUrlInExternalBrowser(requireContext(), url)
+                        }
                     }
                 }
                 .disposeOnDestroyView()
@@ -956,7 +978,7 @@ class RoomDetailFragment @Inject constructor(
     }
 
     override fun onUrlLongClicked(url: String): Boolean {
-        if (url != getString(R.string.edited_suffix)) {
+        if (url != getString(R.string.edited_suffix) && url.isValidUrl()) {
             // Copy the url to the clipboard
             copyToClipboard(requireContext(), url, true, R.string.link_copied_to_clipboard)
         }
@@ -1153,6 +1175,33 @@ class RoomDetailFragment @Inject constructor(
         )
     }
 
+    private fun onSaveActionClicked(action: EventSharedAction.Save) {
+        session.downloadFile(
+                FileService.DownloadMode.FOR_EXTERNAL_SHARE,
+                action.eventId,
+                action.messageContent.body,
+                action.messageContent.getFileUrl(),
+                action.messageContent.encryptedFileInfo?.toElementToDecrypt(),
+                object : MatrixCallback<File> {
+                    override fun onSuccess(data: File) {
+                        if (isAdded) {
+                            val saved = saveMedia(
+                                    context = requireContext(),
+                                    file = data,
+                                    title = action.messageContent.body,
+                                    mediaMimeType = getMimeTypeFromUri(requireContext(), data.toUri())
+                            )
+                            if (saved) {
+                                Toast.makeText(requireContext(), R.string.media_file_added_to_gallery, Toast.LENGTH_LONG).show()
+                            } else {
+                                Toast.makeText(requireContext(), R.string.error_adding_media_file_to_gallery, Toast.LENGTH_LONG).show()
+                            }
+                        }
+                    }
+                }
+        )
+    }
+
     private fun handleActions(action: EventSharedAction) {
         when (action) {
             is EventSharedAction.OpenUserProfile            -> {
@@ -1176,6 +1225,9 @@ class RoomDetailFragment @Inject constructor(
             is EventSharedAction.Share                      -> {
                 onShareActionClicked(action)
             }
+            is EventSharedAction.Save                       -> {
+                onSaveActionClicked(action)
+            }
             is EventSharedAction.ViewEditHistory            -> {
                 onEditedDecorationClicked(action.messageInformationData)
             }
@@ -1232,7 +1284,7 @@ class RoomDetailFragment @Inject constructor(
                 roomDetailViewModel.handle(RoomDetailAction.IgnoreUser(action.senderId))
             }
             is EventSharedAction.OnUrlClicked               -> {
-                onUrlClicked(action.url)
+                onUrlClicked(action.url, action.title)
             }
             is EventSharedAction.OnUrlLongClicked           -> {
                 onUrlLongClicked(action.url)
diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailViewModel.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailViewModel.kt
index cef172da73..d0dcac6ecc 100644
--- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailViewModel.kt
+++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailViewModel.kt
@@ -447,6 +447,19 @@ class RoomDetailViewModel @AssistedInject constructor(
                             // TODO
                             _viewEvents.post(RoomDetailViewEvents.SlashCommandNotImplemented)
                         }
+                        is ParsedCommand.DiscardSession           -> {
+                            if (room.isEncrypted()) {
+                                session.cryptoService().discardOutboundSession(room.roomId)
+                                _viewEvents.post(RoomDetailViewEvents.SlashCommandHandled())
+                                popDraft()
+                            } else {
+                                _viewEvents.post(RoomDetailViewEvents.SlashCommandHandled())
+                                _viewEvents.post(
+                                        RoomDetailViewEvents
+                                                .ShowMessage(stringProvider.getString(R.string.command_description_discard_session_not_handled))
+                                )
+                            }
+                        }
                     }.exhaustive
                 }
                 is SendMode.EDIT    -> {
diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/composer/TextComposerView.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/composer/TextComposerView.kt
index 593ce1a8f6..9e2a6c0f05 100644
--- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/composer/TextComposerView.kt
+++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/composer/TextComposerView.kt
@@ -27,11 +27,13 @@ import android.widget.TextView
 import androidx.constraintlayout.widget.ConstraintLayout
 import androidx.constraintlayout.widget.ConstraintSet
 import androidx.core.text.toSpannable
+import androidx.core.view.isVisible
 import androidx.transition.AutoTransition
 import androidx.transition.Transition
 import androidx.transition.TransitionManager
 import butterknife.BindView
 import butterknife.ButterKnife
+import im.vector.matrix.android.api.crypto.RoomEncryptionTrustLevel
 import im.vector.riotx.R
 import kotlinx.android.synthetic.main.merge_composer_layout.view.*
 
@@ -64,6 +66,8 @@ class TextComposerView @JvmOverloads constructor(context: Context, attrs: Attrib
     lateinit var composerEditText: ComposerEditText
     @BindView(R.id.composer_avatar_view)
     lateinit var composerAvatarImageView: ImageView
+    @BindView(R.id.composer_shield)
+    lateinit var composerShieldImageView: ImageView
 
     private var currentConstraintSetId: Int = -1
 
@@ -158,12 +162,19 @@ class TextComposerView @JvmOverloads constructor(context: Context, attrs: Attrib
         }
     }
 
-    fun setRoomEncrypted(isEncrypted: Boolean) {
-        composerEditText.setHint(
-                if (isEncrypted) {
-                    R.string.room_message_placeholder_encrypted
-                } else {
-                    R.string.room_message_placeholder_not_encrypted
-                })
+    fun setRoomEncrypted(isEncrypted: Boolean, roomEncryptionTrustLevel: RoomEncryptionTrustLevel?) {
+        if (isEncrypted) {
+            composerEditText.setHint(R.string.room_message_placeholder)
+            composerShieldImageView.isVisible = true
+            val shieldRes = when (roomEncryptionTrustLevel) {
+                RoomEncryptionTrustLevel.Trusted -> R.drawable.ic_shield_trusted
+                RoomEncryptionTrustLevel.Warning -> R.drawable.ic_shield_warning
+                else                             -> R.drawable.ic_shield_black
+            }
+            composerShieldImageView.setImageResource(shieldRes)
+        } else {
+            composerEditText.setHint(R.string.room_message_placeholder)
+            composerShieldImageView.isVisible = false
+        }
     }
 }
diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/TimelineEventController.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/TimelineEventController.kt
index 48e92ca438..addbfab43c 100644
--- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/TimelineEventController.kt
+++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/TimelineEventController.kt
@@ -104,7 +104,7 @@ class TimelineEventController @Inject constructor(private val dateFormatter: Vec
     }
 
     interface UrlClickCallback {
-        fun onUrlClicked(url: String): Boolean
+        fun onUrlClicked(url: String, title: String): Boolean
         fun onUrlLongClicked(url: String): Boolean
     }
 
diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/EventSharedAction.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/EventSharedAction.kt
index e38c055d52..b141e9a8cd 100644
--- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/EventSharedAction.kt
+++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/EventSharedAction.kt
@@ -50,6 +50,9 @@ sealed class EventSharedAction(@StringRes val titleRes: Int,
     data class Share(val eventId: String, val messageContent: MessageWithAttachmentContent) :
             EventSharedAction(R.string.share, R.drawable.ic_share)
 
+    data class Save(val eventId: String, val messageContent: MessageWithAttachmentContent) :
+            EventSharedAction(R.string.save, R.drawable.ic_material_save)
+
     data class Resend(val eventId: String) :
             EventSharedAction(R.string.global_retry, R.drawable.ic_refresh_cw)
 
@@ -96,7 +99,7 @@ sealed class EventSharedAction(@StringRes val titleRes: Int,
             EventSharedAction(R.string.message_view_edit_history, R.drawable.ic_view_edit_history)
 
     // An url in the event preview has been clicked
-    data class OnUrlClicked(val url: String) :
+    data class OnUrlClicked(val url: String, val title: String) :
             EventSharedAction(0, 0)
 
     // An url in the event preview has been long clicked
diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageActionsBottomSheet.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageActionsBottomSheet.kt
index 1336c61b68..eeb090092c 100644
--- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageActionsBottomSheet.kt
+++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageActionsBottomSheet.kt
@@ -63,8 +63,8 @@ class MessageActionsBottomSheet : VectorBaseBottomSheetDialogFragment(), Message
         super.onDestroyView()
     }
 
-    override fun onUrlClicked(url: String): Boolean {
-        sharedActionViewModel.post(EventSharedAction.OnUrlClicked(url))
+    override fun onUrlClicked(url: String, title: String): Boolean {
+        sharedActionViewModel.post(EventSharedAction.OnUrlClicked(url, title))
         // Always consume
         return true
     }
diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageActionsEpoxyController.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageActionsEpoxyController.kt
index d2cdf37eab..e77d9ec73f 100644
--- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageActionsEpoxyController.kt
+++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageActionsEpoxyController.kt
@@ -29,6 +29,7 @@ import im.vector.riotx.core.epoxy.dividerItem
 import im.vector.riotx.core.resources.StringProvider
 import im.vector.riotx.features.home.AvatarRenderer
 import im.vector.riotx.features.home.room.detail.timeline.TimelineEventController
+import im.vector.riotx.features.home.room.detail.timeline.item.E2EDecoration
 import im.vector.riotx.features.home.room.detail.timeline.tools.createLinkMovementMethod
 import im.vector.riotx.features.home.room.detail.timeline.tools.linkify
 import javax.inject.Inject
@@ -72,6 +73,29 @@ class MessageActionsEpoxyController @Inject constructor(
             }
         }
 
+        when (state.informationData.e2eDecoration) {
+            E2EDecoration.WARN_IN_CLEAR        -> {
+                bottomSheetSendStateItem {
+                    id("e2e_clear")
+                    showProgress(false)
+                    text(stringProvider.getString(R.string.unencrypted))
+                    drawableStart(R.drawable.ic_shield_warning_small)
+                }
+            }
+            E2EDecoration.WARN_SENT_BY_UNVERIFIED,
+            E2EDecoration.WARN_SENT_BY_UNKNOWN -> {
+                bottomSheetSendStateItem {
+                    id("e2e_unverified")
+                    showProgress(false)
+                    text(stringProvider.getString(R.string.encrypted_unverified))
+                    drawableStart(R.drawable.ic_shield_warning_small)
+                }
+            }
+            else                               -> {
+                // nothing
+            }
+        }
+
         // Quick reactions
         if (state.canReact() && state.quickStates is Success) {
             // Separator
diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageActionsViewModel.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageActionsViewModel.kt
index 5212e1469d..38db5440d6 100644
--- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageActionsViewModel.kt
+++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageActionsViewModel.kt
@@ -30,11 +30,11 @@ import im.vector.matrix.android.api.session.events.model.EventType
 import im.vector.matrix.android.api.session.events.model.isTextMessage
 import im.vector.matrix.android.api.session.events.model.toModel
 import im.vector.matrix.android.api.session.room.model.message.MessageContent
-import im.vector.matrix.android.api.session.room.model.message.MessageWithAttachmentContent
 import im.vector.matrix.android.api.session.room.model.message.MessageFormat
 import im.vector.matrix.android.api.session.room.model.message.MessageTextContent
 import im.vector.matrix.android.api.session.room.model.message.MessageType
 import im.vector.matrix.android.api.session.room.model.message.MessageVerificationRequestContent
+import im.vector.matrix.android.api.session.room.model.message.MessageWithAttachmentContent
 import im.vector.matrix.android.api.session.room.send.SendState
 import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
 import im.vector.matrix.android.api.session.room.timeline.getLastMessageContent
@@ -290,6 +290,10 @@ class MessageActionsViewModel @AssistedInject constructor(@Assisted
                         add(EventSharedAction.Share(timelineEvent.eventId, messageContent))
                     }
 
+                    if (canSave(msgType) && messageContent is MessageWithAttachmentContent) {
+                        add(EventSharedAction.Save(timelineEvent.eventId, messageContent))
+                    }
+
                     if (timelineEvent.root.sendState == SendState.SENT) {
                         // TODO Can be redacted
 
@@ -413,4 +417,14 @@ class MessageActionsViewModel @AssistedInject constructor(@Assisted
             else                     -> false
         }
     }
+
+    private fun canSave(msgType: String?): Boolean {
+        return when (msgType) {
+            MessageType.MSGTYPE_IMAGE,
+            MessageType.MSGTYPE_AUDIO,
+            MessageType.MSGTYPE_VIDEO,
+            MessageType.MSGTYPE_FILE -> true
+            else                     -> false
+        }
+    }
 }
diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/factory/MergedHeaderItemFactory.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/factory/MergedHeaderItemFactory.kt
index 377fc5ab4a..03c273800a 100644
--- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/factory/MergedHeaderItemFactory.kt
+++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/factory/MergedHeaderItemFactory.kt
@@ -18,6 +18,7 @@ package im.vector.riotx.features.home.room.detail.timeline.factory
 
 import im.vector.matrix.android.api.session.events.model.EventType
 import im.vector.matrix.android.api.session.events.model.toModel
+import im.vector.matrix.android.api.session.room.model.create.RoomCreateContent
 import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
 import im.vector.matrix.android.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM
 import im.vector.matrix.android.internal.crypto.model.event.EncryptionEventContent
@@ -43,6 +44,9 @@ class MergedHeaderItemFactory @Inject constructor(private val sessionHolder: Act
     private val collapsedEventIds = linkedSetOf<Long>()
     private val mergeItemCollapseStates = HashMap<Long, Boolean>()
 
+    /**
+     * Note: nextEvent is an older event than event
+     */
     fun create(event: TimelineEvent,
                nextEvent: TimelineEvent?,
                items: List<TimelineEvent>,
@@ -52,7 +56,8 @@ class MergedHeaderItemFactory @Inject constructor(private val sessionHolder: Act
                callback: TimelineEventController.Callback?,
                requestModelBuild: () -> Unit)
             : BasedMergedItem<*>? {
-        return if (nextEvent?.root?.getClearType() == EventType.STATE_ROOM_CREATE && event.isRoomConfiguration()) {
+        return if (nextEvent?.root?.getClearType() == EventType.STATE_ROOM_CREATE
+                && event.isRoomConfiguration(nextEvent.root.getClearContent()?.toModel<RoomCreateContent>()?.creator)) {
             // It's the first item before room.create
             // Collapse all room configuration events
             buildRoomCreationMergedSummary(currentPosition, items, event, eventIdToHighlight, requestModelBuild, callback)
@@ -127,7 +132,7 @@ class MergedHeaderItemFactory @Inject constructor(private val sessionHolder: Act
         val mergedEvents = ArrayList<TimelineEvent>().also { it.add(event) }
         var hasEncryption = false
         var encryptionAlgorithm: String? = null
-        while (prevEvent != null && prevEvent.isRoomConfiguration()) {
+        while (prevEvent != null && prevEvent.isRoomConfiguration(null)) {
             if (prevEvent.root.getClearType() == EventType.STATE_ROOM_ENCRYPTION) {
                 hasEncryption = true
                 encryptionAlgorithm = prevEvent.root.getClearContent()?.toModel<EncryptionEventContent>()?.algorithm
diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/factory/MessageItemFactory.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/factory/MessageItemFactory.kt
index 2b221b9fef..ffb71a38c5 100644
--- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/factory/MessageItemFactory.kt
+++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/factory/MessageItemFactory.kt
@@ -279,6 +279,7 @@ class MessageItemFactory @Inject constructor(
                                       attributes: AbsMessageItem.Attributes): MessageImageVideoItem? {
         val (maxWidth, maxHeight) = timelineMediaSizeProvider.getMaxSize()
         val data = ImageContentRenderer.Data(
+                eventId = informationData.eventId,
                 filename = messageContent.body,
                 url = messageContent.getFileUrl(),
                 elementToDecrypt = messageContent.encryptedFileInfo?.toElementToDecrypt(),
@@ -314,6 +315,7 @@ class MessageItemFactory @Inject constructor(
                                       attributes: AbsMessageItem.Attributes): MessageImageVideoItem? {
         val (maxWidth, maxHeight) = timelineMediaSizeProvider.getMaxSize()
         val thumbnailData = ImageContentRenderer.Data(
+                eventId = informationData.eventId,
                 filename = messageContent.body,
                 url = messageContent.videoInfo?.thumbnailFile?.url
                         ?: messageContent.videoInfo?.thumbnailUrl,
@@ -440,11 +442,11 @@ class MessageItemFactory @Inject constructor(
                 Spanned.SPAN_INCLUSIVE_EXCLUSIVE)
 
         spannable.setSpan(object : ClickableSpan() {
-            override fun onClick(widget: View?) {
+            override fun onClick(widget: View) {
                 callback?.onEditedDecorationClicked(informationData)
             }
 
-            override fun updateDrawState(ds: TextPaint?) {
+            override fun updateDrawState(ds: TextPaint) {
                 // nop
             }
         },
diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/helper/MessageInformationDataFactory.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/helper/MessageInformationDataFactory.kt
index 0758e34495..695da73f89 100644
--- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/helper/MessageInformationDataFactory.kt
+++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/helper/MessageInformationDataFactory.kt
@@ -18,19 +18,24 @@
 
 package im.vector.riotx.features.home.room.detail.timeline.helper
 
+import im.vector.matrix.android.api.extensions.orFalse
 import im.vector.matrix.android.api.session.Session
 import im.vector.matrix.android.api.session.events.model.EventType
 import im.vector.matrix.android.api.session.events.model.toModel
+import im.vector.matrix.android.api.session.room.Room
 import im.vector.matrix.android.api.session.room.model.ReferencesAggregatedContent
 import im.vector.matrix.android.api.session.room.model.message.MessageVerificationRequestContent
+import im.vector.matrix.android.api.session.room.send.SendState
 import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
 import im.vector.matrix.android.api.session.room.timeline.getLastMessageContent
 import im.vector.matrix.android.api.session.room.timeline.hasBeenEdited
+import im.vector.matrix.android.internal.crypto.model.event.EncryptedEventContent
 import im.vector.matrix.android.internal.session.room.VerificationState
 import im.vector.riotx.core.date.VectorDateFormatter
 import im.vector.riotx.core.extensions.localDateTime
 import im.vector.riotx.core.resources.ColorProvider
 import im.vector.riotx.core.utils.getColorFromUserId
+import im.vector.riotx.features.home.room.detail.timeline.item.E2EDecoration
 import im.vector.riotx.features.home.room.detail.timeline.item.MessageInformationData
 import im.vector.riotx.features.home.room.detail.timeline.item.PollResponseData
 import im.vector.riotx.features.home.room.detail.timeline.item.ReactionInfoData
@@ -72,6 +77,8 @@ class MessageInformationDataFactory @Inject constructor(private val session: Ses
             textColor = colorProvider.getColor(getColorFromUserId(event.root.senderId))
         }
 
+        val room = event.root.roomId?.let { session.getRoom(it) }
+        val e2eDecoration = getE2EDecoration(room, event)
         return MessageInformationData(
                 eventId = eventId,
                 senderId = event.root.senderId ?: "",
@@ -111,10 +118,61 @@ class MessageInformationDataFactory @Inject constructor(private val session: Ses
                             ?: VerificationState.REQUEST
                     ReferencesInfoData(verificationState)
                 },
-                sentByMe = event.root.senderId == session.myUserId
+                sentByMe = event.root.senderId == session.myUserId,
+                e2eDecoration = e2eDecoration
         )
     }
 
+    private fun getE2EDecoration(room: Room?, event: TimelineEvent): E2EDecoration {
+        return if (
+                event.root.sendState == SendState.SYNCED
+                && room?.isEncrypted() == true
+                // is user verified
+                && session.cryptoService().crossSigningService().getUserCrossSigningKeys(event.root.senderId ?: "")?.isTrusted() == true) {
+            val ts = room.roomSummary()?.encryptionEventTs ?: 0
+            val eventTs = event.root.originServerTs ?: 0
+            if (event.isEncrypted()) {
+                // Do not decorate failed to decrypt, or redaction (we lost sender device info)
+                if (event.root.getClearType() == EventType.ENCRYPTED || event.root.isRedacted()) {
+                    E2EDecoration.NONE
+                } else {
+                    val sendingDevice = event.root.content
+                            .toModel<EncryptedEventContent>()
+                            ?.deviceId
+                            ?.let { deviceId ->
+                                session.cryptoService().getDeviceInfo(event.root.senderId ?: "", deviceId)
+                            }
+                    when {
+                        sendingDevice == null                            -> {
+                            // For now do not decorate this with warning
+                            // maybe it's a deleted session
+                            E2EDecoration.NONE
+                        }
+                        sendingDevice.trustLevel == null                 -> {
+                            E2EDecoration.WARN_SENT_BY_UNKNOWN
+                        }
+                        sendingDevice.trustLevel?.isVerified().orFalse() -> {
+                            E2EDecoration.NONE
+                        }
+                        else                                             -> {
+                            E2EDecoration.WARN_SENT_BY_UNVERIFIED
+                        }
+                    }
+                }
+            } else {
+                if (EventType.isStateEvent(event.root.type)) {
+                    // Do not warn for state event, they are always in clear
+                    E2EDecoration.NONE
+                } else {
+                    // If event is in clear after the room enabled encryption we should warn
+                    if (eventTs > ts) E2EDecoration.WARN_IN_CLEAR else E2EDecoration.NONE
+                }
+            }
+        } else {
+            E2EDecoration.NONE
+        }
+    }
+
     /**
      * Tiles type message never show the sender information (like verification request), so we should repeat it for next message
      * even if same sender
diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/helper/TimelineDisplayableEvents.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/helper/TimelineDisplayableEvents.kt
index 1ea3cd64ac..f1106d276e 100644
--- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/helper/TimelineDisplayableEvents.kt
+++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/helper/TimelineDisplayableEvents.kt
@@ -50,14 +50,23 @@ fun TimelineEvent.canBeMerged(): Boolean {
     return root.getClearType() == EventType.STATE_ROOM_MEMBER
 }
 
-fun TimelineEvent.isRoomConfiguration(): Boolean {
+fun TimelineEvent.isRoomConfiguration(roomCreatorUserId: String?): Boolean {
     return when (root.getClearType()) {
         EventType.STATE_ROOM_GUEST_ACCESS,
         EventType.STATE_ROOM_HISTORY_VISIBILITY,
         EventType.STATE_ROOM_JOIN_RULES,
-        EventType.STATE_ROOM_MEMBER,
         EventType.STATE_ROOM_NAME,
+        EventType.STATE_ROOM_TOPIC,
+        EventType.STATE_ROOM_AVATAR,
+        EventType.STATE_ROOM_ALIASES,
+        EventType.STATE_ROOM_CANONICAL_ALIAS,
+        EventType.STATE_ROOM_POWER_LEVELS,
         EventType.STATE_ROOM_ENCRYPTION -> true
+        EventType.STATE_ROOM_MEMBER     -> {
+            // Keep only room member events regarding the room creator (when he joined the room),
+            // but exclude events where the room creator invite others, or where others join
+            roomCreatorUserId != null && root.stateKey == roomCreatorUserId
+        }
         else                            -> false
     }
 }
diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/AbsBaseMessageItem.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/AbsBaseMessageItem.kt
index 149b5e74ad..e62de05518 100644
--- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/AbsBaseMessageItem.kt
+++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/AbsBaseMessageItem.kt
@@ -92,6 +92,18 @@ abstract class AbsBaseMessageItem<H : AbsBaseMessageItem.Holder> : BaseEventItem
             holder.reactionsContainer.setOnLongClickListener(baseAttributes.itemLongClickListener)
         }
 
+        when (baseAttributes.informationData.e2eDecoration) {
+            E2EDecoration.NONE                 -> {
+                holder.e2EDecorationView.isVisible = false
+            }
+            E2EDecoration.WARN_IN_CLEAR,
+            E2EDecoration.WARN_SENT_BY_UNVERIFIED,
+            E2EDecoration.WARN_SENT_BY_UNKNOWN -> {
+                holder.e2EDecorationView.setImageResource(R.drawable.ic_shield_warning)
+                holder.e2EDecorationView.isVisible = true
+            }
+        }
+
         holder.view.setOnClickListener(baseAttributes.itemClickListener)
         holder.view.setOnLongClickListener(baseAttributes.itemLongClickListener)
     }
@@ -110,6 +122,7 @@ abstract class AbsBaseMessageItem<H : AbsBaseMessageItem.Holder> : BaseEventItem
 
     abstract class Holder(@IdRes stubId: Int) : BaseEventItem.BaseHolder(stubId) {
         val reactionsContainer by bind<ViewGroup>(R.id.reactionsContainer)
+        val e2EDecorationView by bind<ImageView>(R.id.messageE2EDecoration)
     }
 
     /**
diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/MergedRoomCreationItem.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/MergedRoomCreationItem.kt
index 81050194a8..3985b3856b 100644
--- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/MergedRoomCreationItem.kt
+++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/MergedRoomCreationItem.kt
@@ -43,7 +43,8 @@ abstract class MergedRoomCreationItem : BasedMergedItem<MergedRoomCreationItem.H
         super.bind(holder)
 
         if (attributes.isCollapsed) {
-            val data = distinctMergeData.firstOrNull()
+            // Take the oldest data
+            val data = distinctMergeData.lastOrNull()
 
             val summary = holder.expandView.resources.getString(R.string.room_created_summary_item,
                     data?.memberName ?: data?.userId ?: "")
diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/MessageInformationData.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/MessageInformationData.kt
index 8d4ae81201..088577d03a 100644
--- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/MessageInformationData.kt
+++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/MessageInformationData.kt
@@ -40,7 +40,8 @@ data class MessageInformationData(
         val hasPendingEdits: Boolean = false,
         val readReceipts: List<ReadReceiptData> = emptyList(),
         val referencesInfoData: ReferencesInfoData? = null,
-        val sentByMe : Boolean
+        val sentByMe : Boolean,
+        val e2eDecoration: E2EDecoration = E2EDecoration.NONE
 ) : Parcelable {
 
     val matrixItem: MatrixItem
@@ -75,4 +76,11 @@ data class PollResponseData(
         val isClosed: Boolean = false
 ) : Parcelable
 
+enum class E2EDecoration {
+    NONE,
+    WARN_IN_CLEAR,
+    WARN_SENT_BY_UNVERIFIED,
+    WARN_SENT_BY_UNKNOWN
+}
+
 fun ReadReceiptData.toMatrixItem() = MatrixItem.UserItem(userId, displayName, avatarUrl)
diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/NoticeItem.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/NoticeItem.kt
index ec98ea10ed..a4d5d273e7 100644
--- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/NoticeItem.kt
+++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/NoticeItem.kt
@@ -19,6 +19,7 @@ package im.vector.riotx.features.home.room.detail.timeline.item
 import android.view.View
 import android.widget.ImageView
 import android.widget.TextView
+import androidx.core.view.isVisible
 import com.airbnb.epoxy.EpoxyAttribute
 import com.airbnb.epoxy.EpoxyModelClass
 import im.vector.riotx.R
@@ -45,6 +46,18 @@ abstract class NoticeItem : BaseEventItem<NoticeItem.Holder>() {
         holder.view.setOnLongClickListener(attributes.itemLongClickListener)
         holder.readReceiptsView.render(attributes.informationData.readReceipts, attributes.avatarRenderer, _readReceiptsClickListener)
         holder.avatarImageView.onClick(attributes.avatarClickListener)
+
+        when (attributes.informationData.e2eDecoration) {
+            E2EDecoration.NONE                 -> {
+                holder.e2EDecorationView.isVisible = false
+            }
+            E2EDecoration.WARN_IN_CLEAR,
+            E2EDecoration.WARN_SENT_BY_UNVERIFIED,
+            E2EDecoration.WARN_SENT_BY_UNKNOWN -> {
+                holder.e2EDecorationView.setImageResource(R.drawable.ic_shield_warning)
+                holder.e2EDecorationView.isVisible = true
+            }
+        }
     }
 
     override fun getEventIds(): List<String> {
@@ -56,6 +69,7 @@ abstract class NoticeItem : BaseEventItem<NoticeItem.Holder>() {
     class Holder : BaseHolder(STUB_ID) {
         val avatarImageView by bind<ImageView>(R.id.itemNoticeAvatarView)
         val noticeTextView by bind<TextView>(R.id.itemNoticeTextView)
+        val e2EDecorationView by bind<ImageView>(R.id.messageE2EDecoration)
     }
 
     data class Attributes(
diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/VerificationRequestItem.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/VerificationRequestItem.kt
index ef43605b04..12ef5c3577 100644
--- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/VerificationRequestItem.kt
+++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/VerificationRequestItem.kt
@@ -81,7 +81,8 @@ abstract class VerificationRequestItem : AbsBaseMessageItem<VerificationRequestI
             }
             VerificationState.CANCELED_BY_OTHER -> {
                 holder.buttonBar.isVisible = false
-                holder.statusTextView.text = holder.view.context.getString(R.string.verification_request_other_cancelled, attributes.informationData.memberName)
+                holder.statusTextView.text = holder.view.context
+                        .getString(R.string.verification_request_other_cancelled, attributes.informationData.memberName)
                 holder.statusTextView.isVisible = true
             }
             VerificationState.CANCELED_BY_ME    -> {
diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/tools/EventRenderingTools.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/tools/EventRenderingTools.kt
index 4e9959eda6..d3d7260206 100644
--- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/tools/EventRenderingTools.kt
+++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/tools/EventRenderingTools.kt
@@ -17,19 +17,21 @@
 package im.vector.riotx.features.home.room.detail.timeline.tools
 
 import android.text.SpannableStringBuilder
+import android.text.style.ClickableSpan
 import android.view.MotionEvent
+import android.widget.TextView
 import androidx.core.text.toSpannable
 import im.vector.matrix.android.api.permalinks.MatrixLinkify
 import im.vector.matrix.android.api.permalinks.MatrixPermalinkSpan
 import im.vector.riotx.core.linkify.VectorLinkify
-import im.vector.riotx.core.utils.isValidUrl
+import im.vector.riotx.core.utils.EvenBetterLinkMovementMethod
 import im.vector.riotx.features.home.room.detail.timeline.TimelineEventController
 import im.vector.riotx.features.html.PillImageSpan
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.withContext
-import me.saket.bettermovementmethod.BetterLinkMovementMethod
+import im.vector.riotx.core.utils.isValidUrl
 
 fun CharSequence.findPillsAndProcess(scope: CoroutineScope, processBlock: (PillImageSpan) -> Unit) {
     scope.launch(Dispatchers.Main) {
@@ -42,10 +44,11 @@ fun CharSequence.findPillsAndProcess(scope: CoroutineScope, processBlock: (PillI
 }
 
 fun CharSequence.linkify(callback: TimelineEventController.UrlClickCallback?): CharSequence {
+    val text = this.toString()
     val spannable = SpannableStringBuilder(this)
     MatrixLinkify.addLinks(spannable, object : MatrixPermalinkSpan.Callback {
         override fun onUrlClicked(url: String) {
-            callback?.onUrlClicked(url)
+            callback?.onUrlClicked(url, text)
         }
     })
     VectorLinkify.addLinks(spannable, true)
@@ -54,17 +57,18 @@ fun CharSequence.linkify(callback: TimelineEventController.UrlClickCallback?): C
 
 // Better link movement methods fixes the issue when
 // long pressing to open the context menu on a TextView also triggers an autoLink click.
-fun createLinkMovementMethod(urlClickCallback: TimelineEventController.UrlClickCallback?): BetterLinkMovementMethod {
-    return BetterLinkMovementMethod.newInstance()
+fun createLinkMovementMethod(urlClickCallback: TimelineEventController.UrlClickCallback?): EvenBetterLinkMovementMethod {
+    return EvenBetterLinkMovementMethod(object : EvenBetterLinkMovementMethod.OnLinkClickListener {
+        override fun onLinkClicked(textView: TextView, span: ClickableSpan, url: String, actualText: String): Boolean {
+            // Always return false if the url is not valid, so the EvenBetterLinkMovementMethod can fallback to default click listener.
+            return url.isValidUrl() && urlClickCallback?.onUrlClicked(url, actualText) == true
+        }
+    })
             .apply {
-                setOnLinkClickListener { _, url ->
-                    // Return false to let android manage the click on the link, or true if the link is handled by the application
-                    url.isValidUrl() && urlClickCallback?.onUrlClicked(url) == true
-                }
-
                 // We need also to fix the case when long click on link will trigger long click on cell
                 setOnLinkLongClickListener { tv, url ->
                     // Long clicks are handled by parent, return true to block android to do something with url
+                    // Always return false if the url is not valid, so the EvenBetterLinkMovementMethod can fallback to default click listener.
                     if (url.isValidUrl() && urlClickCallback?.onUrlLongClicked(url) == true) {
                         tv.dispatchTouchEvent(MotionEvent.obtain(0, 0, MotionEvent.ACTION_CANCEL, 0f, 0f, 0))
                         true
diff --git a/vector/src/main/java/im/vector/riotx/features/login/LoginFragment.kt b/vector/src/main/java/im/vector/riotx/features/login/LoginFragment.kt
index 01cc19fa5b..8b89aeda2a 100644
--- a/vector/src/main/java/im/vector/riotx/features/login/LoginFragment.kt
+++ b/vector/src/main/java/im/vector/riotx/features/login/LoginFragment.kt
@@ -19,6 +19,7 @@ package im.vector.riotx.features.login
 import android.os.Build
 import android.os.Bundle
 import android.view.View
+import android.view.inputmethod.EditorInfo
 import androidx.autofill.HintConstants
 import androidx.core.view.isVisible
 import butterknife.OnClick
@@ -28,6 +29,7 @@ import com.airbnb.mvrx.Success
 import com.jakewharton.rxbinding3.widget.textChanges
 import im.vector.matrix.android.api.failure.Failure
 import im.vector.matrix.android.api.failure.MatrixError
+import im.vector.matrix.android.api.failure.isInvalidPassword
 import im.vector.riotx.R
 import im.vector.riotx.core.extensions.hideKeyboard
 import im.vector.riotx.core.extensions.showPassword
@@ -39,7 +41,8 @@ import kotlinx.android.synthetic.main.fragment_login.*
 import javax.inject.Inject
 
 /**
- * In this screen, in signin mode:
+ * In this screen:
+ * In signin mode:
  * - the user is asked for login (or email) and password to sign in to a homeserver.
  * - He also can reset his password
  * In signup mode:
@@ -48,6 +51,7 @@ import javax.inject.Inject
 class LoginFragment @Inject constructor() : AbstractLoginFragment() {
 
     private var passwordShown = false
+    private var isSignupMode = false
 
     override fun getLayoutResId() = R.layout.fragment_login
 
@@ -56,6 +60,14 @@ class LoginFragment @Inject constructor() : AbstractLoginFragment() {
 
         setupSubmitButton()
         setupPasswordReveal()
+
+        passwordField.setOnEditorActionListener { _, actionId, _ ->
+            if (actionId == EditorInfo.IME_ACTION_DONE) {
+                submit()
+                return@setOnEditorActionListener true
+            }
+            return@setOnEditorActionListener false
+        }
     }
 
     private fun setupAutoFill(state: LoginViewState) {
@@ -81,7 +93,20 @@ class LoginFragment @Inject constructor() : AbstractLoginFragment() {
         val login = loginField.text.toString()
         val password = passwordField.text.toString()
 
-        loginViewModel.handle(LoginAction.LoginOrRegister(login, password, getString(R.string.login_mobile_device)))
+        // This can be called by the IME action, so deal with empty cases
+        var error = 0
+        if (login.isEmpty()) {
+            loginFieldTil.error = getString(if (isSignupMode) R.string.error_empty_field_choose_user_name else R.string.error_empty_field_enter_user_name)
+            error++
+        }
+        if (password.isEmpty()) {
+            passwordFieldTil.error = getString(if (isSignupMode) R.string.error_empty_field_choose_password else R.string.error_empty_field_your_password)
+            error++
+        }
+
+        if (error == 0) {
+            loginViewModel.handle(LoginAction.LoginOrRegister(login, password, getString(R.string.login_mobile_device_riotx)))
+        }
     }
 
     private fun cleanupUi() {
@@ -189,6 +214,8 @@ class LoginFragment @Inject constructor() : AbstractLoginFragment() {
     }
 
     override fun updateWithState(state: LoginViewState) {
+        isSignupMode = state.signMode == SignMode.SignUp
+
         setupUi(state)
         setupAutoFill(state)
         setupButtons(state)
@@ -209,10 +236,7 @@ class LoginFragment @Inject constructor() : AbstractLoginFragment() {
                 } else {
                     // Trick to display the error without text.
                     loginFieldTil.error = " "
-                    if (error is Failure.ServerError
-                            && error.error.code == MatrixError.M_FORBIDDEN
-                            && error.error.message == "Invalid password"
-                            && spaceInPassword()) {
+                    if (error.isInvalidPassword() && spaceInPassword()) {
                         passwordFieldTil.error = getString(R.string.auth_invalid_login_param_space_in_password)
                     } else {
                         passwordFieldTil.error = errorFormatter.toHumanReadable(error)
diff --git a/vector/src/main/java/im/vector/riotx/features/login/LoginWebFragment.kt b/vector/src/main/java/im/vector/riotx/features/login/LoginWebFragment.kt
index 08d92760b2..f9b0b98f29 100644
--- a/vector/src/main/java/im/vector/riotx/features/login/LoginWebFragment.kt
+++ b/vector/src/main/java/im/vector/riotx/features/login/LoginWebFragment.kt
@@ -31,9 +31,14 @@ import android.webkit.WebView
 import android.webkit.WebViewClient
 import androidx.appcompat.app.AlertDialog
 import com.airbnb.mvrx.activityViewModel
+import im.vector.matrix.android.api.auth.LOGIN_FALLBACK_PATH
+import im.vector.matrix.android.api.auth.REGISTER_FALLBACK_PATH
+import im.vector.matrix.android.api.auth.SSO_FALLBACK_PATH
+import im.vector.matrix.android.api.auth.SSO_REDIRECT_URL_PARAM
 import im.vector.matrix.android.api.auth.data.Credentials
 import im.vector.matrix.android.internal.di.MoshiProvider
 import im.vector.riotx.R
+import im.vector.riotx.core.extensions.appendParamToUrl
 import im.vector.riotx.core.utils.AssetReader
 import im.vector.riotx.features.signout.soft.SoftLogoutAction
 import im.vector.riotx.features.signout.soft.SoftLogoutViewModel
@@ -123,14 +128,24 @@ class LoginWebFragment @Inject constructor(
         val url = buildString {
             append(state.homeServerUrl?.trim { it == '/' })
             if (state.signMode == SignMode.SignIn) {
-                append("/_matrix/static/client/login/")
+                if (state.loginMode == LoginMode.Sso) {
+                    append(SSO_FALLBACK_PATH)
+                    // We do not want to deal with the result, so let the fallback login page to handle it for us
+                    appendParamToUrl(SSO_REDIRECT_URL_PARAM,
+                            buildString {
+                                append(state.homeServerUrl?.trim { it == '/' })
+                                append(LOGIN_FALLBACK_PATH)
+                            })
+                } else {
+                    append(LOGIN_FALLBACK_PATH)
+                }
                 state.deviceId?.takeIf { it.isNotBlank() }?.let {
                     // But https://github.com/matrix-org/synapse/issues/5755
-                    append("?device_id=$it")
+                    appendParamToUrl("device_id", it)
                 }
             } else {
                 // MODE_REGISTER
-                append("/_matrix/static/client/register/")
+                append(REGISTER_FALLBACK_PATH)
             }
         }
 
diff --git a/vector/src/main/java/im/vector/riotx/features/media/ImageContentRenderer.kt b/vector/src/main/java/im/vector/riotx/features/media/ImageContentRenderer.kt
index 737549d5b8..becb714bf4 100644
--- a/vector/src/main/java/im/vector/riotx/features/media/ImageContentRenderer.kt
+++ b/vector/src/main/java/im/vector/riotx/features/media/ImageContentRenderer.kt
@@ -46,6 +46,7 @@ class ImageContentRenderer @Inject constructor(private val activeSessionHolder:
 
     @Parcelize
     data class Data(
+            val eventId: String,
             val filename: String,
             val url: String?,
             val elementToDecrypt: ElementToDecrypt?,
diff --git a/vector/src/main/java/im/vector/riotx/features/media/ImageMediaViewerActivity.kt b/vector/src/main/java/im/vector/riotx/features/media/ImageMediaViewerActivity.kt
index d9da08254f..ca6510a897 100644
--- a/vector/src/main/java/im/vector/riotx/features/media/ImageMediaViewerActivity.kt
+++ b/vector/src/main/java/im/vector/riotx/features/media/ImageMediaViewerActivity.kt
@@ -21,10 +21,12 @@ import android.content.Intent
 import android.graphics.drawable.Drawable
 import android.os.Build
 import android.os.Bundle
+import android.view.MenuItem
 import android.view.View
 import android.view.ViewTreeObserver
 import androidx.annotation.RequiresApi
 import androidx.appcompat.widget.Toolbar
+import androidx.core.net.toUri
 import androidx.core.transition.addListener
 import androidx.core.view.ViewCompat
 import androidx.core.view.isInvisible
@@ -36,15 +38,23 @@ import com.bumptech.glide.request.RequestListener
 import com.bumptech.glide.request.target.Target
 import com.github.piasy.biv.indicator.progresspie.ProgressPieIndicator
 import com.github.piasy.biv.view.GlideImageViewFactory
+import im.vector.matrix.android.api.MatrixCallback
+import im.vector.matrix.android.api.session.Session
+import im.vector.matrix.android.api.session.file.FileService
+import im.vector.riotx.R
 import im.vector.riotx.core.di.ScreenComponent
 import im.vector.riotx.core.glide.GlideApp
+import im.vector.riotx.core.intent.getMimeTypeFromUri
 import im.vector.riotx.core.platform.VectorBaseActivity
+import im.vector.riotx.core.utils.shareMedia
 import kotlinx.android.synthetic.main.activity_image_media_viewer.*
 import timber.log.Timber
+import java.io.File
 import javax.inject.Inject
 
 class ImageMediaViewerActivity : VectorBaseActivity() {
 
+    @Inject lateinit var session: Session
     @Inject lateinit var imageContentRenderer: ImageContentRenderer
 
     private lateinit var mediaData: ImageContentRenderer.Data
@@ -56,10 +66,17 @@ class ImageMediaViewerActivity : VectorBaseActivity() {
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
         setContentView(im.vector.riotx.R.layout.activity_image_media_viewer)
-        mediaData = intent.getParcelableExtra(EXTRA_MEDIA_DATA)
+
+        if (intent.hasExtra(EXTRA_MEDIA_DATA)) {
+            mediaData = intent.getParcelableExtra(EXTRA_MEDIA_DATA)!!
+        } else {
+            finish()
+        }
+
         intent.extras?.getString(EXTRA_SHARED_TRANSITION_NAME)?.let {
             ViewCompat.setTransitionName(imageTransitionView, it)
         }
+
         if (mediaData.url.isNullOrEmpty()) {
             supportFinishAfterTransition()
             return
@@ -103,6 +120,33 @@ class ImageMediaViewerActivity : VectorBaseActivity() {
         }
     }
 
+    override fun getMenuRes() = R.menu.vector_media_viewer
+
+    override fun onOptionsItemSelected(item: MenuItem): Boolean {
+        when (item.itemId) {
+            R.id.mediaViewerShareAction -> {
+                onShareActionClicked()
+                return true
+            }
+        }
+        return super.onOptionsItemSelected(item)
+    }
+
+    private fun onShareActionClicked() {
+        session.downloadFile(
+                FileService.DownloadMode.FOR_EXTERNAL_SHARE,
+                mediaData.eventId,
+                mediaData.filename,
+                mediaData.url,
+                mediaData.elementToDecrypt,
+                object : MatrixCallback<File> {
+                    override fun onSuccess(data: File) {
+                        shareMedia(this@ImageMediaViewerActivity, data, getMimeTypeFromUri(this@ImageMediaViewerActivity, data.toUri()))
+                    }
+                }
+        )
+    }
+
     private fun configureToolbar(toolbar: Toolbar, mediaData: ImageContentRenderer.Data) {
         setSupportActionBar(toolbar)
         supportActionBar?.apply {
diff --git a/vector/src/main/java/im/vector/riotx/features/media/VideoMediaViewerActivity.kt b/vector/src/main/java/im/vector/riotx/features/media/VideoMediaViewerActivity.kt
index 9c3312f3bb..6985278ad0 100644
--- a/vector/src/main/java/im/vector/riotx/features/media/VideoMediaViewerActivity.kt
+++ b/vector/src/main/java/im/vector/riotx/features/media/VideoMediaViewerActivity.kt
@@ -19,17 +19,29 @@ package im.vector.riotx.features.media
 import android.content.Context
 import android.content.Intent
 import android.os.Bundle
+import android.view.MenuItem
 import androidx.appcompat.widget.Toolbar
+import androidx.core.net.toUri
+import im.vector.matrix.android.api.MatrixCallback
+import im.vector.matrix.android.api.session.Session
+import im.vector.matrix.android.api.session.file.FileService
+import im.vector.riotx.R
 import im.vector.riotx.core.di.ScreenComponent
+import im.vector.riotx.core.intent.getMimeTypeFromUri
 import im.vector.riotx.core.platform.VectorBaseActivity
+import im.vector.riotx.core.utils.shareMedia
 import kotlinx.android.synthetic.main.activity_video_media_viewer.*
+import java.io.File
 import javax.inject.Inject
 
 class VideoMediaViewerActivity : VectorBaseActivity() {
 
+    @Inject lateinit var session: Session
     @Inject lateinit var imageContentRenderer: ImageContentRenderer
     @Inject lateinit var videoContentRenderer: VideoContentRenderer
 
+    private lateinit var mediaData: VideoContentRenderer.Data
+
     override fun injectWith(injector: ScreenComponent) {
         injector.inject(this)
     }
@@ -37,11 +49,47 @@ class VideoMediaViewerActivity : VectorBaseActivity() {
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
         setContentView(im.vector.riotx.R.layout.activity_video_media_viewer)
-        val mediaData = intent.getParcelableExtra<VideoContentRenderer.Data>(EXTRA_MEDIA_DATA)
 
-        configureToolbar(videoMediaViewerToolbar, mediaData)
-        imageContentRenderer.render(mediaData.thumbnailMediaData, ImageContentRenderer.Mode.FULL_SIZE, videoMediaViewerThumbnailView)
-        videoContentRenderer.render(mediaData, videoMediaViewerThumbnailView, videoMediaViewerLoading, videoMediaViewerVideoView, videoMediaViewerErrorView)
+        if (intent.hasExtra(EXTRA_MEDIA_DATA)) {
+            mediaData = intent.getParcelableExtra<VideoContentRenderer.Data>(EXTRA_MEDIA_DATA)!!
+
+            configureToolbar(videoMediaViewerToolbar, mediaData)
+            imageContentRenderer.render(mediaData.thumbnailMediaData, ImageContentRenderer.Mode.FULL_SIZE, videoMediaViewerThumbnailView)
+            videoContentRenderer.render(mediaData,
+                    videoMediaViewerThumbnailView,
+                    videoMediaViewerLoading,
+                    videoMediaViewerVideoView,
+                    videoMediaViewerErrorView)
+        } else {
+            finish()
+        }
+    }
+
+    override fun getMenuRes() = R.menu.vector_media_viewer
+
+    override fun onOptionsItemSelected(item: MenuItem): Boolean {
+        when (item.itemId) {
+            R.id.mediaViewerShareAction -> {
+                onShareActionClicked()
+                return true
+            }
+        }
+        return super.onOptionsItemSelected(item)
+    }
+
+    private fun onShareActionClicked() {
+        session.downloadFile(
+                FileService.DownloadMode.FOR_EXTERNAL_SHARE,
+                mediaData.eventId,
+                mediaData.filename,
+                mediaData.url,
+                mediaData.elementToDecrypt,
+                object : MatrixCallback<File> {
+                    override fun onSuccess(data: File) {
+                        shareMedia(this@VideoMediaViewerActivity, data, getMimeTypeFromUri(this@VideoMediaViewerActivity, data.toUri()))
+                    }
+                }
+        )
     }
 
     private fun configureToolbar(toolbar: Toolbar, mediaData: VideoContentRenderer.Data) {
diff --git a/vector/src/main/java/im/vector/riotx/features/navigation/DefaultNavigator.kt b/vector/src/main/java/im/vector/riotx/features/navigation/DefaultNavigator.kt
index 2e91090ec4..2e2814cb78 100644
--- a/vector/src/main/java/im/vector/riotx/features/navigation/DefaultNavigator.kt
+++ b/vector/src/main/java/im/vector/riotx/features/navigation/DefaultNavigator.kt
@@ -34,6 +34,7 @@ import im.vector.riotx.core.utils.toast
 import im.vector.riotx.features.createdirect.CreateDirectRoomActivity
 import im.vector.riotx.features.crypto.keysbackup.settings.KeysBackupManageActivity
 import im.vector.riotx.features.crypto.keysbackup.setup.KeysBackupSetupActivity
+import im.vector.riotx.features.crypto.recover.BootstrapBottomSheet
 import im.vector.riotx.features.crypto.verification.SupportedVerificationMethodsProvider
 import im.vector.riotx.features.crypto.verification.VerificationBottomSheet
 import im.vector.riotx.features.debug.DebugMenuActivity
@@ -95,7 +96,7 @@ class DefaultNavigator @Inject constructor(
                     roomId = null,
                     otherUserId = session.myUserId,
                     transactionId = pr.transactionId
-            ).show(context.supportFragmentManager, "REQPOP")
+            ).show(context.supportFragmentManager, VerificationBottomSheet.WAITING_SELF_VERIF_TAG)
         }
     }
 
@@ -107,6 +108,12 @@ class DefaultNavigator @Inject constructor(
         }
     }
 
+    override fun upgradeSessionSecurity(context: Context) {
+        if (context is VectorBaseActivity) {
+            BootstrapBottomSheet.show(context.supportFragmentManager, false)
+        }
+    }
+
     override fun openNotJoinedRoom(context: Context, roomIdOrAlias: String?, eventId: String?, buildTask: Boolean) {
         if (context is VectorBaseActivity) {
             context.notImplemented("Open not joined room")
diff --git a/vector/src/main/java/im/vector/riotx/features/navigation/Navigator.kt b/vector/src/main/java/im/vector/riotx/features/navigation/Navigator.kt
index 65ef08dd05..bf99643912 100644
--- a/vector/src/main/java/im/vector/riotx/features/navigation/Navigator.kt
+++ b/vector/src/main/java/im/vector/riotx/features/navigation/Navigator.kt
@@ -34,6 +34,8 @@ interface Navigator {
 
     fun waitSessionVerification(context: Context)
 
+    fun upgradeSessionSecurity(context: Context)
+
     fun openRoomForSharingAndFinish(activity: Activity, roomId: String, sharedData: SharedData)
 
     fun openNotJoinedRoom(context: Context, roomIdOrAlias: String?, eventId: String? = null, buildTask: Boolean = false)
diff --git a/vector/src/main/java/im/vector/riotx/features/notifications/NotificationBroadcastReceiver.kt b/vector/src/main/java/im/vector/riotx/features/notifications/NotificationBroadcastReceiver.kt
index 53d69bce2d..04b267fb3a 100644
--- a/vector/src/main/java/im/vector/riotx/features/notifications/NotificationBroadcastReceiver.kt
+++ b/vector/src/main/java/im/vector/riotx/features/notifications/NotificationBroadcastReceiver.kt
@@ -97,7 +97,7 @@ class NotificationBroadcastReceiver : BroadcastReceiver() {
         val message = getReplyMessage(intent)
         val roomId = intent.getStringExtra(KEY_ROOM_ID)
 
-        if (message.isNullOrBlank() || roomId.isBlank()) {
+        if (message.isNullOrBlank() || roomId.isNullOrBlank()) {
             // ignore this event
             // Can this happen? should we update notification?
             return
diff --git a/vector/src/main/java/im/vector/riotx/features/notifications/NotificationDrawerManager.kt b/vector/src/main/java/im/vector/riotx/features/notifications/NotificationDrawerManager.kt
index 9e3a298378..6fc396b264 100644
--- a/vector/src/main/java/im/vector/riotx/features/notifications/NotificationDrawerManager.kt
+++ b/vector/src/main/java/im/vector/riotx/features/notifications/NotificationDrawerManager.kt
@@ -157,7 +157,7 @@ class NotificationDrawerManager @Inject constructor(private val context: Context
                     e is NotifiableMessageEvent && e.roomId == roomId
                 }
             }
-            notificationUtils.cancelNotificationMessage(roomId, ROOM_MESSAGES_NOTIFICATION_ID)
+            refreshNotificationDrawer()
         }
     }
 
@@ -191,7 +191,12 @@ class NotificationDrawerManager @Inject constructor(private val context: Context
         backgroundHandler.removeCallbacksAndMessages(null)
         backgroundHandler.postDelayed(
                 {
-                    refreshNotificationDrawerBg()
+                    try {
+                        refreshNotificationDrawerBg()
+                    } catch (throwable: Throwable) {
+                        // It can happen if for instance session has been destroyed. It's a bit ugly to try catch like this, but it's safer
+                        Timber.w(throwable, "refreshNotificationDrawerBg failure")
+                    }
                 }, 200)
     }
 
diff --git a/vector/src/main/java/im/vector/riotx/features/rageshake/VectorFileLogger.kt b/vector/src/main/java/im/vector/riotx/features/rageshake/VectorFileLogger.kt
index d4563eb243..bcc48fb96c 100644
--- a/vector/src/main/java/im/vector/riotx/features/rageshake/VectorFileLogger.kt
+++ b/vector/src/main/java/im/vector/riotx/features/rageshake/VectorFileLogger.kt
@@ -77,7 +77,7 @@ class VectorFileLogger @Inject constructor(val context: Context, private val vec
                 sFileHandler?.formatter = LogFormatter()
                 sLogger.useParentHandlers = false
                 sLogger.level = Level.ALL
-                sLogger.addHandler(sFileHandler)
+                sFileHandler?.let { sLogger.addHandler(it) }
             }
         } catch (e: Throwable) {
             Timber.e(e, "Failed to initialize FileLogger")
diff --git a/vector/src/main/java/im/vector/riotx/features/reactions/data/EmojiDataSource.kt b/vector/src/main/java/im/vector/riotx/features/reactions/data/EmojiDataSource.kt
index 1d7338e2a4..4acb8ed79e 100644
--- a/vector/src/main/java/im/vector/riotx/features/reactions/data/EmojiDataSource.kt
+++ b/vector/src/main/java/im/vector/riotx/features/reactions/data/EmojiDataSource.kt
@@ -32,6 +32,23 @@ class EmojiDataSource @Inject constructor(
                         .adapter(EmojiData::class.java)
                         .fromJson(input.bufferedReader().use { it.readText() })
             }
+            ?.let { parsedRawData ->
+                // Add key as a keyword, it will solve the issue that ":tada" is not available in completion
+                parsedRawData.copy(
+                        emojis = mutableMapOf<String, EmojiItem>().apply {
+                            parsedRawData.emojis.keys.forEach { key ->
+                                val origin = parsedRawData.emojis[key] ?: return@forEach
+
+                                // Do not add keys containing '_'
+                                if (origin.keywords.contains(key) || key.contains("_")) {
+                                    put(key, origin)
+                                } else {
+                                    put(key, origin.copy(keywords = origin.keywords + key))
+                                }
+                            }
+                        }
+                )
+            }
             ?: EmojiData(emptyList(), emptyMap(), emptyMap())
 
     private val quickReactions = mutableListOf<EmojiItem>()
diff --git a/vector/src/main/java/im/vector/riotx/features/roomdirectory/roompreview/RoomPreviewActivity.kt b/vector/src/main/java/im/vector/riotx/features/roomdirectory/roompreview/RoomPreviewActivity.kt
index a7cb8f2f68..3cb442127f 100644
--- a/vector/src/main/java/im/vector/riotx/features/roomdirectory/roompreview/RoomPreviewActivity.kt
+++ b/vector/src/main/java/im/vector/riotx/features/roomdirectory/roompreview/RoomPreviewActivity.kt
@@ -70,7 +70,7 @@ class RoomPreviewActivity : VectorBaseActivity(), ToolbarConfigurable {
         if (isFirstCreation()) {
             val args = intent.getParcelableExtra<RoomPreviewData>(ARG)
 
-            if (args.worldReadable) {
+            if (args?.worldReadable == true) {
                 // TODO Room preview: Note: M does not recommend to use /events anymore, so for now we just display the room preview
                 // TODO the same way if it was not world readable
                 addFragment(R.id.simpleFragmentContainer, RoomPreviewNoPreviewFragment::class.java, args)
diff --git a/vector/src/main/java/im/vector/riotx/features/roommemberprofile/devices/DeviceListEpoxyController.kt b/vector/src/main/java/im/vector/riotx/features/roommemberprofile/devices/DeviceListEpoxyController.kt
index 50a87b24a4..87d156759d 100644
--- a/vector/src/main/java/im/vector/riotx/features/roommemberprofile/devices/DeviceListEpoxyController.kt
+++ b/vector/src/main/java/im/vector/riotx/features/roommemberprofile/devices/DeviceListEpoxyController.kt
@@ -63,7 +63,7 @@ class DeviceListEpoxyController @Inject constructor(private val stringProvider:
                 }
             }
             is Success    -> {
-                val deviceList = data.cryptoDevices.invoke().sortedByDescending {
+                val deviceList = data.cryptoDevices.invoke().sortedBy {
                     it.isVerified
                 }
 
diff --git a/vector/src/main/java/im/vector/riotx/features/roommemberprofile/devices/DeviceTrustInfoEpoxyController.kt b/vector/src/main/java/im/vector/riotx/features/roommemberprofile/devices/DeviceTrustInfoEpoxyController.kt
index 907c019f39..a9af166c1d 100644
--- a/vector/src/main/java/im/vector/riotx/features/roommemberprofile/devices/DeviceTrustInfoEpoxyController.kt
+++ b/vector/src/main/java/im/vector/riotx/features/roommemberprofile/devices/DeviceTrustInfoEpoxyController.kt
@@ -101,7 +101,7 @@ class DeviceTrustInfoEpoxyController @Inject constructor(private val stringProvi
 
                 bottomSheetVerificationActionItem {
                     id("verify")
-                    title(stringProvider.getString(R.string.verification_verify_device_manually))
+                    title(stringProvider.getString(R.string.cross_signing_verify_by_emoji))
                     titleColor(colorProvider.getColor(R.color.riotx_accent))
                     iconRes(R.drawable.ic_arrow_right)
                     iconColor(colorProvider.getColor(R.color.riotx_accent))
diff --git a/vector/src/main/java/im/vector/riotx/features/settings/VectorLocale.kt b/vector/src/main/java/im/vector/riotx/features/settings/VectorLocale.kt
index 805fa53e96..e1a89ab3c4 100644
--- a/vector/src/main/java/im/vector/riotx/features/settings/VectorLocale.kt
+++ b/vector/src/main/java/im/vector/riotx/features/settings/VectorLocale.kt
@@ -19,7 +19,7 @@ package im.vector.riotx.features.settings
 import android.content.Context
 import android.content.res.Configuration
 import android.os.Build
-import android.preference.PreferenceManager
+import androidx.preference.PreferenceManager
 import androidx.core.content.edit
 import im.vector.riotx.BuildConfig
 import im.vector.riotx.R
@@ -59,9 +59,9 @@ object VectorLocale {
         val preferences = PreferenceManager.getDefaultSharedPreferences(context)
 
         if (preferences.contains(APPLICATION_LOCALE_LANGUAGE_KEY)) {
-            applicationLocale = Locale(preferences.getString(APPLICATION_LOCALE_LANGUAGE_KEY, ""),
-                    preferences.getString(APPLICATION_LOCALE_COUNTRY_KEY, ""),
-                    preferences.getString(APPLICATION_LOCALE_VARIANT_KEY, "")
+            applicationLocale = Locale(preferences.getString(APPLICATION_LOCALE_LANGUAGE_KEY, "")!!,
+                    preferences.getString(APPLICATION_LOCALE_COUNTRY_KEY, "")!!,
+                    preferences.getString(APPLICATION_LOCALE_VARIANT_KEY, "")!!
             )
         } else {
             applicationLocale = Locale.getDefault()
diff --git a/vector/src/main/java/im/vector/riotx/features/settings/VectorPreferences.kt b/vector/src/main/java/im/vector/riotx/features/settings/VectorPreferences.kt
index 9473c26055..c995c4d986 100755
--- a/vector/src/main/java/im/vector/riotx/features/settings/VectorPreferences.kt
+++ b/vector/src/main/java/im/vector/riotx/features/settings/VectorPreferences.kt
@@ -24,12 +24,12 @@ import android.provider.MediaStore
 import androidx.core.content.edit
 import androidx.preference.PreferenceManager
 import com.squareup.seismic.ShakeDetector
+import im.vector.matrix.android.api.extensions.tryThis
 import im.vector.riotx.BuildConfig
 import im.vector.riotx.R
 import im.vector.riotx.features.homeserver.ServerUrlsRepository
 import im.vector.riotx.features.themes.ThemeUtils
 import timber.log.Timber
-import java.io.File
 import javax.inject.Inject
 
 class VectorPreferences @Inject constructor(private val context: Context) {
@@ -68,7 +68,7 @@ class VectorPreferences @Inject constructor(private val context: Context) {
         const val SETTINGS_ENCRYPTION_EXPORT_E2E_ROOM_KEYS_PREFERENCE_KEY = "SETTINGS_ENCRYPTION_EXPORT_E2E_ROOM_KEYS_PREFERENCE_KEY"
         const val SETTINGS_ENCRYPTION_IMPORT_E2E_ROOM_KEYS_PREFERENCE_KEY = "SETTINGS_ENCRYPTION_IMPORT_E2E_ROOM_KEYS_PREFERENCE_KEY"
         const val SETTINGS_ENCRYPTION_NEVER_SENT_TO_PREFERENCE_KEY = "SETTINGS_ENCRYPTION_NEVER_SENT_TO_PREFERENCE_KEY"
-        const val SETTINGS_SHOW_DEVICES_LIST_PREFERENCE_KEY =  "SETTINGS_SHOW_DEVICES_LIST_PREFERENCE_KEY"
+        const val SETTINGS_SHOW_DEVICES_LIST_PREFERENCE_KEY = "SETTINGS_SHOW_DEVICES_LIST_PREFERENCE_KEY"
 
         const val SETTINGS_SECURE_MESSAGE_RECOVERY_PREFERENCE_KEY = "SETTINGS_SECURE_MESSAGE_RECOVERY_PREFERENCE_KEY"
 
@@ -151,13 +151,15 @@ class VectorPreferences @Inject constructor(private val context: Context) {
         const val SETTINGS_USE_RAGE_SHAKE_KEY = "SETTINGS_USE_RAGE_SHAKE_KEY"
         const val SETTINGS_RAGE_SHAKE_DETECTION_THRESHOLD_KEY = "SETTINGS_RAGE_SHAKE_DETECTION_THRESHOLD_KEY"
 
+        // Security
+        const val SETTINGS_SECURITY_USE_FLAG_SECURE = "SETTINGS_SECURITY_USE_FLAG_SECURE"
+
         // other
         const val SETTINGS_MEDIA_SAVING_PERIOD_KEY = "SETTINGS_MEDIA_SAVING_PERIOD_KEY"
         private const val SETTINGS_MEDIA_SAVING_PERIOD_SELECTED_KEY = "SETTINGS_MEDIA_SAVING_PERIOD_SELECTED_KEY"
         private const val DID_ASK_TO_IGNORE_BATTERY_OPTIMIZATIONS_KEY = "DID_ASK_TO_IGNORE_BATTERY_OPTIMIZATIONS_KEY"
         private const val DID_MIGRATE_TO_NOTIFICATION_REWORK = "DID_MIGRATE_TO_NOTIFICATION_REWORK"
         private const val DID_ASK_TO_USE_ANALYTICS_TRACKING_KEY = "DID_ASK_TO_USE_ANALYTICS_TRACKING_KEY"
-        const val SETTINGS_DEACTIVATE_ACCOUNT_KEY = "SETTINGS_DEACTIVATE_ACCOUNT_KEY"
         private const val SETTINGS_DISPLAY_ALL_EVENTS_KEY = "SETTINGS_DISPLAY_ALL_EVENTS_KEY"
 
         private const val MEDIA_SAVING_3_DAYS = 0
@@ -165,6 +167,8 @@ class VectorPreferences @Inject constructor(private val context: Context) {
         private const val MEDIA_SAVING_1_MONTH = 2
         private const val MEDIA_SAVING_FOREVER = 3
 
+        private const val SETTINGS_UNKNOWN_DEVICE_DISMISSED_LIST = "SETTINGS_UNKNWON_DEVICE_DISMISSED_LIST"
+
         // some preferences keys must be kept after a logout
         private val mKeysToKeepAfterLogout = listOf(
                 SETTINGS_DEFAULT_MEDIA_COMPRESSION_KEY,
@@ -200,7 +204,13 @@ class VectorPreferences @Inject constructor(private val context: Context) {
                 SETTINGS_SET_SYNC_TIMEOUT_PREFERENCE_KEY,
                 SETTINGS_SET_SYNC_DELAY_PREFERENCE_KEY,
 
-                SETTINGS_USE_RAGE_SHAKE_KEY
+                SETTINGS_DEVELOPER_MODE_PREFERENCE_KEY,
+                SETTINGS_LABS_SHOW_HIDDEN_EVENTS_PREFERENCE_KEY,
+                SETTINGS_LABS_ALLOW_EXTENDED_LOGS,
+                SETTINGS_DEVELOPER_MODE_FAIL_FAST_PREFERENCE_KEY,
+
+                SETTINGS_USE_RAGE_SHAKE_KEY,
+                SETTINGS_SECURITY_USE_FLAG_SECURE
         )
     }
 
@@ -362,6 +372,18 @@ class VectorPreferences @Inject constructor(private val context: Context) {
         return defaultPrefs.getBoolean(SETTINGS_PLAY_SHUTTER_SOUND_KEY, true)
     }
 
+    fun storeUnknownDeviceDismissedList(deviceIds: List<String>) {
+        defaultPrefs.edit(true) {
+            putStringSet(SETTINGS_UNKNOWN_DEVICE_DISMISSED_LIST, deviceIds.toSet())
+        }
+    }
+
+    fun getUnknownDeviceDismissedList(): List<String> {
+        return tryThis {
+            defaultPrefs.getStringSet(SETTINGS_UNKNOWN_DEVICE_DISMISSED_LIST, null)?.toList()
+        } ?: emptyList()
+    }
+
     /**
      * Update the notification ringtone
      *
@@ -427,11 +449,11 @@ class VectorPreferences @Inject constructor(private val context: Context) {
         val toneUri = getNotificationRingTone() ?: return null
 
         try {
-            val proj = arrayOf(MediaStore.Audio.Media.DATA)
+            val proj = arrayOf(MediaStore.Audio.Media.DISPLAY_NAME)
             return context.contentResolver.query(toneUri, proj, null, null, null)?.use {
-                val columnIndex = it.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA)
+                val columnIndex = it.getColumnIndexOrThrow(MediaStore.Audio.Media.DISPLAY_NAME)
                 it.moveToFirst()
-                File(it.getString(columnIndex)).nameWithoutExtension
+                it.getString(columnIndex)
             }
         } catch (e: Exception) {
             Timber.e(e, "## getNotificationRingToneName() failed")
@@ -747,4 +769,11 @@ class VectorPreferences @Inject constructor(private val context: Context) {
     fun displayAllEvents(): Boolean {
         return defaultPrefs.getBoolean(SETTINGS_DISPLAY_ALL_EVENTS_KEY, false)
     }
+
+    /**
+     * The user does not allow screenshots of the application
+     */
+    fun useFlagSecure(): Boolean {
+        return defaultPrefs.getBoolean(SETTINGS_SECURITY_USE_FLAG_SECURE, false)
+    }
 }
diff --git a/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsActivity.kt b/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsActivity.kt
index 5db14fdbd2..0c73c0f5d3 100755
--- a/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsActivity.kt
+++ b/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsActivity.kt
@@ -20,11 +20,13 @@ import android.content.Intent
 import androidx.fragment.app.FragmentManager
 import androidx.preference.Preference
 import androidx.preference.PreferenceFragmentCompat
+import im.vector.matrix.android.api.failure.GlobalError
 import im.vector.matrix.android.api.session.Session
 import im.vector.riotx.R
 import im.vector.riotx.core.di.ScreenComponent
 import im.vector.riotx.core.extensions.replaceFragment
 import im.vector.riotx.core.platform.VectorBaseActivity
+import im.vector.riotx.features.settings.devices.VectorSettingsDevicesFragment
 import kotlinx.android.synthetic.main.activity_vector_settings.*
 import timber.log.Timber
 import javax.inject.Inject
@@ -43,6 +45,8 @@ class VectorSettingsActivity : VectorBaseActivity(),
 
     private var keyToHighlight: String? = null
 
+    var ignoreInvalidTokenError = false
+
     @Inject lateinit var session: Session
 
     override fun injectWith(injector: ScreenComponent) {
@@ -55,11 +59,16 @@ class VectorSettingsActivity : VectorBaseActivity(),
         if (isFirstCreation()) {
             // display the fragment
             when (intent.getIntExtra(EXTRA_DIRECT_ACCESS, EXTRA_DIRECT_ACCESS_ROOT)) {
-                EXTRA_DIRECT_ACCESS_ADVANCED_SETTINGS ->
+                EXTRA_DIRECT_ACCESS_ADVANCED_SETTINGS                ->
                     replaceFragment(R.id.vector_settings_page, VectorSettingsAdvancedSettingsFragment::class.java, null, FRAGMENT_TAG)
-                EXTRA_DIRECT_ACCESS_SECURITY_PRIVACY ->
+                EXTRA_DIRECT_ACCESS_SECURITY_PRIVACY                 ->
                     replaceFragment(R.id.vector_settings_page, VectorSettingsSecurityPrivacyFragment::class.java, null, FRAGMENT_TAG)
-                else                                  ->
+                EXTRA_DIRECT_ACCESS_SECURITY_PRIVACY_MANAGE_SESSIONS ->
+                    replaceFragment(R.id.vector_settings_page,
+                            VectorSettingsDevicesFragment::class.java,
+                            null,
+                            FRAGMENT_TAG)
+                else                                                 ->
                     replaceFragment(R.id.vector_settings_page, VectorSettingsRootFragment::class.java, null, FRAGMENT_TAG)
             }
         }
@@ -110,6 +119,14 @@ class VectorSettingsActivity : VectorBaseActivity(),
         return keyToHighlight
     }
 
+    override fun handleInvalidToken(globalError: GlobalError.InvalidToken) {
+        if (ignoreInvalidTokenError) {
+            Timber.w("Ignoring invalid token global error")
+        } else {
+            super.handleInvalidToken(globalError)
+        }
+    }
+
     companion object {
         fun getIntent(context: Context, directAccess: Int) = Intent(context, VectorSettingsActivity::class.java)
                 .apply { putExtra(EXTRA_DIRECT_ACCESS, directAccess) }
@@ -119,6 +136,7 @@ class VectorSettingsActivity : VectorBaseActivity(),
         const val EXTRA_DIRECT_ACCESS_ROOT = 0
         const val EXTRA_DIRECT_ACCESS_ADVANCED_SETTINGS = 1
         const val EXTRA_DIRECT_ACCESS_SECURITY_PRIVACY = 2
+        const val EXTRA_DIRECT_ACCESS_SECURITY_PRIVACY_MANAGE_SESSIONS = 3
 
         private const val FRAGMENT_TAG = "VectorSettingsPreferencesFragment"
     }
diff --git a/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsGeneralFragment.kt b/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsGeneralFragment.kt
index 0a670e2c5a..802cf7b33f 100644
--- a/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsGeneralFragment.kt
+++ b/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsGeneralFragment.kt
@@ -35,6 +35,8 @@ import com.bumptech.glide.Glide
 import com.bumptech.glide.load.engine.cache.DiskCache
 import com.google.android.material.textfield.TextInputEditText
 import com.google.android.material.textfield.TextInputLayout
+import im.vector.matrix.android.api.MatrixCallback
+import im.vector.matrix.android.api.failure.isInvalidPassword
 import im.vector.riotx.R
 import im.vector.riotx.core.extensions.hideKeyboard
 import im.vector.riotx.core.extensions.showPassword
@@ -108,10 +110,14 @@ class VectorSettingsGeneralFragment : VectorSettingsBaseFragment() {
         }
 
         // Password
-        mPasswordPreference.onPreferenceClickListener = Preference.OnPreferenceClickListener {
-            notImplemented()
-            // onPasswordUpdateClick()
-            false
+        // Hide the preference if password can not be updated
+        if (session.getHomeServerCapabilities().canChangePassword) {
+            mPasswordPreference.onPreferenceClickListener = Preference.OnPreferenceClickListener {
+                onPasswordUpdateClick()
+                false
+            }
+        } else {
+            mPasswordPreference.isVisible = false
         }
 
         // Add Email
@@ -228,19 +234,6 @@ class VectorSettingsGeneralFragment : VectorSettingsBaseFragment() {
 
             false
         }
-
-        // Deactivate account section
-
-        // deactivate account
-        findPreference<VectorPreference>(VectorPreferences.SETTINGS_DEACTIVATE_ACCOUNT_KEY)!!
-                .onPreferenceClickListener = Preference.OnPreferenceClickListener {
-            activity?.let {
-                notImplemented()
-                // TODO startActivity(DeactivateAccountActivity.getIntent(it))
-            }
-
-            false
-        }
     }
 
     override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
@@ -684,21 +677,20 @@ class VectorSettingsGeneralFragment : VectorSettingsBaseFragment() {
 
             var passwordShown = false
 
-            showPassword.setOnClickListener(object : View.OnClickListener {
-                override fun onClick(v: View?) {
-                    passwordShown = !passwordShown
+            showPassword.setOnClickListener {
+                passwordShown = !passwordShown
 
-                    oldPasswordText.showPassword(passwordShown)
-                    newPasswordText.showPassword(passwordShown)
-                    confirmNewPasswordText.showPassword(passwordShown)
+                oldPasswordText.showPassword(passwordShown)
+                newPasswordText.showPassword(passwordShown)
+                confirmNewPasswordText.showPassword(passwordShown)
 
-                    showPassword.setImageResource(if (passwordShown) R.drawable.ic_eye_closed_black else R.drawable.ic_eye_black)
-                }
-            })
+                showPassword.setImageResource(if (passwordShown) R.drawable.ic_eye_closed_black else R.drawable.ic_eye_black)
+            }
 
             val dialog = AlertDialog.Builder(activity)
                     .setView(view)
-                    .setPositiveButton(R.string.settings_change_password_submit, null)
+                    .setCancelable(false)
+                    .setPositiveButton(R.string.settings_change_password, null)
                     .setNegativeButton(R.string.cancel, null)
                     .setOnDismissListener {
                         view.hideKeyboard()
@@ -707,12 +699,13 @@ class VectorSettingsGeneralFragment : VectorSettingsBaseFragment() {
 
             dialog.setOnShowListener {
                 val updateButton = dialog.getButton(AlertDialog.BUTTON_POSITIVE)
+                val cancelButton = dialog.getButton(AlertDialog.BUTTON_NEGATIVE)
                 updateButton.isEnabled = false
 
                 fun updateUi() {
-                    val oldPwd = oldPasswordText.text.toString().trim()
-                    val newPwd = newPasswordText.text.toString().trim()
-                    val newConfirmPwd = confirmNewPasswordText.text.toString().trim()
+                    val oldPwd = oldPasswordText.text.toString()
+                    val newPwd = newPasswordText.text.toString()
+                    val newConfirmPwd = confirmNewPasswordText.text.toString()
 
                     updateButton.isEnabled = oldPwd.isNotEmpty() && newPwd.isNotEmpty() && newPwd == newConfirmPwd
 
@@ -750,6 +743,7 @@ class VectorSettingsGeneralFragment : VectorSettingsBaseFragment() {
                         confirmNewPasswordText.isEnabled = false
                         changePasswordLoader.isVisible = true
                         updateButton.isEnabled = false
+                        cancelButton.isEnabled = false
                     } else {
                         showPassword.isEnabled = true
                         oldPasswordText.isEnabled = true
@@ -757,6 +751,7 @@ class VectorSettingsGeneralFragment : VectorSettingsBaseFragment() {
                         confirmNewPasswordText.isEnabled = true
                         changePasswordLoader.isVisible = false
                         updateButton.isEnabled = true
+                        cancelButton.isEnabled = true
                     }
                 }
 
@@ -768,47 +763,32 @@ class VectorSettingsGeneralFragment : VectorSettingsBaseFragment() {
 
                     view.hideKeyboard()
 
-                    val oldPwd = oldPasswordText.text.toString().trim()
-                    val newPwd = newPasswordText.text.toString().trim()
+                    val oldPwd = oldPasswordText.text.toString()
+                    val newPwd = newPasswordText.text.toString()
 
-                    notImplemented()
-                    /* TODO
                     showPasswordLoadingView(true)
-
-                    session.updatePassword(oldPwd, newPwd, object : MatrixCallback<Unit> {
-                        private fun onDone(@StringRes textResId: Int) {
+                    session.changePassword(oldPwd, newPwd, object : MatrixCallback<Unit> {
+                        override fun onSuccess(data: Unit) {
+                            if (!isAdded) {
+                                return
+                            }
                             showPasswordLoadingView(false)
+                            dialog.dismiss()
+                            activity.toast(R.string.settings_password_updated)
+                        }
 
-                            if (textResId == R.string.settings_fail_to_update_password_invalid_current_password) {
-                                oldPasswordTil.error = getString(textResId)
-                            } else {
-                                dialog.dismiss()
-                                activity.toast(textResId, Toast.LENGTH_LONG)
+                        override fun onFailure(failure: Throwable) {
+                            if (!isAdded) {
+                                return
                             }
-                        }
-
-                        override fun onSuccess(info: Void?) {
-                            onDone(R.string.settings_password_updated)
-                        }
-
-                        override fun onNetworkError(e: Exception) {
-                            onDone(R.string.settings_fail_to_update_password)
-                        }
-
-                        override fun onMatrixError(e: MatrixError) {
-                            if (e.error == "Invalid password") {
-                                onDone(R.string.settings_fail_to_update_password_invalid_current_password)
+                            showPasswordLoadingView(false)
+                            if (failure.isInvalidPassword()) {
+                                oldPasswordTil.error = getString(R.string.settings_fail_to_update_password_invalid_current_password)
                             } else {
-                                dialog.dismiss()
-                                onDone(R.string.settings_fail_to_update_password)
+                                oldPasswordTil.error = getString(R.string.settings_fail_to_update_password)
                             }
                         }
-
-                        override fun onUnexpectedError(e: Exception) {
-                            onDone(R.string.settings_fail_to_update_password)
-                        }
                     })
-                    */
                 }
             }
             dialog.show()
diff --git a/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsSecurityPrivacyFragment.kt b/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsSecurityPrivacyFragment.kt
index 4324c79dfd..394587ea5d 100644
--- a/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsSecurityPrivacyFragment.kt
+++ b/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsSecurityPrivacyFragment.kt
@@ -58,23 +58,10 @@ class VectorSettingsSecurityPrivacyFragment @Inject constructor(
     override var titleRes = R.string.settings_security_and_privacy
     override val preferenceXmlRes = R.xml.vector_settings_security_privacy
 
-    // devices: device IDs and device names
-    private val mDevicesNameList: MutableList<DeviceInfo> = mutableListOf()
-
-    private var mMyDeviceInfo: DeviceInfo? = null
-
     // cryptography
     private val mCryptographyCategory by lazy {
         findPreference<PreferenceCategory>(VectorPreferences.SETTINGS_CRYPTOGRAPHY_PREFERENCE_KEY)!!
     }
-    // cryptography manage
-    private val mCryptographyManageCategory by lazy {
-        findPreference<PreferenceCategory>(VectorPreferences.SETTINGS_CRYPTOGRAPHY_MANAGE_PREFERENCE_KEY)!!
-    }
-    // displayed pushers
-    private val mPushersSettingsCategory by lazy {
-        findPreference<PreferenceCategory>(VectorPreferences.SETTINGS_NOTIFICATIONS_TARGETS_PREFERENCE_KEY)!!
-    }
 
     private val mCrossSigningStatePreference by lazy {
         findPreference<VectorPreference>(VectorPreferences.SETTINGS_ENCRYPTION_CROSS_SIGNING_PREFERENCE_KEY)!!
@@ -106,7 +93,6 @@ class VectorSettingsSecurityPrivacyFragment @Inject constructor(
         // My device name may have been updated
         refreshMyDevice()
         refreshXSigningStatus()
-        mCryptographyCategory.isVisible = vectorPreferences.developerMode()
     }
 
     override fun bindPref() {
@@ -133,7 +119,6 @@ class VectorSettingsSecurityPrivacyFragment @Inject constructor(
     }
 
     private fun refreshXSigningStatus() {
-        if (vectorPreferences.developerMode()) {
             val crossSigningKeys = session.cryptoService().crossSigningService().getMyCrossSigningKeys()
             val xSigningIsEnableInAccount = crossSigningKeys != null
             val xSigningKeysAreTrusted = session.cryptoService().crossSigningService().checkUserTrust(session.myUserId).isVerified()
@@ -154,9 +139,6 @@ class VectorSettingsSecurityPrivacyFragment @Inject constructor(
             }
 
             mCrossSigningStatePreference.isVisible = true
-        } else {
-            mCrossSigningStatePreference.isVisible = false
-        }
     }
 
     override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
@@ -203,7 +185,10 @@ class VectorSettingsSecurityPrivacyFragment @Inject constructor(
      */
     private fun exportKeys() {
         // We need WRITE_EXTERNAL permission
-        if (checkPermissions(PERMISSIONS_FOR_WRITING_FILES, this, PERMISSION_REQUEST_CODE_EXPORT_KEYS, R.string.permissions_rationale_msg_keys_backup_export)) {
+        if (checkPermissions(PERMISSIONS_FOR_WRITING_FILES,
+                        this,
+                        PERMISSION_REQUEST_CODE_EXPORT_KEYS,
+                        R.string.permissions_rationale_msg_keys_backup_export)) {
             activity?.let { activity ->
                 ExportKeysDialog().show(activity, object : ExportKeysDialog.ExportKeyDialogListener {
                     override fun onPassphrase(passphrase: String) {
@@ -332,7 +317,7 @@ class VectorSettingsSecurityPrivacyFragment @Inject constructor(
                                     }
 
                                     override fun onFailure(failure: Throwable) {
-                                        appContext.toast(failure.localizedMessage)
+                                        appContext.toast(failure.localizedMessage ?: getString(R.string.unexpected_error))
                                         hideLoadingView()
                                     }
                                 })
@@ -346,15 +331,6 @@ class VectorSettingsSecurityPrivacyFragment @Inject constructor(
     // Cryptography
     // ==============================================================================================================
 
-    private fun removeCryptographyPreference() {
-        preferenceScreen.let {
-            it.removePreference(mCryptographyCategory)
-
-            // Also remove keys management section
-            it.removePreference(mCryptographyManageCategory)
-        }
-    }
-
     /**
      * Build the cryptography preference section.
      *
@@ -436,7 +412,7 @@ class VectorSettingsSecurityPrivacyFragment @Inject constructor(
             refreshCryptographyPreference(it)
         }
         // TODO Move to a ViewModel...
-        session.cryptoService().getDevicesList(object : MatrixCallback<DevicesListResponse> {
+        session.cryptoService().fetchDevicesList(object : MatrixCallback<DevicesListResponse> {
             override fun onSuccess(data: DevicesListResponse) {
                 if (isAdded) {
                     refreshCryptographyPreference(data.devices ?: emptyList())
diff --git a/vector/src/main/java/im/vector/riotx/features/settings/account/deactivation/DeactivateAccountFragment.kt b/vector/src/main/java/im/vector/riotx/features/settings/account/deactivation/DeactivateAccountFragment.kt
new file mode 100644
index 0000000000..f5130d5e00
--- /dev/null
+++ b/vector/src/main/java/im/vector/riotx/features/settings/account/deactivation/DeactivateAccountFragment.kt
@@ -0,0 +1,119 @@
+/*
+ * 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.riotx.features.settings.account.deactivation
+
+import android.content.Context
+import android.os.Bundle
+import android.view.View
+import com.airbnb.mvrx.fragmentViewModel
+import com.airbnb.mvrx.withState
+import com.jakewharton.rxbinding3.widget.textChanges
+import im.vector.riotx.R
+import im.vector.riotx.core.extensions.exhaustive
+import im.vector.riotx.core.extensions.showPassword
+import im.vector.riotx.core.platform.VectorBaseActivity
+import im.vector.riotx.core.platform.VectorBaseFragment
+import im.vector.riotx.features.MainActivity
+import im.vector.riotx.features.MainActivityArgs
+import im.vector.riotx.features.settings.VectorSettingsActivity
+import kotlinx.android.synthetic.main.fragment_deactivate_account.*
+import javax.inject.Inject
+
+class DeactivateAccountFragment @Inject constructor(
+        val viewModelFactory: DeactivateAccountViewModel.Factory
+) : VectorBaseFragment() {
+
+    private val viewModel: DeactivateAccountViewModel by fragmentViewModel()
+
+    override fun getLayoutResId() = R.layout.fragment_deactivate_account
+
+    override fun onResume() {
+        super.onResume()
+        (activity as? VectorBaseActivity)?.supportActionBar?.setTitle(R.string.deactivate_account_title)
+    }
+
+    private var settingsActivity: VectorSettingsActivity? = null
+
+    override fun onAttach(context: Context) {
+        super.onAttach(context)
+        settingsActivity = context as? VectorSettingsActivity
+    }
+
+    override fun onDetach() {
+        super.onDetach()
+        settingsActivity = null
+    }
+
+    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+        super.onViewCreated(view, savedInstanceState)
+
+        setupUi()
+        setupViewListeners()
+        observeViewEvents()
+    }
+
+    private fun setupUi() {
+        deactivateAccountPassword.textChanges()
+                .subscribe {
+                    deactivateAccountPasswordTil.error = null
+                    deactivateAccountSubmit.isEnabled = it.isNotEmpty()
+                }
+                .disposeOnDestroyView()
+    }
+
+    private fun setupViewListeners() {
+        deactivateAccountPasswordReveal.setOnClickListener {
+            viewModel.handle(DeactivateAccountAction.TogglePassword)
+        }
+
+        deactivateAccountSubmit.setOnClickListener {
+            viewModel.handle(DeactivateAccountAction.DeactivateAccount(
+                    deactivateAccountPassword.text.toString(),
+                    deactivateAccountEraseCheckbox.isChecked))
+        }
+    }
+
+    private fun observeViewEvents() {
+        viewModel.observeViewEvents {
+            when (it) {
+                is DeactivateAccountViewEvents.Loading      -> {
+                    settingsActivity?.ignoreInvalidTokenError = true
+                    showLoadingDialog(it.message)
+                }
+                DeactivateAccountViewEvents.EmptyPassword   -> {
+                    settingsActivity?.ignoreInvalidTokenError = false
+                    deactivateAccountPasswordTil.error = getString(R.string.error_empty_field_your_password)
+                }
+                DeactivateAccountViewEvents.InvalidPassword -> {
+                    settingsActivity?.ignoreInvalidTokenError = false
+                    deactivateAccountPasswordTil.error = getString(R.string.settings_fail_to_update_password_invalid_current_password)
+                }
+                is DeactivateAccountViewEvents.OtherFailure -> {
+                    settingsActivity?.ignoreInvalidTokenError = false
+                    displayErrorDialog(it.throwable)
+                }
+                DeactivateAccountViewEvents.Done            ->
+                    MainActivity.restartApp(activity!!, MainActivityArgs(clearCredentials = true, isAccountDeactivated = true))
+            }.exhaustive
+        }
+    }
+
+    override fun invalidate() = withState(viewModel) { state ->
+        deactivateAccountPassword.showPassword(state.passwordShown)
+        deactivateAccountPasswordReveal.setImageResource(if (state.passwordShown) R.drawable.ic_eye_closed_black else R.drawable.ic_eye_black)
+    }
+}
diff --git a/vector/src/main/java/im/vector/riotx/features/settings/account/deactivation/DeactivateAccountViewEvents.kt b/vector/src/main/java/im/vector/riotx/features/settings/account/deactivation/DeactivateAccountViewEvents.kt
new file mode 100644
index 0000000000..4e7f7252e2
--- /dev/null
+++ b/vector/src/main/java/im/vector/riotx/features/settings/account/deactivation/DeactivateAccountViewEvents.kt
@@ -0,0 +1,30 @@
+/*
+ * 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.riotx.features.settings.account.deactivation
+
+import im.vector.riotx.core.platform.VectorViewEvents
+
+/**
+ * Transient events for deactivate account settings screen
+ */
+sealed class DeactivateAccountViewEvents : VectorViewEvents {
+    data class Loading(val message: CharSequence? = null) : DeactivateAccountViewEvents()
+    object EmptyPassword : DeactivateAccountViewEvents()
+    object InvalidPassword : DeactivateAccountViewEvents()
+    data class OtherFailure(val throwable: Throwable) : DeactivateAccountViewEvents()
+    object Done : DeactivateAccountViewEvents()
+}
diff --git a/vector/src/main/java/im/vector/riotx/features/settings/account/deactivation/DeactivateAccountViewModel.kt b/vector/src/main/java/im/vector/riotx/features/settings/account/deactivation/DeactivateAccountViewModel.kt
new file mode 100644
index 0000000000..adfc9ff5ae
--- /dev/null
+++ b/vector/src/main/java/im/vector/riotx/features/settings/account/deactivation/DeactivateAccountViewModel.kt
@@ -0,0 +1,93 @@
+/*
+ * 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.riotx.features.settings.account.deactivation
+
+import com.airbnb.mvrx.FragmentViewModelContext
+import com.airbnb.mvrx.MvRxState
+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.matrix.android.api.MatrixCallback
+import im.vector.matrix.android.api.failure.isInvalidPassword
+import im.vector.matrix.android.api.session.Session
+import im.vector.riotx.core.extensions.exhaustive
+import im.vector.riotx.core.platform.VectorViewModel
+import im.vector.riotx.core.platform.VectorViewModelAction
+
+data class DeactivateAccountViewState(
+        val passwordShown: Boolean = false
+) : MvRxState
+
+sealed class DeactivateAccountAction : VectorViewModelAction {
+    object TogglePassword : DeactivateAccountAction()
+    data class DeactivateAccount(val password: String, val eraseAllData: Boolean) : DeactivateAccountAction()
+}
+
+class DeactivateAccountViewModel @AssistedInject constructor(@Assisted private val initialState: DeactivateAccountViewState,
+                                                             private val session: Session)
+    : VectorViewModel<DeactivateAccountViewState, DeactivateAccountAction, DeactivateAccountViewEvents>(initialState) {
+
+    @AssistedInject.Factory
+    interface Factory {
+        fun create(initialState: DeactivateAccountViewState): DeactivateAccountViewModel
+    }
+
+    override fun handle(action: DeactivateAccountAction) {
+        when (action) {
+            DeactivateAccountAction.TogglePassword       -> handleTogglePassword()
+            is DeactivateAccountAction.DeactivateAccount -> handleDeactivateAccount(action)
+        }.exhaustive
+    }
+
+    private fun handleTogglePassword() = withState {
+        setState {
+            copy(passwordShown = !passwordShown)
+        }
+    }
+
+    private fun handleDeactivateAccount(action: DeactivateAccountAction.DeactivateAccount) {
+        if (action.password.isEmpty()) {
+            _viewEvents.post(DeactivateAccountViewEvents.EmptyPassword)
+            return
+        }
+
+        _viewEvents.post(DeactivateAccountViewEvents.Loading())
+
+        session.deactivateAccount(action.password, action.eraseAllData, object : MatrixCallback<Unit> {
+            override fun onSuccess(data: Unit) {
+                _viewEvents.post(DeactivateAccountViewEvents.Done)
+            }
+
+            override fun onFailure(failure: Throwable) {
+                if (failure.isInvalidPassword()) {
+                    _viewEvents.post(DeactivateAccountViewEvents.InvalidPassword)
+                } else {
+                    _viewEvents.post(DeactivateAccountViewEvents.OtherFailure(failure))
+                }
+            }
+        })
+    }
+
+    companion object : MvRxViewModelFactory<DeactivateAccountViewModel, DeactivateAccountViewState> {
+
+        @JvmStatic
+        override fun create(viewModelContext: ViewModelContext, state: DeactivateAccountViewState): DeactivateAccountViewModel? {
+            val fragment: DeactivateAccountFragment = (viewModelContext as FragmentViewModelContext).fragment()
+            return fragment.viewModelFactory.create(state)
+        }
+    }
+}
diff --git a/vector/src/main/java/im/vector/riotx/features/settings/crosssigning/CrossSigningEpoxyController.kt b/vector/src/main/java/im/vector/riotx/features/settings/crosssigning/CrossSigningEpoxyController.kt
index e33b12d19a..5b7875d0ce 100644
--- a/vector/src/main/java/im/vector/riotx/features/settings/crosssigning/CrossSigningEpoxyController.kt
+++ b/vector/src/main/java/im/vector/riotx/features/settings/crosssigning/CrossSigningEpoxyController.kt
@@ -24,18 +24,19 @@ import im.vector.riotx.core.ui.list.genericItem
 import im.vector.riotx.core.ui.list.genericItemWithValue
 import im.vector.riotx.core.utils.DimensionConverter
 import im.vector.riotx.features.crypto.verification.epoxy.bottomSheetVerificationActionItem
+import im.vector.riotx.features.settings.VectorPreferences
 import me.gujun.android.span.span
 import javax.inject.Inject
 
 class CrossSigningEpoxyController @Inject constructor(
         private val stringProvider: StringProvider,
         private val colorProvider: ColorProvider,
-        private val dimensionConverter: DimensionConverter
+        private val dimensionConverter: DimensionConverter,
+        private val vectorPreferences: VectorPreferences
 ) : TypedEpoxyController<CrossSigningSettingsViewState>() {
 
     interface InteractionListener {
         fun onInitializeCrossSigningKeys()
-        fun onResetCrossSigningKeys()
         fun verifySession()
     }
 
@@ -49,18 +50,6 @@ class CrossSigningEpoxyController @Inject constructor(
                 titleIconResourceId(R.drawable.ic_shield_trusted)
                 title(stringProvider.getString(R.string.encryption_information_dg_xsigning_complete))
             }
-            if (!data.isUploadingKeys) {
-                bottomSheetVerificationActionItem {
-                    id("resetkeys")
-                    title("Reset keys")
-                    titleColor(colorProvider.getColor(R.color.riotx_destructive_accent))
-                    iconRes(R.drawable.ic_arrow_right)
-                    iconColor(colorProvider.getColor(R.color.riotx_destructive_accent))
-                    listener {
-                        interactionListener?.onResetCrossSigningKeys()
-                    }
-                }
-            }
         } else if (data.xSigningKeysAreTrusted) {
             genericItem {
                 id("trusted")
@@ -68,20 +57,9 @@ class CrossSigningEpoxyController @Inject constructor(
                 title(stringProvider.getString(R.string.encryption_information_dg_xsigning_trusted))
             }
             if (!data.isUploadingKeys) {
-                bottomSheetVerificationActionItem {
-                    id("resetkeys")
-                    title("Reset keys")
-                    titleColor(colorProvider.getColor(R.color.riotx_destructive_accent))
-                    iconRes(R.drawable.ic_arrow_right)
-                    iconColor(colorProvider.getColor(R.color.riotx_destructive_accent))
-                    listener {
-                        interactionListener?.onResetCrossSigningKeys()
-                    }
-                }
-
                 bottomSheetVerificationActionItem {
                     id("verify")
-                    title(stringProvider.getString(R.string.complete_security))
+                    title(stringProvider.getString(R.string.crosssigning_verify_this_session))
                     titleColor(colorProvider.getColor(R.color.riotx_positive_accent))
                     iconRes(R.drawable.ic_arrow_right)
                     iconColor(colorProvider.getColor(R.color.riotx_positive_accent))
@@ -98,7 +76,7 @@ class CrossSigningEpoxyController @Inject constructor(
             }
             bottomSheetVerificationActionItem {
                 id("verify")
-                title(stringProvider.getString(R.string.complete_security))
+                title(stringProvider.getString(R.string.crosssigning_verify_this_session))
                 titleColor(colorProvider.getColor(R.color.riotx_positive_accent))
                 iconRes(R.drawable.ic_arrow_right)
                 iconColor(colorProvider.getColor(R.color.riotx_positive_accent))
@@ -106,25 +84,15 @@ class CrossSigningEpoxyController @Inject constructor(
                     interactionListener?.verifySession()
                 }
             }
-            bottomSheetVerificationActionItem {
-                id("resetkeys")
-                title("Reset keys")
-                titleColor(colorProvider.getColor(R.color.riotx_destructive_accent))
-                iconRes(R.drawable.ic_arrow_right)
-                iconColor(colorProvider.getColor(R.color.riotx_destructive_accent))
-                listener {
-                    interactionListener?.onResetCrossSigningKeys()
-                }
-            }
         } else {
             genericItem {
                 id("not")
                 title(stringProvider.getString(R.string.encryption_information_dg_xsigning_disabled))
             }
-            if (!data.isUploadingKeys) {
+            if (vectorPreferences.developerMode() && !data.isUploadingKeys) {
                 bottomSheetVerificationActionItem {
                     id("initKeys")
-                    title("Initialize keys")
+                    title(stringProvider.getString(R.string.initialize_cross_signing))
                     titleColor(colorProvider.getColor(R.color.riotx_positive_accent))
                     iconRes(R.drawable.ic_arrow_right)
                     iconColor(colorProvider.getColor(R.color.riotx_positive_accent))
diff --git a/vector/src/main/java/im/vector/riotx/features/settings/crosssigning/CrossSigningSettingsFragment.kt b/vector/src/main/java/im/vector/riotx/features/settings/crosssigning/CrossSigningSettingsFragment.kt
index 76835211cb..1f81fd7c7b 100644
--- a/vector/src/main/java/im/vector/riotx/features/settings/crosssigning/CrossSigningSettingsFragment.kt
+++ b/vector/src/main/java/im/vector/riotx/features/settings/crosssigning/CrossSigningSettingsFragment.kt
@@ -101,14 +101,4 @@ class CrossSigningSettingsFragment @Inject constructor(
     override fun verifySession() {
         viewModel.handle(CrossSigningAction.VerifySession)
     }
-
-    override fun onResetCrossSigningKeys() {
-        AlertDialog.Builder(requireContext())
-                .setTitle(R.string.dialog_title_confirmation)
-                .setMessage(R.string.are_you_sure)
-                .setPositiveButton(R.string.ok) { _, _ ->
-                    viewModel.handle(CrossSigningAction.InitializeCrossSigning)
-                }
-                .show()
-    }
 }
diff --git a/vector/src/main/java/im/vector/riotx/features/settings/crosssigning/CrossSigningSettingsViewModel.kt b/vector/src/main/java/im/vector/riotx/features/settings/crosssigning/CrossSigningSettingsViewModel.kt
index f18e0b3cc7..24fc1bfdf8 100644
--- a/vector/src/main/java/im/vector/riotx/features/settings/crosssigning/CrossSigningSettingsViewModel.kt
+++ b/vector/src/main/java/im/vector/riotx/features/settings/crosssigning/CrossSigningSettingsViewModel.kt
@@ -22,14 +22,12 @@ import com.airbnb.mvrx.ViewModelContext
 import com.squareup.inject.assisted.Assisted
 import com.squareup.inject.assisted.AssistedInject
 import im.vector.matrix.android.api.MatrixCallback
-import im.vector.matrix.android.api.failure.Failure
+import im.vector.matrix.android.api.failure.toRegistrationFlowResponse
 import im.vector.matrix.android.api.session.Session
 import im.vector.matrix.android.api.session.crypto.crosssigning.MXCrossSigningInfo
 import im.vector.matrix.android.internal.auth.data.LoginFlowTypes
-import im.vector.matrix.android.internal.auth.registration.RegistrationFlowResponse
 import im.vector.matrix.android.internal.crypto.crosssigning.isVerified
 import im.vector.matrix.android.internal.crypto.model.rest.UserPasswordAuth
-import im.vector.matrix.android.internal.di.MoshiProvider
 import im.vector.matrix.rx.rx
 import im.vector.riotx.core.extensions.exhaustive
 import im.vector.riotx.core.platform.VectorViewModel
@@ -113,35 +111,26 @@ class CrossSigningSettingsViewModel @AssistedInject constructor(@Assisted privat
             override fun onFailure(failure: Throwable) {
                 _pendingSession = null
 
-                if (failure is Failure.OtherServerError && failure.httpCode == 401) {
-                    try {
-                        MoshiProvider.providesMoshi()
-                                .adapter(RegistrationFlowResponse::class.java)
-                                .fromJson(failure.errorBody)
-                    } catch (e: Exception) {
-                        null
-                    }?.let { flowResponse ->
-                        // Retry with authentication
-                        if (flowResponse.flows?.any { it.stages?.contains(LoginFlowTypes.PASSWORD) == true } == true) {
-                            _pendingSession = flowResponse.session ?: ""
-                            _viewEvents.post(CrossSigningSettingsViewEvents.RequestPassword)
-                            return
-                        } else {
-                            // can't do this from here
-                            _viewEvents.post(CrossSigningSettingsViewEvents.Failure(Throwable("You cannot do that from mobile")))
+                val registrationFlowResponse = failure.toRegistrationFlowResponse()
+                if (registrationFlowResponse != null) {
+                    // Retry with authentication
+                    if (registrationFlowResponse.flows?.any { it.stages?.contains(LoginFlowTypes.PASSWORD) == true } == true) {
+                        _pendingSession = registrationFlowResponse.session ?: ""
+                        _viewEvents.post(CrossSigningSettingsViewEvents.RequestPassword)
+                    } else {
+                        // can't do this from here
+                        _viewEvents.post(CrossSigningSettingsViewEvents.Failure(Throwable("You cannot do that from mobile")))
 
-                            setState {
-                                copy(isUploadingKeys = false)
-                            }
-                            return
+                        setState {
+                            copy(isUploadingKeys = false)
                         }
                     }
-                }
+                } else {
+                    _viewEvents.post(CrossSigningSettingsViewEvents.Failure(failure))
 
-                _viewEvents.post(CrossSigningSettingsViewEvents.Failure(failure))
-
-                setState {
-                    copy(isUploadingKeys = false)
+                    setState {
+                        copy(isUploadingKeys = false)
+                    }
                 }
             }
         })
diff --git a/vector/src/main/java/im/vector/riotx/features/settings/devices/DeviceItem.kt b/vector/src/main/java/im/vector/riotx/features/settings/devices/DeviceItem.kt
index b792afe666..5802bebf39 100644
--- a/vector/src/main/java/im/vector/riotx/features/settings/devices/DeviceItem.kt
+++ b/vector/src/main/java/im/vector/riotx/features/settings/devices/DeviceItem.kt
@@ -20,15 +20,17 @@ import android.graphics.Typeface
 import android.view.ViewGroup
 import android.widget.ImageView
 import android.widget.TextView
-import androidx.core.content.ContextCompat
-import androidx.core.view.isInvisible
 import androidx.core.view.isVisible
 import com.airbnb.epoxy.EpoxyAttribute
 import com.airbnb.epoxy.EpoxyModelClass
+import im.vector.matrix.android.internal.crypto.crosssigning.DeviceTrustLevel
 import im.vector.matrix.android.internal.crypto.model.rest.DeviceInfo
 import im.vector.riotx.R
 import im.vector.riotx.core.epoxy.VectorEpoxyHolder
 import im.vector.riotx.core.epoxy.VectorEpoxyModel
+import im.vector.riotx.core.resources.ColorProvider
+import im.vector.riotx.core.utils.DimensionConverter
+import me.gujun.android.span.span
 import java.text.DateFormat
 import java.text.SimpleDateFormat
 import java.util.Date
@@ -53,21 +55,37 @@ abstract class DeviceItem : VectorEpoxyModel<DeviceItem.Holder>() {
     var detailedMode = false
 
     @EpoxyAttribute
-    var trusted : Boolean? = null
+    var trusted: DeviceTrustLevel? = null
+
+    @EpoxyAttribute
+    var e2eCapable: Boolean = true
+
+    @EpoxyAttribute
+    var legacyMode: Boolean = false
+
+    @EpoxyAttribute
+    var trustedSession: Boolean = false
+
+    @EpoxyAttribute
+    var colorProvider: ColorProvider? = null
+
+    @EpoxyAttribute
+    var dimensionConverter: DimensionConverter? = null
 
     override fun bind(holder: Holder) {
         holder.root.setOnClickListener { itemClickAction?.invoke() }
 
-        if (trusted != null) {
-            holder.trustIcon.setImageDrawable(
-                    ContextCompat.getDrawable(
-                            holder.view.context,
-                            if (trusted!!) R.drawable.ic_shield_trusted else R.drawable.ic_shield_warning
-                    )
-            )
-            holder.trustIcon.isInvisible = false
+        val shield = TrustUtils.shieldForTrust(
+                currentDevice,
+                trustedSession,
+                legacyMode,
+                trusted
+        )
+
+        if (e2eCapable) {
+            holder.trustIcon.setImageResource(shield)
         } else {
-            holder.trustIcon.isInvisible = true
+            holder.trustIcon.setImageDrawable(null)
         }
 
         val detailedModeLabels = listOf(
@@ -103,7 +121,28 @@ abstract class DeviceItem : VectorEpoxyModel<DeviceItem.Holder>() {
                 it.setTypeface(null, if (currentDevice) Typeface.BOLD else Typeface.NORMAL)
             }
         } else {
-            holder.summaryLabelText.text = deviceInfo.displayName ?: deviceInfo.deviceId ?: ""
+            holder.summaryLabelText.text =
+                    span {
+                        +(deviceInfo.displayName ?: deviceInfo.deviceId ?: "")
+                        apply {
+                            // Add additional info if current session is not trusted
+                            if (!trustedSession) {
+                                +"\n"
+                                span {
+                                    text = "${deviceInfo.deviceId}"
+                                    apply {
+                                        colorProvider?.getColorFromAttribute(R.attr.riotx_text_secondary)?.let {
+                                            textColor = it
+                                        }
+                                        dimensionConverter?.spToPx(12)?.let {
+                                            textSize = it
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+
             holder.summaryLabelText.isVisible = true
             detailedModeLabels.map {
                 it.isVisible = false
diff --git a/vector/src/main/java/im/vector/riotx/features/settings/devices/DeviceVerificationInfoBottomSheetViewModel.kt b/vector/src/main/java/im/vector/riotx/features/settings/devices/DeviceVerificationInfoBottomSheetViewModel.kt
index 7ee79a279f..ac4c371448 100644
--- a/vector/src/main/java/im/vector/riotx/features/settings/devices/DeviceVerificationInfoBottomSheetViewModel.kt
+++ b/vector/src/main/java/im/vector/riotx/features/settings/devices/DeviceVerificationInfoBottomSheetViewModel.kt
@@ -16,17 +16,14 @@
 package im.vector.riotx.features.settings.devices
 
 import com.airbnb.mvrx.Async
-import com.airbnb.mvrx.Fail
 import com.airbnb.mvrx.FragmentViewModelContext
 import com.airbnb.mvrx.Loading
 import com.airbnb.mvrx.MvRxState
 import com.airbnb.mvrx.MvRxViewModelFactory
-import com.airbnb.mvrx.Success
 import com.airbnb.mvrx.Uninitialized
 import com.airbnb.mvrx.ViewModelContext
 import com.squareup.inject.assisted.Assisted
 import com.squareup.inject.assisted.AssistedInject
-import im.vector.matrix.android.api.MatrixCallback
 import im.vector.matrix.android.api.session.Session
 import im.vector.matrix.android.internal.crypto.model.CryptoDeviceInfo
 import im.vector.matrix.android.internal.crypto.model.rest.DeviceInfo
@@ -37,7 +34,10 @@ import im.vector.riotx.core.platform.VectorViewModel
 
 data class DeviceVerificationInfoBottomSheetViewState(
         val cryptoDeviceInfo: Async<CryptoDeviceInfo?> = Uninitialized,
-        val deviceInfo: Async<DeviceInfo> = Uninitialized
+        val deviceInfo: Async<DeviceInfo> = Uninitialized,
+        val hasAccountCrossSigning: Boolean = false,
+        val accountCrossSigningIsTrusted: Boolean = false,
+        val isMine: Boolean = false
 ) : MvRxState
 
 class DeviceVerificationInfoBottomSheetViewModel @AssistedInject constructor(@Assisted initialState: DeviceVerificationInfoBottomSheetViewState,
@@ -51,31 +51,43 @@ class DeviceVerificationInfoBottomSheetViewModel @AssistedInject constructor(@As
     }
 
     init {
+
+        setState {
+            copy(
+                    hasAccountCrossSigning = session.cryptoService().crossSigningService().getMyCrossSigningKeys() != null,
+                    accountCrossSigningIsTrusted = session.cryptoService().crossSigningService().isCrossSigningVerified()
+            )
+        }
+        session.rx().liveCrossSigningInfo(session.myUserId)
+                .execute {
+                    copy(
+                            hasAccountCrossSigning = it.invoke()?.getOrNull() != null,
+                            accountCrossSigningIsTrusted = it.invoke()?.getOrNull()?.isTrusted() == true
+                    )
+                }
+
         session.rx().liveUserCryptoDevices(session.myUserId)
                 .map { list ->
                     list.firstOrNull { it.deviceId == deviceId }
                 }
                 .execute {
                     copy(
-                            cryptoDeviceInfo = it
+                            cryptoDeviceInfo = it,
+                            isMine = it.invoke()?.deviceId == session.sessionParams.credentials.deviceId
                     )
                 }
+
         setState {
             copy(deviceInfo = Loading())
         }
-        session.cryptoService().getDeviceInfo(deviceId, object : MatrixCallback<DeviceInfo> {
-            override fun onSuccess(data: DeviceInfo) {
-                setState {
-                    copy(deviceInfo = Success(data))
-                }
-            }
 
-            override fun onFailure(failure: Throwable) {
-                setState {
-                    copy(deviceInfo = Fail(failure))
+        session.rx().liveMyDeviceInfo()
+                .map { devices ->
+                    devices.firstOrNull { it.deviceId == deviceId } ?: DeviceInfo(deviceId = deviceId)
+                }
+                .execute {
+                    copy(deviceInfo = it)
                 }
-            }
-        })
     }
 
     companion object : MvRxViewModelFactory<DeviceVerificationInfoBottomSheetViewModel, DeviceVerificationInfoBottomSheetViewState> {
diff --git a/vector/src/main/java/im/vector/riotx/features/settings/devices/DeviceVerificationInfoEpoxyController.kt b/vector/src/main/java/im/vector/riotx/features/settings/devices/DeviceVerificationInfoEpoxyController.kt
index 90724166a0..4123e260e2 100644
--- a/vector/src/main/java/im/vector/riotx/features/settings/devices/DeviceVerificationInfoEpoxyController.kt
+++ b/vector/src/main/java/im/vector/riotx/features/settings/devices/DeviceVerificationInfoEpoxyController.kt
@@ -16,7 +16,9 @@
 package im.vector.riotx.features.settings.devices
 
 import com.airbnb.epoxy.TypedEpoxyController
+import im.vector.matrix.android.api.extensions.orFalse
 import im.vector.matrix.android.api.session.Session
+import im.vector.matrix.android.internal.crypto.model.CryptoDeviceInfo
 import im.vector.riotx.R
 import im.vector.riotx.core.epoxy.dividerItem
 import im.vector.riotx.core.epoxy.loadingItem
@@ -26,6 +28,7 @@ import im.vector.riotx.core.ui.list.GenericItem
 import im.vector.riotx.core.ui.list.genericFooterItem
 import im.vector.riotx.core.ui.list.genericItem
 import im.vector.riotx.features.crypto.verification.epoxy.bottomSheetVerificationActionItem
+import timber.log.Timber
 import javax.inject.Inject
 
 class DeviceVerificationInfoEpoxyController @Inject constructor(private val stringProvider: StringProvider,
@@ -37,111 +40,251 @@ class DeviceVerificationInfoEpoxyController @Inject constructor(private val stri
 
     override fun buildModels(data: DeviceVerificationInfoBottomSheetViewState?) {
         val cryptoDeviceInfo = data?.cryptoDeviceInfo?.invoke()
-        if (cryptoDeviceInfo != null) {
-            if (cryptoDeviceInfo.isVerified) {
+        when {
+            cryptoDeviceInfo != null           -> {
+                // It's a E2E capable device
+                handleE2ECapableDevice(data, cryptoDeviceInfo)
+            }
+            data?.deviceInfo?.invoke() != null -> {
+                // It's a non E2E capable device
+                handleNonE2EDevice(data)
+            }
+            else                               -> {
+                loadingItem {
+                    id("loading")
+                }
+            }
+        }
+    }
+
+    private fun handleE2ECapableDevice(data: DeviceVerificationInfoBottomSheetViewState, cryptoDeviceInfo: CryptoDeviceInfo) {
+        val shield = TrustUtils.shieldForTrust(
+                currentDevice = data.isMine,
+                trustMSK = data.accountCrossSigningIsTrusted,
+                legacyMode = !data.hasAccountCrossSigning,
+                deviceTrustLevel = cryptoDeviceInfo.trustLevel
+        )
+
+        if (data.hasAccountCrossSigning) {
+            // Cross Signing is enabled
+            handleE2EWithCrossSigning(data.isMine, data.accountCrossSigningIsTrusted, cryptoDeviceInfo, shield)
+        } else {
+            handleE2EInLegacy(data.isMine, cryptoDeviceInfo, shield)
+        }
+
+        // COMMON ACTIONS (Rename / signout)
+        addGenericDeviceManageActions(data, cryptoDeviceInfo.deviceId)
+    }
+
+    private fun handleE2EWithCrossSigning(isMine: Boolean, currentSessionIsTrusted: Boolean, cryptoDeviceInfo: CryptoDeviceInfo, shield: Int) {
+        Timber.v("handleE2EWithCrossSigning $isMine, $cryptoDeviceInfo, $shield")
+
+        if (isMine) {
+            if (currentSessionIsTrusted) {
                 genericItem {
                     id("trust${cryptoDeviceInfo.deviceId}")
                     style(GenericItem.STYLE.BIG_TEXT)
-                    titleIconResourceId(R.drawable.ic_shield_trusted)
+                    titleIconResourceId(shield)
                     title(stringProvider.getString(R.string.encryption_information_verified))
                     description(stringProvider.getString(R.string.settings_active_sessions_verified_device_desc))
                 }
             } else {
+                // You need tomcomplete security
                 genericItem {
                     id("trust${cryptoDeviceInfo.deviceId}")
-                    titleIconResourceId(R.drawable.ic_shield_warning)
                     style(GenericItem.STYLE.BIG_TEXT)
-                    title(stringProvider.getString(R.string.encryption_information_not_verified))
-                    description(stringProvider.getString(R.string.settings_active_sessions_unverified_device_desc))
-                }
-            }
-
-            genericItem {
-                id("info${cryptoDeviceInfo.deviceId}")
-                title(cryptoDeviceInfo.displayName() ?: "")
-                description("(${cryptoDeviceInfo.deviceId})")
-            }
-
-            if (!cryptoDeviceInfo.isVerified) {
-                dividerItem {
-                    id("d1")
-                }
-                bottomSheetVerificationActionItem {
-                    id("verify")
-                    title(stringProvider.getString(R.string.verification_verify_device))
-                    titleColor(colorProvider.getColor(R.color.riotx_accent))
-                    iconRes(R.drawable.ic_arrow_right)
-                    iconColor(colorProvider.getColor(R.color.riotx_accent))
-                    listener {
-                        callback?.onAction(DevicesAction.VerifyMyDevice(cryptoDeviceInfo.deviceId))
-                    }
-                }
-            }
-
-            if (cryptoDeviceInfo.deviceId != session.sessionParams.credentials.deviceId) {
-                // Add the delete option
-                dividerItem {
-                    id("d2")
-                }
-                bottomSheetVerificationActionItem {
-                    id("delete")
-                    title(stringProvider.getString(R.string.settings_active_sessions_signout_device))
-                    titleColor(colorProvider.getColor(R.color.riotx_destructive_accent))
-                    iconRes(R.drawable.ic_arrow_right)
-                    iconColor(colorProvider.getColor(R.color.riotx_destructive_accent))
-                    listener {
-                        callback?.onAction(DevicesAction.Delete(cryptoDeviceInfo.deviceId))
-                    }
-                }
-            }
-
-            dividerItem {
-                id("d3")
-            }
-            bottomSheetVerificationActionItem {
-                id("rename")
-                title(stringProvider.getString(R.string.rename))
-                titleColor(colorProvider.getColorFromAttribute(R.attr.riotx_text_primary))
-                iconRes(R.drawable.ic_arrow_right)
-                iconColor(colorProvider.getColorFromAttribute(R.attr.riotx_text_primary))
-                listener {
-                    callback?.onAction(DevicesAction.PromptRename(cryptoDeviceInfo.deviceId))
-                }
-            }
-        } else if (data?.deviceInfo?.invoke() != null) {
-            val info = data.deviceInfo.invoke()
-            genericItem {
-                id("info${info?.deviceId}")
-                title(info?.displayName ?: "")
-                description("(${info?.deviceId})")
-            }
-
-            genericFooterItem {
-                id("infoCrypto${info?.deviceId}")
-                text(stringProvider.getString(R.string.settings_failed_to_get_crypto_device_info))
-            }
-
-            if (info?.deviceId != session.sessionParams.credentials.deviceId) {
-                // Add the delete option
-                dividerItem {
-                    id("d2")
-                }
-                bottomSheetVerificationActionItem {
-                    id("delete")
-                    title(stringProvider.getString(R.string.settings_active_sessions_signout_device))
-                    titleColor(colorProvider.getColor(R.color.riotx_destructive_accent))
-                    iconRes(R.drawable.ic_arrow_right)
-                    iconColor(colorProvider.getColor(R.color.riotx_destructive_accent))
-                    listener {
-                        callback?.onAction(DevicesAction.Delete(info?.deviceId ?: ""))
-                    }
+                    titleIconResourceId(shield)
+                    title(stringProvider.getString(R.string.crosssigning_verify_this_session))
+                    description(stringProvider.getString(R.string.confirm_your_identity))
                 }
             }
         } else {
-            loadingItem {
-                id("loading")
+            if (!currentSessionIsTrusted) {
+                // we don't know if this session is trusted...
+                // for now we show nothing?
+            } else {
+                // we rely on cross signing status
+                val trust = cryptoDeviceInfo.trustLevel?.isCrossSigningVerified() == true
+                if (trust) {
+                    genericItem {
+                        id("trust${cryptoDeviceInfo.deviceId}")
+                        style(GenericItem.STYLE.BIG_TEXT)
+                        titleIconResourceId(shield)
+                        title(stringProvider.getString(R.string.encryption_information_verified))
+                        description(stringProvider.getString(R.string.settings_active_sessions_verified_device_desc))
+                    }
+                } else {
+                    genericItem {
+                        id("trust${cryptoDeviceInfo.deviceId}")
+                        titleIconResourceId(shield)
+                        style(GenericItem.STYLE.BIG_TEXT)
+                        title(stringProvider.getString(R.string.encryption_information_not_verified))
+                        description(stringProvider.getString(R.string.settings_active_sessions_unverified_device_desc))
+                    }
+                }
             }
         }
+
+        // DEVICE INFO SECTION
+        genericItem {
+            id("info${cryptoDeviceInfo.deviceId}")
+            title(cryptoDeviceInfo.displayName() ?: "")
+            description("(${cryptoDeviceInfo.deviceId})")
+        }
+
+        if (isMine && !currentSessionIsTrusted) {
+            // Add complete security
+            dividerItem {
+                id("completeSecurityDiv")
+            }
+            bottomSheetVerificationActionItem {
+                id("completeSecurity")
+                title(stringProvider.getString(R.string.crosssigning_verify_this_session))
+                titleColor(colorProvider.getColor(R.color.riotx_accent))
+                iconRes(R.drawable.ic_arrow_right)
+                iconColor(colorProvider.getColor(R.color.riotx_accent))
+                listener {
+                    callback?.onAction(DevicesAction.CompleteSecurity)
+                }
+            }
+        } else if (!isMine) {
+            if (currentSessionIsTrusted) {
+                // we can propose to verify it
+                val isVerified = cryptoDeviceInfo.trustLevel?.crossSigningVerified.orFalse()
+                if (!isVerified) {
+                    addVerifyActions(cryptoDeviceInfo)
+                }
+            }
+        }
+    }
+
+    private fun handleE2EInLegacy(isMine: Boolean, cryptoDeviceInfo: CryptoDeviceInfo, shield: Int) {
+        // ==== Legacy
+
+        // TRUST INFO SECTION
+        if (cryptoDeviceInfo.trustLevel?.isLocallyVerified() == true) {
+            genericItem {
+                id("trust${cryptoDeviceInfo.deviceId}")
+                style(GenericItem.STYLE.BIG_TEXT)
+                titleIconResourceId(shield)
+                title(stringProvider.getString(R.string.encryption_information_verified))
+                description(stringProvider.getString(R.string.settings_active_sessions_verified_device_desc))
+            }
+        } else {
+            genericItem {
+                id("trust${cryptoDeviceInfo.deviceId}")
+                titleIconResourceId(shield)
+                style(GenericItem.STYLE.BIG_TEXT)
+                title(stringProvider.getString(R.string.encryption_information_not_verified))
+                description(stringProvider.getString(R.string.settings_active_sessions_unverified_device_desc))
+            }
+        }
+
+        // DEVICE INFO SECTION
+        genericItem {
+            id("info${cryptoDeviceInfo.deviceId}")
+            title(cryptoDeviceInfo.displayName() ?: "")
+            description("(${cryptoDeviceInfo.deviceId})")
+        }
+
+        // ACTIONS
+
+        if (!isMine) {
+            // if it's not the current device you can trigger a verification
+            dividerItem {
+                id("d1")
+            }
+            bottomSheetVerificationActionItem {
+                id("verify${cryptoDeviceInfo.deviceId}")
+                title(stringProvider.getString(R.string.verification_verify_device))
+                titleColor(colorProvider.getColor(R.color.riotx_accent))
+                iconRes(R.drawable.ic_arrow_right)
+                iconColor(colorProvider.getColor(R.color.riotx_accent))
+                listener {
+                    callback?.onAction(DevicesAction.VerifyMyDevice(cryptoDeviceInfo.deviceId))
+                }
+            }
+        }
+    }
+
+    private fun addVerifyActions(cryptoDeviceInfo: CryptoDeviceInfo) {
+        dividerItem {
+            id("verifyDiv")
+        }
+        bottomSheetVerificationActionItem {
+            id("verify_text")
+            title(stringProvider.getString(R.string.cross_signing_verify_by_text))
+            titleColor(colorProvider.getColor(R.color.riotx_accent))
+            iconRes(R.drawable.ic_arrow_right)
+            iconColor(colorProvider.getColor(R.color.riotx_accent))
+            listener {
+                callback?.onAction(DevicesAction.VerifyMyDeviceManually(cryptoDeviceInfo.deviceId))
+            }
+        }
+        dividerItem {
+            id("verifyDiv2")
+        }
+        bottomSheetVerificationActionItem {
+            id("verify_emoji")
+            title(stringProvider.getString(R.string.cross_signing_verify_by_emoji))
+            titleColor(colorProvider.getColor(R.color.riotx_accent))
+            iconRes(R.drawable.ic_arrow_right)
+            iconColor(colorProvider.getColor(R.color.riotx_accent))
+            listener {
+                callback?.onAction(DevicesAction.VerifyMyDevice(cryptoDeviceInfo.deviceId))
+            }
+        }
+    }
+
+    private fun addGenericDeviceManageActions(data: DeviceVerificationInfoBottomSheetViewState, deviceId: String) {
+        // Offer delete session if not me
+        if (!data.isMine) {
+            // Add the delete option
+            dividerItem {
+                id("manageD1")
+            }
+            bottomSheetVerificationActionItem {
+                id("delete")
+                title(stringProvider.getString(R.string.settings_active_sessions_signout_device))
+                titleColor(colorProvider.getColor(R.color.riotx_destructive_accent))
+                iconRes(R.drawable.ic_arrow_right)
+                iconColor(colorProvider.getColor(R.color.riotx_destructive_accent))
+                listener {
+                    callback?.onAction(DevicesAction.Delete(deviceId))
+                }
+            }
+        }
+
+        // Always offer rename
+        dividerItem {
+            id("manageD2")
+        }
+        bottomSheetVerificationActionItem {
+            id("rename")
+            title(stringProvider.getString(R.string.rename))
+            titleColor(colorProvider.getColorFromAttribute(R.attr.riotx_text_primary))
+            iconRes(R.drawable.ic_arrow_right)
+            iconColor(colorProvider.getColorFromAttribute(R.attr.riotx_text_primary))
+            listener {
+                callback?.onAction(DevicesAction.PromptRename(deviceId))
+            }
+        }
+    }
+
+    private fun handleNonE2EDevice(data: DeviceVerificationInfoBottomSheetViewState) {
+        val info = data.deviceInfo.invoke() ?: return
+        genericItem {
+            id("info${info.deviceId}")
+            title(info.displayName ?: "")
+            description("(${info.deviceId})")
+        }
+
+        genericFooterItem {
+            id("infoCrypto${info.deviceId}")
+            text(stringProvider.getString(R.string.settings_failed_to_get_crypto_device_info))
+        }
+
+        info.deviceId?.let { addGenericDeviceManageActions(data, it) }
     }
 
     interface Callback {
diff --git a/vector/src/main/java/im/vector/riotx/features/settings/devices/DevicesAction.kt b/vector/src/main/java/im/vector/riotx/features/settings/devices/DevicesAction.kt
index e4b1b98cc8..854f5ea895 100644
--- a/vector/src/main/java/im/vector/riotx/features/settings/devices/DevicesAction.kt
+++ b/vector/src/main/java/im/vector/riotx/features/settings/devices/DevicesAction.kt
@@ -16,14 +16,18 @@
 
 package im.vector.riotx.features.settings.devices
 
+import im.vector.matrix.android.internal.crypto.model.CryptoDeviceInfo
 import im.vector.riotx.core.platform.VectorViewModelAction
 
 sealed class DevicesAction : VectorViewModelAction {
-    object Retry : DevicesAction()
+    object Refresh : DevicesAction()
     data class Delete(val deviceId: String) : DevicesAction()
     data class Password(val password: String) : DevicesAction()
     data class Rename(val deviceId: String, val newName: String) : DevicesAction()
 
     data class PromptRename(val deviceId: String) : DevicesAction()
     data class VerifyMyDevice(val deviceId: String) : DevicesAction()
+    data class VerifyMyDeviceManually(val deviceId: String) : DevicesAction()
+    object CompleteSecurity : DevicesAction()
+    data class MarkAsManuallyVerified(val cryptoDeviceInfo: CryptoDeviceInfo) : DevicesAction()
 }
diff --git a/vector/src/main/java/im/vector/riotx/features/settings/devices/DevicesController.kt b/vector/src/main/java/im/vector/riotx/features/settings/devices/DevicesController.kt
index 1d275c7da2..1b08f23996 100644
--- a/vector/src/main/java/im/vector/riotx/features/settings/devices/DevicesController.kt
+++ b/vector/src/main/java/im/vector/riotx/features/settings/devices/DevicesController.kt
@@ -21,20 +21,23 @@ import com.airbnb.mvrx.Fail
 import com.airbnb.mvrx.Loading
 import com.airbnb.mvrx.Success
 import com.airbnb.mvrx.Uninitialized
-import im.vector.matrix.android.api.extensions.sortByLastSeen
-import im.vector.matrix.android.internal.crypto.model.CryptoDeviceInfo
+import im.vector.matrix.android.internal.crypto.crosssigning.DeviceTrustLevel
 import im.vector.matrix.android.internal.crypto.model.rest.DeviceInfo
 import im.vector.riotx.R
 import im.vector.riotx.core.epoxy.errorWithRetryItem
 import im.vector.riotx.core.epoxy.loadingItem
 import im.vector.riotx.core.error.ErrorFormatter
+import im.vector.riotx.core.resources.ColorProvider
 import im.vector.riotx.core.resources.StringProvider
 import im.vector.riotx.core.ui.list.genericItemHeader
+import im.vector.riotx.core.utils.DimensionConverter
 import im.vector.riotx.features.settings.VectorPreferences
 import javax.inject.Inject
 
 class DevicesController @Inject constructor(private val errorFormatter: ErrorFormatter,
                                             private val stringProvider: StringProvider,
+                                            private val colorProvider: ColorProvider,
+                                            private val dimensionConverter: DimensionConverter,
                                             private val vectorPreferences: VectorPreferences) : EpoxyController() {
 
     var callback: Callback? = null
@@ -68,30 +71,51 @@ class DevicesController @Inject constructor(private val errorFormatter: ErrorFor
                     listener { callback?.retry() }
                 }
             is Success       ->
-                buildDevicesList(devices(), state.cryptoDevices(), state.myDeviceId)
+                buildDevicesList(devices(), state.myDeviceId, !state.hasAccountCrossSigning, state.accountCrossSigningIsTrusted)
         }
     }
 
-    private fun buildDevicesList(devices: List<DeviceInfo>, cryptoDevices: List<CryptoDeviceInfo>?, myDeviceId: String) {
-        // Current device
-        genericItemHeader {
-            id("current")
-            text(stringProvider.getString(R.string.devices_current_device))
-        }
-
+    private fun buildDevicesList(devices: List<DeviceFullInfo>,
+                                 myDeviceId: String,
+                                 legacyMode: Boolean,
+                                 currentSessionCrossTrusted: Boolean) {
         devices
-                .filter {
-                    it.deviceId == myDeviceId
-                }
-                .forEachIndexed { idx, deviceInfo ->
+                .firstOrNull {
+                    it.deviceInfo.deviceId == myDeviceId
+                }?.let { fullInfo ->
+                    val deviceInfo = fullInfo.deviceInfo
+                    // Current device
+                    genericItemHeader {
+                        id("current")
+                        text(stringProvider.getString(R.string.devices_current_device))
+                    }
+
                     deviceItem {
-                        id("myDevice$idx")
+                        id("myDevice${deviceInfo.deviceId}")
+                        legacyMode(legacyMode)
+                        trustedSession(currentSessionCrossTrusted)
+                        dimensionConverter(dimensionConverter)
+                        colorProvider(colorProvider)
                         detailedMode(vectorPreferences.developerMode())
                         deviceInfo(deviceInfo)
                         currentDevice(true)
+                        e2eCapable(true)
                         itemClickAction { callback?.onDeviceClicked(deviceInfo) }
-                        trusted(true)
+                        trusted(DeviceTrustLevel(currentSessionCrossTrusted, true))
                     }
+
+//                    // If cross signing enabled and this session not trusted, add short cut to complete security
+                    // NEED DESIGN
+//                    if (!legacyMode && !currentSessionCrossTrusted) {
+//                        genericButtonItem {
+//                            id("complete_security")
+//                            iconRes(R.drawable.ic_shield_warning)
+//                            text(stringProvider.getString(R.string.complete_security))
+//                            itemClickAction(DebouncedClickListener(View.OnClickListener { _ ->
+//                                callback?.completeSecurity()
+//                            }))
+//                        }
+//                    }
                 }
 
         // Other devices
@@ -103,19 +127,23 @@ class DevicesController @Inject constructor(private val errorFormatter: ErrorFor
 
             devices
                     .filter {
-                        it.deviceId != myDeviceId
+                        it.deviceInfo.deviceId != myDeviceId
                     }
-                    // sort before display: most recent first
-                    .sortByLastSeen()
-                    .forEachIndexed { idx, deviceInfo ->
-                        val isCurrentDevice = deviceInfo.deviceId == myDeviceId
+                    .forEachIndexed { idx, deviceInfoPair ->
+                        val deviceInfo = deviceInfoPair.deviceInfo
+                        val cryptoInfo = deviceInfoPair.cryptoDeviceInfo
                         deviceItem {
                             id("device$idx")
+                            legacyMode(legacyMode)
+                            trustedSession(currentSessionCrossTrusted)
+                            dimensionConverter(dimensionConverter)
+                            colorProvider(colorProvider)
                             detailedMode(vectorPreferences.developerMode())
                             deviceInfo(deviceInfo)
-                            currentDevice(isCurrentDevice)
+                            currentDevice(false)
                             itemClickAction { callback?.onDeviceClicked(deviceInfo) }
-                            trusted(cryptoDevices?.firstOrNull { it.deviceId == deviceInfo.deviceId }?.isVerified)
+                            e2eCapable(cryptoInfo != null)
+                            trusted(cryptoInfo?.trustLevel)
                         }
                     }
         }
diff --git a/vector/src/main/java/im/vector/riotx/features/settings/devices/DevicesViewEvents.kt b/vector/src/main/java/im/vector/riotx/features/settings/devices/DevicesViewEvents.kt
index 075eb2050e..2cbdbe9485 100644
--- a/vector/src/main/java/im/vector/riotx/features/settings/devices/DevicesViewEvents.kt
+++ b/vector/src/main/java/im/vector/riotx/features/settings/devices/DevicesViewEvents.kt
@@ -17,6 +17,8 @@
 
 package im.vector.riotx.features.settings.devices
 
+import im.vector.matrix.android.api.session.Session
+import im.vector.matrix.android.internal.crypto.model.CryptoDeviceInfo
 import im.vector.matrix.android.internal.crypto.model.rest.DeviceInfo
 import im.vector.riotx.core.platform.VectorViewEvents
 
@@ -35,4 +37,10 @@ sealed class DevicesViewEvents : VectorViewEvents {
             val userId: String,
             val transactionId: String?
     ) : DevicesViewEvents()
+
+    data class SelfVerification(
+            val session: Session
+    ) : DevicesViewEvents()
+
+    data class ShowManuallyVerify(val cryptoDeviceInfo: CryptoDeviceInfo) : DevicesViewEvents()
 }
diff --git a/vector/src/main/java/im/vector/riotx/features/settings/devices/DevicesViewModel.kt b/vector/src/main/java/im/vector/riotx/features/settings/devices/DevicesViewModel.kt
index 79a5fe84aa..cd5e53b7c3 100644
--- a/vector/src/main/java/im/vector/riotx/features/settings/devices/DevicesViewModel.kt
+++ b/vector/src/main/java/im/vector/riotx/features/settings/devices/DevicesViewModel.kt
@@ -16,6 +16,7 @@
 
 package im.vector.riotx.features.settings.devices
 
+import androidx.lifecycle.viewModelScope
 import com.airbnb.mvrx.Async
 import com.airbnb.mvrx.Fail
 import com.airbnb.mvrx.FragmentViewModelContext
@@ -28,33 +29,46 @@ import com.airbnb.mvrx.ViewModelContext
 import com.squareup.inject.assisted.Assisted
 import com.squareup.inject.assisted.AssistedInject
 import im.vector.matrix.android.api.MatrixCallback
+import im.vector.matrix.android.api.NoOpMatrixCallback
+import im.vector.matrix.android.api.extensions.tryThis
 import im.vector.matrix.android.api.failure.Failure
 import im.vector.matrix.android.api.session.Session
+import im.vector.matrix.android.api.session.crypto.verification.VerificationMethod
 import im.vector.matrix.android.api.session.crypto.verification.VerificationService
 import im.vector.matrix.android.api.session.crypto.verification.VerificationTransaction
 import im.vector.matrix.android.api.session.crypto.verification.VerificationTxState
 import im.vector.matrix.android.internal.auth.data.LoginFlowTypes
+import im.vector.matrix.android.internal.crypto.crosssigning.DeviceTrustLevel
 import im.vector.matrix.android.internal.crypto.model.CryptoDeviceInfo
-import im.vector.matrix.android.internal.crypto.model.MXUsersDevicesMap
 import im.vector.matrix.android.internal.crypto.model.rest.DeviceInfo
-import im.vector.matrix.android.internal.crypto.model.rest.DevicesListResponse
+import im.vector.matrix.android.internal.util.awaitCallback
 import im.vector.matrix.rx.rx
 import im.vector.riotx.core.platform.VectorViewModel
-import im.vector.riotx.features.crypto.verification.SupportedVerificationMethodsProvider
+import io.reactivex.Observable
+import io.reactivex.functions.BiFunction
+import io.reactivex.subjects.PublishSubject
+import kotlinx.coroutines.launch
+import java.util.concurrent.TimeUnit
 
 data class DevicesViewState(
         val myDeviceId: String = "",
-        val devices: Async<List<DeviceInfo>> = Uninitialized,
-        val cryptoDevices: Async<List<CryptoDeviceInfo>> = Uninitialized,
+//        val devices: Async<List<DeviceInfo>> = Uninitialized,
+//        val cryptoDevices: Async<List<CryptoDeviceInfo>> = Uninitialized,
+        val devices: Async<List<DeviceFullInfo>> = Uninitialized,
         // TODO Replace by isLoading boolean
-        val request: Async<Unit> = Uninitialized
+        val request: Async<Unit> = Uninitialized,
+        val hasAccountCrossSigning: Boolean = false,
+        val accountCrossSigningIsTrusted: Boolean = false
 ) : MvRxState
 
+data class DeviceFullInfo(
+        val deviceInfo: DeviceInfo,
+        val cryptoDeviceInfo: CryptoDeviceInfo?
+)
 class DevicesViewModel @AssistedInject constructor(
         @Assisted initialState: DevicesViewState,
-        private val session: Session,
-        private val supportedVerificationMethodsProvider: SupportedVerificationMethodsProvider)
-    : VectorViewModel<DevicesViewState, DevicesAction, DevicesViewEvents>(initialState), VerificationService.Listener {
+        private val session: Session
+) : VectorViewModel<DevicesViewState, DevicesAction, DevicesViewEvents>(initialState), VerificationService.Listener {
 
     @AssistedInject.Factory
     interface Factory {
@@ -74,16 +88,76 @@ class DevicesViewModel @AssistedInject constructor(
     private var _currentDeviceId: String? = null
     private var _currentSession: String? = null
 
-    init {
-        refreshDevicesList()
-        session.cryptoService().verificationService().addListener(this)
+    private val refreshPublisher: PublishSubject<Unit> = PublishSubject.create()
 
-        session.rx().liveUserCryptoDevices(session.myUserId)
-                .execute {
+    init {
+
+        setState {
+            copy(
+                    hasAccountCrossSigning = session.cryptoService().crossSigningService().getMyCrossSigningKeys() != null,
+                    accountCrossSigningIsTrusted = session.cryptoService().crossSigningService().isCrossSigningVerified(),
+                    myDeviceId = session.sessionParams.credentials.deviceId ?: ""
+            )
+        }
+
+        Observable.combineLatest<List<CryptoDeviceInfo>, List<DeviceInfo>, List<DeviceFullInfo>>(
+                session.rx().liveUserCryptoDevices(session.myUserId),
+                session.rx().liveMyDeviceInfo(),
+                BiFunction { cryptoList, infoList ->
+                    infoList
+                            .sortedByDescending { it.lastSeenTs }
+                            .map { deviceInfo ->
+                                val cryptoDeviceInfo = cryptoList.firstOrNull { it.deviceId == deviceInfo.deviceId }
+                                DeviceFullInfo(deviceInfo, cryptoDeviceInfo)
+                            }
+                }
+        )
+                .distinct()
+                .execute { async ->
                     copy(
-                            cryptoDevices = it
+                            devices = async
                     )
                 }
+
+        session.rx().liveCrossSigningInfo(session.myUserId)
+                .execute {
+                    copy(
+                            hasAccountCrossSigning = it.invoke()?.getOrNull() != null,
+                            accountCrossSigningIsTrusted = it.invoke()?.getOrNull()?.isTrusted() == true
+                    )
+                }
+        session.cryptoService().verificationService().addListener(this)
+
+//        session.rx().liveMyDeviceInfo()
+//                .execute {
+//                    copy(
+//                            devices = it
+//                    )
+//                }
+
+        session.rx().liveUserCryptoDevices(session.myUserId)
+                .distinct()
+                .throttleLast(5_000, TimeUnit.MILLISECONDS)
+                .subscribe {
+                    // If we have a new crypto device change, we might want to trigger refresh of device info
+                    session.cryptoService().fetchDevicesList(NoOpMatrixCallback())
+                }.disposeOnClear()
+
+//        session.rx().liveUserCryptoDevices(session.myUserId)
+//                .execute {
+//                    copy(
+//                            cryptoDevices = it
+//                    )
+//                }
+
+        refreshPublisher.throttleFirst(4_000, TimeUnit.MILLISECONDS)
+                .subscribe {
+                    session.cryptoService().fetchDevicesList(NoOpMatrixCallback())
+                    session.cryptoService().downloadKeys(listOf(session.myUserId), true, NoOpMatrixCallback())
+                }
+                .disposeOnClear()
+        // then force download
+        queryRefreshDevicesList()
     }
 
     override fun onCleared() {
@@ -93,7 +167,7 @@ class DevicesViewModel @AssistedInject constructor(
 
     override fun transactionUpdated(tx: VerificationTransaction) {
         if (tx.state == VerificationTxState.Verified) {
-            refreshDevicesList()
+            queryRefreshDevicesList()
         }
     }
 
@@ -102,91 +176,66 @@ class DevicesViewModel @AssistedInject constructor(
      * The devices list is the list of the devices where the user is logged in.
      * It can be any mobile devices, and any browsers.
      */
-    private fun refreshDevicesList() {
-        if (!session.sessionParams.credentials.deviceId.isNullOrEmpty()) {
-            // display something asap
-            val localKnown = session.cryptoService().getUserDevices(session.myUserId).map {
-                DeviceInfo(
-                        user_id = session.myUserId,
-                        deviceId = it.deviceId,
-                        displayName = it.displayName()
-                )
-            }
-
-            setState {
-                copy(
-                        // Keep known list if we have it, and let refresh go in backgroung
-                        devices = this.devices.takeIf { it is Success } ?: Success(localKnown)
-                )
-            }
-
-            session.cryptoService().getDevicesList(object : MatrixCallback<DevicesListResponse> {
-                override fun onSuccess(data: DevicesListResponse) {
-                    setState {
-                        copy(
-                                myDeviceId = session.sessionParams.credentials.deviceId ?: "",
-                                devices = Success(data.devices.orEmpty())
-                        )
-                    }
-                }
-
-                override fun onFailure(failure: Throwable) {
-                    setState {
-                        copy(
-                                devices = Fail(failure)
-                        )
-                    }
-                }
-            })
-
-            // Put cached state
-            setState {
-                copy(
-                        myDeviceId = session.sessionParams.credentials.deviceId ?: "",
-                        cryptoDevices = Success(session.cryptoService().getUserDevices(session.myUserId))
-                )
-            }
-
-            // then force download
-            session.cryptoService().downloadKeys(listOf(session.myUserId), true, object : MatrixCallback<MXUsersDevicesMap<CryptoDeviceInfo>> {
-                override fun onSuccess(data: MXUsersDevicesMap<CryptoDeviceInfo>) {
-                    setState {
-                        copy(
-                                cryptoDevices = Success(session.cryptoService().getUserDevices(session.myUserId))
-                        )
-                    }
-                }
-            })
-        } else {
-            // Should not happen
-        }
+    private fun queryRefreshDevicesList() {
+        refreshPublisher.onNext(Unit)
     }
 
     override fun handle(action: DevicesAction) {
         return when (action) {
-            is DevicesAction.Retry          -> refreshDevicesList()
-            is DevicesAction.Delete         -> handleDelete(action)
-            is DevicesAction.Password       -> handlePassword(action)
-            is DevicesAction.Rename         -> handleRename(action)
-            is DevicesAction.PromptRename   -> handlePromptRename(action)
-            is DevicesAction.VerifyMyDevice -> handleVerify(action)
+            is DevicesAction.Refresh                -> queryRefreshDevicesList()
+            is DevicesAction.Delete                 -> handleDelete(action)
+            is DevicesAction.Password               -> handlePassword(action)
+            is DevicesAction.Rename                 -> handleRename(action)
+            is DevicesAction.PromptRename           -> handlePromptRename(action)
+            is DevicesAction.VerifyMyDevice         -> handleInteractiveVerification(action)
+            is DevicesAction.CompleteSecurity       -> handleCompleteSecurity()
+            is DevicesAction.MarkAsManuallyVerified -> handleVerifyManually(action)
+            is DevicesAction.VerifyMyDeviceManually -> handleShowDeviceCryptoInfo(action)
         }
     }
 
-    private fun handleVerify(action: DevicesAction.VerifyMyDevice) {
+    private fun handleInteractiveVerification(action: DevicesAction.VerifyMyDevice) {
         val txID = session.cryptoService()
                 .verificationService()
-                .requestKeyVerification(supportedVerificationMethodsProvider.provide(), session.myUserId, listOf(action.deviceId))
+                .beginKeyVerification(VerificationMethod.SAS, session.myUserId, action.deviceId, null)
         _viewEvents.post(DevicesViewEvents.ShowVerifyDevice(
                 session.myUserId,
-                txID.transactionId
+                txID
         ))
     }
 
+    private fun handleShowDeviceCryptoInfo(action: DevicesAction.VerifyMyDeviceManually) = withState { state ->
+        state.devices.invoke()
+                ?.firstOrNull { it.cryptoDeviceInfo?.deviceId == action.deviceId }
+                ?.let {
+                    _viewEvents.post(DevicesViewEvents.ShowManuallyVerify(it.cryptoDeviceInfo!!))
+                }
+    }
+
+    private fun handleVerifyManually(action: DevicesAction.MarkAsManuallyVerified) = withState { state ->
+        viewModelScope.launch {
+            if (state.hasAccountCrossSigning) {
+                awaitCallback<Unit> {
+                    tryThis { session.cryptoService().crossSigningService().trustDevice(action.cryptoDeviceInfo.deviceId, it) }
+                }
+            } else {
+                // legacy
+                session.cryptoService().setDeviceVerification(
+                        DeviceTrustLevel(crossSigningVerified = false, locallyVerified = true),
+                        action.cryptoDeviceInfo.userId,
+                        action.cryptoDeviceInfo.deviceId)
+            }
+        }
+    }
+
+    private fun handleCompleteSecurity() {
+        _viewEvents.post(DevicesViewEvents.SelfVerification(session))
+    }
+
     private fun handlePromptRename(action: DevicesAction.PromptRename) = withState { state ->
-        val info = state.devices.invoke()?.firstOrNull { it.deviceId == action.deviceId }
+        val info = state.devices.invoke()?.firstOrNull { it.deviceInfo.deviceId == action.deviceId }
         if (info != null) {
-            _viewEvents.post(DevicesViewEvents.PromptRenameDevice(info))
+            _viewEvents.post(DevicesViewEvents.PromptRenameDevice(info.deviceInfo))
         }
     }
 
@@ -199,7 +248,7 @@ class DevicesViewModel @AssistedInject constructor(
                     )
                 }
                 // force settings update
-                refreshDevicesList()
+                queryRefreshDevicesList()
             }
 
             override fun onFailure(failure: Throwable) {
@@ -270,7 +319,7 @@ class DevicesViewModel @AssistedInject constructor(
                     )
                 }
                 // force settings update
-                refreshDevicesList()
+                queryRefreshDevicesList()
             }
         })
     }
@@ -299,7 +348,7 @@ class DevicesViewModel @AssistedInject constructor(
                     )
                 }
                 // force settings update
-                refreshDevicesList()
+                queryRefreshDevicesList()
             }
 
             override fun onFailure(failure: Throwable) {
diff --git a/vector/src/main/java/im/vector/riotx/features/settings/devices/TrustUtils.kt b/vector/src/main/java/im/vector/riotx/features/settings/devices/TrustUtils.kt
new file mode 100644
index 0000000000..7f987b327b
--- /dev/null
+++ b/vector/src/main/java/im/vector/riotx/features/settings/devices/TrustUtils.kt
@@ -0,0 +1,56 @@
+/*
+ * 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.riotx.features.settings.devices
+
+import androidx.annotation.DrawableRes
+import im.vector.matrix.android.internal.crypto.crosssigning.DeviceTrustLevel
+import im.vector.riotx.R
+
+object TrustUtils {
+
+    @DrawableRes
+    fun shieldForTrust(currentDevice: Boolean, trustMSK: Boolean, legacyMode: Boolean, deviceTrustLevel: DeviceTrustLevel?): Int {
+        return when {
+            currentDevice -> {
+                if (legacyMode) {
+                    // In legacy, current session is always trusted
+                    R.drawable.ic_shield_trusted
+                } else {
+                    // If current session doesn't trust MSK, show red shield for current device
+                    R.drawable.ic_shield_trusted.takeIf { trustMSK } ?: R.drawable.ic_shield_warning
+                }
+            }
+            else          -> {
+                if (legacyMode) {
+                    // use local trust
+                    R.drawable.ic_shield_trusted.takeIf { deviceTrustLevel?.locallyVerified == true } ?: R.drawable.ic_shield_warning
+                } else {
+                    if (trustMSK) {
+                        // use cross sign trust, put locally trusted in black
+                        R.drawable.ic_shield_trusted.takeIf { deviceTrustLevel?.crossSigningVerified == true }
+                                ?: R.drawable.ic_shield_black.takeIf { deviceTrustLevel?.locallyVerified == true }
+                                ?: R.drawable.ic_shield_warning
+                    } else {
+                        // The current session is untrusted, so displays others in black
+                        // as we can't know the cross-signing state
+                        R.drawable.ic_shield_black
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/vector/src/main/java/im/vector/riotx/features/settings/devices/VectorSettingsDevicesFragment.kt b/vector/src/main/java/im/vector/riotx/features/settings/devices/VectorSettingsDevicesFragment.kt
index 603b0b6b78..fa8ee16931 100644
--- a/vector/src/main/java/im/vector/riotx/features/settings/devices/VectorSettingsDevicesFragment.kt
+++ b/vector/src/main/java/im/vector/riotx/features/settings/devices/VectorSettingsDevicesFragment.kt
@@ -27,6 +27,7 @@ import com.airbnb.mvrx.fragmentViewModel
 import com.airbnb.mvrx.withState
 import im.vector.matrix.android.internal.crypto.model.rest.DeviceInfo
 import im.vector.riotx.R
+import im.vector.riotx.core.dialogs.ManuallyVerifyDialog
 import im.vector.riotx.core.dialogs.PromptPasswordDialog
 import im.vector.riotx.core.extensions.cleanup
 import im.vector.riotx.core.extensions.configureWith
@@ -73,6 +74,15 @@ class VectorSettingsDevicesFragment @Inject constructor(
                             transactionId = it.transactionId
                     ).show(childFragmentManager, "REQPOP")
                 }
+                is DevicesViewEvents.SelfVerification   -> {
+                    VerificationBottomSheet.forSelfVerification(it.session)
+                            .show(childFragmentManager, "REQPOP")
+                }
+                is DevicesViewEvents.ShowManuallyVerify -> {
+                    ManuallyVerifyDialog.show(requireActivity(), it.cryptoDeviceInfo) {
+                        viewModel.handle(DevicesAction.MarkAsManuallyVerified(it.cryptoDeviceInfo))
+                    }
+                }
             }.exhaustive
         }
     }
@@ -92,8 +102,8 @@ class VectorSettingsDevicesFragment @Inject constructor(
 
     override fun onResume() {
         super.onResume()
-
         (activity as? VectorBaseActivity)?.supportActionBar?.setTitle(R.string.settings_active_sessions_manage)
+        viewModel.handle(DevicesAction.Refresh)
     }
 
     override fun onDeviceClicked(deviceInfo: DeviceInfo) {
@@ -112,7 +122,7 @@ class VectorSettingsDevicesFragment @Inject constructor(
 //    }
 
     override fun retry() {
-        viewModel.handle(DevicesAction.Retry)
+        viewModel.handle(DevicesAction.Refresh)
     }
 
     /**
diff --git a/vector/src/main/java/im/vector/riotx/features/ui/SharedPreferencesUiStateRepository.kt b/vector/src/main/java/im/vector/riotx/features/ui/SharedPreferencesUiStateRepository.kt
index f850d12422..43761ee214 100644
--- a/vector/src/main/java/im/vector/riotx/features/ui/SharedPreferencesUiStateRepository.kt
+++ b/vector/src/main/java/im/vector/riotx/features/ui/SharedPreferencesUiStateRepository.kt
@@ -26,6 +26,12 @@ import javax.inject.Inject
  */
 class SharedPreferencesUiStateRepository @Inject constructor(private val sharedPreferences: SharedPreferences) : UiStateRepository {
 
+    override fun reset() {
+        sharedPreferences.edit {
+            remove(KEY_DISPLAY_MODE)
+        }
+    }
+
     override fun getDisplayMode(): RoomListDisplayMode {
         return when (sharedPreferences.getInt(KEY_DISPLAY_MODE, VALUE_DISPLAY_MODE_CATCHUP)) {
             VALUE_DISPLAY_MODE_PEOPLE -> RoomListDisplayMode.PEOPLE
diff --git a/vector/src/main/java/im/vector/riotx/features/ui/UiStateRepository.kt b/vector/src/main/java/im/vector/riotx/features/ui/UiStateRepository.kt
index feac6a64ed..c3ecd456e5 100644
--- a/vector/src/main/java/im/vector/riotx/features/ui/UiStateRepository.kt
+++ b/vector/src/main/java/im/vector/riotx/features/ui/UiStateRepository.kt
@@ -23,6 +23,11 @@ import im.vector.riotx.features.home.RoomListDisplayMode
  */
 interface UiStateRepository {
 
+    /**
+     * Reset all the saved data
+     */
+    fun reset()
+
     fun getDisplayMode(): RoomListDisplayMode
 
     fun storeDisplayMode(displayMode: RoomListDisplayMode)
diff --git a/vector/src/main/res/drawable-xxhdpi/ic_material_save.png b/vector/src/main/res/drawable-xxhdpi/ic_material_save.png
deleted file mode 100755
index d5306e1170..0000000000
Binary files a/vector/src/main/res/drawable-xxhdpi/ic_material_save.png and /dev/null differ
diff --git a/vector/src/main/res/drawable/ic_file.xml b/vector/src/main/res/drawable/ic_file.xml
new file mode 100644
index 0000000000..2b74a19a94
--- /dev/null
+++ b/vector/src/main/res/drawable/ic_file.xml
@@ -0,0 +1,21 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+  <path
+      android:pathData="M13,2H6C4.8954,2 4,2.8954 4,4V20C4,21.1046 4.8954,22 6,22H18C19.1046,22 20,21.1046 20,20V9L13,2Z"
+      android:strokeLineJoin="round"
+      android:strokeWidth="2"
+      android:fillColor="#00000000"
+      android:fillType="evenOdd"
+      android:strokeColor="#2E2F32"
+      android:strokeLineCap="round"/>
+  <path
+      android:pathData="M13,2V9H20"
+      android:strokeLineJoin="round"
+      android:strokeWidth="2"
+      android:fillColor="#00000000"
+      android:strokeColor="#2E2F32"
+      android:strokeLineCap="round"/>
+</vector>
diff --git a/vector/src/main/res/drawable/ic_material_save.xml b/vector/src/main/res/drawable/ic_material_save.xml
new file mode 100644
index 0000000000..e299376f3a
--- /dev/null
+++ b/vector/src/main/res/drawable/ic_material_save.xml
@@ -0,0 +1,5 @@
+<vector android:autoMirrored="true" android:height="24dp"
+    android:viewportHeight="24" android:viewportWidth="24"
+    android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+    <path android:fillColor="#FF000000" android:pathData="M17,3L5,3c-1.11,0 -2,0.9 -2,2v14c0,1.1 0.89,2 2,2h14c1.1,0 2,-0.9 2,-2L21,7l-4,-4zM12,19c-1.66,0 -3,-1.34 -3,-3s1.34,-3 3,-3 3,1.34 3,3 -1.34,3 -3,3zM15,9L5,9L5,5h10v4z"/>
+</vector>
diff --git a/vector/src/main/res/drawable/ic_message_key.xml b/vector/src/main/res/drawable/ic_message_key.xml
index c4a415477b..9c5e53571d 100644
--- a/vector/src/main/res/drawable/ic_message_key.xml
+++ b/vector/src/main/res/drawable/ic_message_key.xml
@@ -7,13 +7,10 @@
     <clip-path
         android:pathData="M0,0h22v6h-22zM0,17h22v7h-22z"/>
     <path
-        android:pathData="M21,11.4445C21.0038,12.911 20.6612,14.3577 20,15.6667C18.401,18.8659 15.1321,20.8875 11.5555,20.8889C10.089,20.8927 8.6423,20.5501 7.3333,19.8889L1,22L3.1111,15.6667C2.4499,14.3577 2.1073,12.911 2.1111,11.4445C2.1125,7.8679 4.1341,4.599 7.3333,3C8.6423,2.3388 10.089,1.9962 11.5555,2H12.1111C16.9064,2.2646 20.7354,6.0936 21,10.8889V11.4445V11.4445Z"
-        android:strokeLineJoin="round"
+        android:pathData="M19,14C19,16.0333 17.7458,17.9018 16.043,19.4808C14.3615,21.0401 12.4,22.1689 11.3349,22.7219C11.1216,22.8327 10.8784,22.8327 10.6651,22.7219C9.6,22.1689 7.6385,21.0401 5.957,19.4808C4.2542,17.9018 3,16.0333 3,14V3.6043C3,3.1356 3.3255,2.7298 3.7831,2.6282L10.7831,1.0726C10.9259,1.0409 11.0741,1.0409 11.2169,1.0726L18.2169,2.6282C18.6745,2.7298 19,3.1356 19,3.6043V14Z"
         android:strokeWidth="2"
         android:fillColor="#00000000"
-        android:fillType="evenOdd"
-        android:strokeColor="#2E2F32"
-        android:strokeLineCap="round"/>
+        android:strokeColor="#2E2F32"/>
   </group>
   <path
       android:pathData="M2,8C0.8954,8 0,8.8954 0,10V13C0,14.1046 0.8954,15 2,15H20C21.1046,15 22,14.1046 22,13V10C22,8.8954 21.1046,8 20,8H2ZM4.25,9.5C3.8358,9.5 3.5,9.8358 3.5,10.25C3.5,10.6642 3.8358,11 4.25,11H6.75C7.1642,11 7.5,10.6642 7.5,10.25C7.5,9.8358 7.1642,9.5 6.75,9.5H4.25ZM8.5,10.25C8.5,9.8358 8.8358,9.5 9.25,9.5H9.75C10.1642,9.5 10.5,9.8358 10.5,10.25C10.5,10.6642 10.1642,11 9.75,11H9.25C8.8358,11 8.5,10.6642 8.5,10.25ZM12.25,9.5C11.8358,9.5 11.5,9.8358 11.5,10.25C11.5,10.6642 11.8358,11 12.25,11H14.75C15.1642,11 15.5,10.6642 15.5,10.25C15.5,9.8358 15.1642,9.5 14.75,9.5H12.25ZM16.5,10.25C16.5,9.8358 16.8358,9.5 17.25,9.5H17.75C18.1642,9.5 18.5,9.8358 18.5,10.25C18.5,10.6642 18.1642,11 17.75,11H17.25C16.8358,11 16.5,10.6642 16.5,10.25ZM4.25,12C3.8358,12 3.5,12.3358 3.5,12.75C3.5,13.1642 3.8358,13.5 4.25,13.5H4.75C5.1642,13.5 5.5,13.1642 5.5,12.75C5.5,12.3358 5.1642,12 4.75,12H4.25ZM6.5,12.75C6.5,12.3358 6.8358,12 7.25,12H9.75C10.1642,12 10.5,12.3358 10.5,12.75C10.5,13.1642 10.1642,13.5 9.75,13.5H7.25C6.8358,13.5 6.5,13.1642 6.5,12.75ZM12.25,12C11.8358,12 11.5,12.3358 11.5,12.75C11.5,13.1642 11.8358,13.5 12.25,13.5H12.75C13.1642,13.5 13.5,13.1642 13.5,12.75C13.5,12.3358 13.1642,12 12.75,12H12.25Z"
diff --git a/vector/src/main/res/drawable/ic_message_password.xml b/vector/src/main/res/drawable/ic_message_password.xml
index 311be14cc6..f82603a320 100644
--- a/vector/src/main/res/drawable/ic_message_password.xml
+++ b/vector/src/main/res/drawable/ic_message_password.xml
@@ -7,13 +7,10 @@
     <clip-path
         android:pathData="M0,0h22v6h-22zM0,17h22v7h-22z"/>
     <path
-        android:pathData="M21,11.4445C21.0038,12.911 20.6612,14.3577 20,15.6667C18.401,18.8659 15.1321,20.8875 11.5555,20.8889C10.089,20.8927 8.6423,20.5501 7.3333,19.8889L1,22L3.1111,15.6667C2.4499,14.3577 2.1073,12.911 2.1111,11.4445C2.1125,7.8679 4.1341,4.599 7.3333,3C8.6423,2.3388 10.089,1.9962 11.5555,2H12.1111C16.9064,2.2646 20.7354,6.0936 21,10.8889V11.4445V11.4445Z"
-        android:strokeLineJoin="round"
+        android:pathData="M11.3349,22.7219C11.1216,22.8327 10.8784,22.8327 10.6651,22.7219C9.6,22.1689 7.6385,21.0401 5.957,19.4808C4.2542,17.9018 3,16.0333 3,14V3.6043C3,3.1356 3.3255,2.7298 3.7831,2.6282L10.7831,1.0726C10.9259,1.0409 11.0741,1.0409 11.2169,1.0726L18.2169,2.6282C18.6745,2.7298 19,3.1356 19,3.6043V14C19,16.0333 17.7458,17.9018 16.043,19.4808C14.3615,21.0401 12.4,22.1689 11.3349,22.7219Z"
         android:strokeWidth="2"
         android:fillColor="#00000000"
-        android:fillType="evenOdd"
-        android:strokeColor="#2E2F32"
-        android:strokeLineCap="round"/>
+        android:strokeColor="#2E2F32"/>
   </group>
   <path
       android:pathData="M0,10C0,8.8954 0.8954,8 2,8H20C21.1046,8 22,8.8954 22,10V13C22,14.1046 21.1046,15 20,15H2C0.8954,15 0,14.1046 0,13V10ZM5,11.5C5,12.3284 4.3284,13 3.5,13C2.6716,13 2,12.3284 2,11.5C2,10.6716 2.6716,10 3.5,10C4.3284,10 5,10.6716 5,11.5ZM8.5,13C9.3284,13 10,12.3284 10,11.5C10,10.6716 9.3284,10 8.5,10C7.6716,10 7,10.6716 7,11.5C7,12.3284 7.6716,13 8.5,13ZM15,11.5C15,12.3284 14.3284,13 13.5,13C12.6716,13 12,12.3284 12,11.5C12,10.6716 12.6716,10 13.5,10C14.3284,10 15,10.6716 15,11.5ZM18.5,13C19.3284,13 20,12.3284 20,11.5C20,10.6716 19.3284,10 18.5,10C17.6716,10 17,10.6716 17,11.5C17,12.3284 17.6716,13 18.5,13Z"
diff --git a/vector/src/main/res/drawable/ic_monitor.xml b/vector/src/main/res/drawable/ic_monitor.xml
new file mode 100644
index 0000000000..c6bbe52171
--- /dev/null
+++ b/vector/src/main/res/drawable/ic_monitor.xml
@@ -0,0 +1,28 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+  <path
+      android:strokeWidth="1"
+      android:pathData="M2,5C2,3.8954 2.8954,3 4,3H20C21.1046,3 22,3.8954 22,5V15C22,16.1046 21.1046,17 20,17H4C2.8954,17 2,16.1046 2,15V5Z"
+      android:strokeLineJoin="round"
+      android:fillColor="#00000000"
+      android:fillType="evenOdd"
+      android:strokeColor="#2E2F32"
+      android:strokeLineCap="round"/>
+  <path
+      android:strokeWidth="1"
+      android:pathData="M8,21H16"
+      android:strokeLineJoin="round"
+      android:fillColor="#00000000"
+      android:strokeColor="#2E2F32"
+      android:strokeLineCap="round"/>
+  <path
+      android:strokeWidth="1"
+      android:pathData="M12,17V21"
+      android:strokeLineJoin="round"
+      android:fillColor="#00000000"
+      android:strokeColor="#2E2F32"
+      android:strokeLineCap="round"/>
+</vector>
diff --git a/vector/src/main/res/drawable/ic_shield_warning_small.xml b/vector/src/main/res/drawable/ic_shield_warning_small.xml
new file mode 100644
index 0000000000..d42add32ea
--- /dev/null
+++ b/vector/src/main/res/drawable/ic_shield_warning_small.xml
@@ -0,0 +1,20 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="16dp"
+    android:height="16dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+  <path
+      android:strokeWidth="1"
+      android:pathData="m12,21s9,-3.8 9,-9.5v-6.65l-9,-2.85 -9,2.85v6.65c0,5.7 9,9.5 9,9.5z"
+      android:strokeLineJoin="round"
+      android:fillColor="#ff4b55"
+      android:strokeColor="#fff"
+      android:fillType="evenOdd"
+      android:strokeLineCap="round"/>
+  <path
+      android:pathData="M12.05,5.5L12.05,5.5A1.25,1.25 0,0 1,13.3 6.75L13.3,12.25A1.25,1.25 0,0 1,12.05 13.5L12.05,13.5A1.25,1.25 0,0 1,10.8 12.25L10.8,6.75A1.25,1.25 0,0 1,12.05 5.5z"
+      android:fillColor="#fff"/>
+  <path
+      android:pathData="M12.05,15L12.05,15A1.25,1.25 0,0 1,13.3 16.25L13.3,16.25A1.25,1.25 0,0 1,12.05 17.5L12.05,17.5A1.25,1.25 0,0 1,10.8 16.25L10.8,16.25A1.25,1.25 0,0 1,12.05 15z"
+      android:fillColor="#fff"/>
+</vector>
diff --git a/vector/src/main/res/drawable/ic_smartphone.xml b/vector/src/main/res/drawable/ic_smartphone.xml
new file mode 100644
index 0000000000..3f1072ce16
--- /dev/null
+++ b/vector/src/main/res/drawable/ic_smartphone.xml
@@ -0,0 +1,17 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+  <path
+      android:strokeWidth="1"
+      android:pathData="M5,4C5,2.8954 5.8954,2 7,2H17C18.1046,2 19,2.8954 19,4V20C19,21.1046 18.1046,22 17,22H7C5.8954,22 5,21.1046 5,20V4Z"
+      android:strokeLineJoin="round"
+      android:fillColor="#00000000"
+      android:fillType="evenOdd"
+      android:strokeColor="#2E2F32"
+      android:strokeLineCap="round"/>
+  <path
+      android:pathData="M12,18m-1,0a1,1 0,1 1,2 0a1,1 0,1 1,-2 0"
+      android:fillColor="#2E2F32"/>
+</vector>
diff --git a/vector/src/main/res/layout/alerter_verification_layout.xml b/vector/src/main/res/layout/alerter_verification_layout.xml
index b06883b056..7098c3152d 100644
--- a/vector/src/main/res/layout/alerter_verification_layout.xml
+++ b/vector/src/main/res/layout/alerter_verification_layout.xml
@@ -33,7 +33,7 @@
     <LinearLayout
         android:id="@+id/alerter_texts"
         android:layout_width="0dp"
-        android:layout_height="0dp"
+        android:layout_height="wrap_content"
         android:orientation="vertical"
         app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintEnd_toEndOf="parent"
@@ -68,6 +68,7 @@
             android:textAppearance="@style/AlertTextAppearance.Text"
             android:visibility="gone"
             tools:text="Text"
+            android:maxLines="3"
             tools:visibility="visible" />
 
     </LinearLayout>
diff --git a/vector/src/main/res/layout/bottom_sheet_bootstrap.xml b/vector/src/main/res/layout/bottom_sheet_bootstrap.xml
index 5f2ce368ff..fda590517c 100644
--- a/vector/src/main/res/layout/bottom_sheet_bootstrap.xml
+++ b/vector/src/main/res/layout/bottom_sheet_bootstrap.xml
@@ -1,5 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-
 <androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
     xmlns:tools="http://schemas.android.com/tools"
@@ -12,10 +11,9 @@
 
     <androidx.constraintlayout.widget.ConstraintLayout
         android:layout_width="match_parent"
-
+        android:layout_height="wrap_content"
         android:paddingTop="16dp"
-        android:paddingBottom="16dp"
-        android:layout_height="wrap_content">
+        android:paddingBottom="16dp">
 
         <ImageView
             android:id="@+id/bootstrapIcon"
@@ -28,23 +26,19 @@
             app:layout_constraintStart_toStartOf="parent"
             app:layout_constraintTop_toTopOf="parent" />
 
-
         <TextView
             android:id="@+id/bootstrapTitleText"
             android:layout_width="0dp"
             android:layout_height="wrap_content"
             android:layout_marginStart="8dp"
             android:layout_marginEnd="16dp"
-            android:layout_weight="1"
             android:ellipsize="end"
-            android:maxLines="2"
             android:textColor="?riotx_text_primary"
             android:textSize="20sp"
             android:textStyle="bold"
-            app:layout_constraintBottom_toBottomOf="@+id/bootstrapIcon"
             app:layout_constraintEnd_toEndOf="parent"
             app:layout_constraintStart_toEndOf="@+id/bootstrapIcon"
-            app:layout_constraintTop_toTopOf="@+id/bootstrapIcon"
+            app:layout_constraintTop_toTopOf="parent"
             tools:text="@string/recovery_passphrase" />
 
         <androidx.fragment.app.FragmentContainerView
diff --git a/vector/src/main/res/layout/bottom_sheet_verification.xml b/vector/src/main/res/layout/bottom_sheet_verification.xml
index 5f1461594d..8de64de060 100644
--- a/vector/src/main/res/layout/bottom_sheet_verification.xml
+++ b/vector/src/main/res/layout/bottom_sheet_verification.xml
@@ -44,13 +44,11 @@
             android:layout_height="wrap_content"
             android:layout_marginStart="8dp"
             android:layout_marginEnd="16dp"
-            android:layout_weight="1"
             android:ellipsize="end"
             android:maxLines="2"
             android:textColor="?riotx_text_primary"
             android:textSize="20sp"
             android:textStyle="bold"
-            app:layout_constraintBottom_toBottomOf="@+id/verificationRequestAvatar"
             app:layout_constraintEnd_toEndOf="parent"
             app:layout_constraintStart_toEndOf="@+id/verificationRequestAvatar"
             app:layout_constraintTop_toTopOf="@+id/verificationRequestAvatar"
diff --git a/vector/src/main/res/layout/constraint_set_composer_layout_compact.xml b/vector/src/main/res/layout/constraint_set_composer_layout_compact.xml
index ac04dfe3ec..4607f28f34 100644
--- a/vector/src/main/res/layout/constraint_set_composer_layout_compact.xml
+++ b/vector/src/main/res/layout/constraint_set_composer_layout_compact.xml
@@ -99,18 +99,31 @@
         android:layout_width="32dp"
         android:layout_height="32dp"
         android:layout_marginStart="8dp"
-        android:layout_marginLeft="8dp"
         android:layout_marginTop="8dp"
-        android:layout_marginEnd="8dp"
-        android:layout_marginRight="8dp"
+        android:layout_marginEnd="4dp"
+        app:layout_goneMarginEnd="8dp"
         android:layout_marginBottom="8dp"
         app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintEnd_toStartOf="@+id/composerEditText"
         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintTop_toTopOf="parent"
         app:layout_constraintVertical_bias="1"
+        app:layout_constraintEnd_toStartOf="@+id/composer_shield"
         tools:src="@tools:sample/avatars" />
 
+
+    <ImageView
+        android:id="@+id/composer_shield"
+        android:layout_width="16dp"
+        android:layout_height="16dp"
+        app:layout_constraintTop_toTopOf="@id/composer_avatar_view"
+        app:layout_constraintEnd_toStartOf="@+id/composerEditText"
+        app:layout_constraintBottom_toBottomOf="@id/composer_avatar_view"
+        app:layout_constraintStart_toEndOf="@+id/composer_avatar_view"
+        tools:src="@drawable/ic_shield_black"
+        tools:visibility="visible"
+        />
+
+
     <ImageButton
         android:id="@+id/attachmentButton"
         android:layout_width="48dp"
@@ -154,11 +167,11 @@
         android:minHeight="48dp"
         android:nextFocusLeft="@id/composerEditText"
         android:nextFocusUp="@id/composerEditText"
-        android:padding="16dp"
+        android:padding="8dp"
         android:textSize="14sp"
         app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintEnd_toStartOf="@+id/attachmentButton"
-        app:layout_constraintStart_toEndOf="@+id/composer_avatar_view"
+        app:layout_constraintStart_toEndOf="@+id/composer_shield"
         app:layout_constraintTop_toTopOf="parent"
         tools:text="@tools:sample/lorem/random" />
 
diff --git a/vector/src/main/res/layout/constraint_set_composer_layout_expanded.xml b/vector/src/main/res/layout/constraint_set_composer_layout_expanded.xml
index d246c988e6..17b350542a 100644
--- a/vector/src/main/res/layout/constraint_set_composer_layout_expanded.xml
+++ b/vector/src/main/res/layout/constraint_set_composer_layout_expanded.xml
@@ -107,17 +107,32 @@
         android:layout_marginStart="8dp"
         android:layout_marginLeft="8dp"
         android:layout_marginTop="8dp"
-        android:layout_marginEnd="8dp"
+        android:layout_marginEnd="4dp"
+        app:layout_goneMarginEnd="8dp"
         android:layout_marginRight="8dp"
         android:layout_marginBottom="8dp"
         app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintEnd_toStartOf="@+id/composerEditText"
+        app:layout_constraintEnd_toStartOf="@+id/composer_shield"
         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintTop_toTopOf="parent"
         app:layout_constraintVertical_bias="1"
         tools:src="@tools:sample/avatars" />
 
 
+    <ImageView
+        android:id="@+id/composer_shield"
+        android:layout_width="16dp"
+        android:layout_height="16dp"
+        app:layout_constraintTop_toTopOf="@id/composer_avatar_view"
+        app:layout_constraintEnd_toStartOf="@+id/composerEditText"
+        app:layout_constraintBottom_toBottomOf="@id/composer_avatar_view"
+        app:layout_constraintStart_toEndOf="@+id/composer_avatar_view"
+        tools:src="@drawable/ic_shield_black"
+        tools:visibility="visible"
+        />
+
+
+
     <ImageButton
         android:id="@+id/attachmentButton"
         android:layout_width="48dp"
@@ -161,7 +176,7 @@
         android:minHeight="48dp"
         android:nextFocusLeft="@id/composerEditText"
         android:nextFocusUp="@id/composerEditText"
-        android:padding="16dp"
+        android:padding="8dp"
         android:textSize="14sp"
         app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintEnd_toStartOf="@+id/sendButton"
diff --git a/vector/src/main/res/layout/dialog_change_password.xml b/vector/src/main/res/layout/dialog_change_password.xml
index 925859bcd1..12806a56b7 100644
--- a/vector/src/main/res/layout/dialog_change_password.xml
+++ b/vector/src/main/res/layout/dialog_change_password.xml
@@ -39,7 +39,8 @@
         android:id="@+id/change_password_old_pwd_til"
         style="@style/VectorTextInputLayout"
         android:layout_width="match_parent"
-        android:layout_height="wrap_content">
+        android:layout_height="wrap_content"
+        app:errorEnabled="true">
 
         <com.google.android.material.textfield.TextInputEditText
             android:id="@+id/change_password_old_pwd_text"
@@ -53,7 +54,9 @@
     <com.google.android.material.textfield.TextInputLayout
         style="@style/VectorTextInputLayout"
         android:layout_width="match_parent"
-        android:layout_height="wrap_content">
+        android:layout_height="wrap_content"
+        android:layout_marginTop="8dp"
+        app:errorEnabled="true">
 
         <com.google.android.material.textfield.TextInputEditText
             android:id="@+id/change_password_new_pwd_text"
@@ -69,6 +72,7 @@
         style="@style/VectorTextInputLayout"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
+        android:layout_marginTop="8dp"
         app:errorEnabled="true">
 
         <com.google.android.material.textfield.TextInputEditText
diff --git a/vector/src/main/res/layout/fragment_bootstrap_enter_account_password.xml b/vector/src/main/res/layout/fragment_bootstrap_enter_account_password.xml
index c91110402f..c26723637b 100644
--- a/vector/src/main/res/layout/fragment_bootstrap_enter_account_password.xml
+++ b/vector/src/main/res/layout/fragment_bootstrap_enter_account_password.xml
@@ -12,11 +12,11 @@
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:layout_marginTop="8dp"
-        tools:text="@string/enter_account_password"
         android:textColor="?riotx_text_primary"
         android:textSize="14sp"
         app:layout_constraintBottom_toTopOf="@id/bootstrapAccountPasswordTil"
-        app:layout_constraintTop_toTopOf="parent" />
+        app:layout_constraintTop_toTopOf="parent"
+        tools:text="@string/enter_account_password" />
 
     <com.google.android.material.textfield.TextInputLayout
         android:id="@+id/bootstrapAccountPasswordTil"
@@ -59,9 +59,7 @@
     <com.google.android.material.button.MaterialButton
         android:id="@+id/bootstrapPasswordButton"
         style="@style/VectorButtonStyleText"
-        android:layout_gravity="end"
         android:layout_marginTop="@dimen/layout_vertical_margin"
-        android:padding="8dp"
         android:text="@string/_continue"
         app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintEnd_toEndOf="parent"
diff --git a/vector/src/main/res/layout/fragment_bootstrap_enter_passphrase.xml b/vector/src/main/res/layout/fragment_bootstrap_enter_passphrase.xml
index 96618e519f..b344f2819d 100644
--- a/vector/src/main/res/layout/fragment_bootstrap_enter_passphrase.xml
+++ b/vector/src/main/res/layout/fragment_bootstrap_enter_passphrase.xml
@@ -1,5 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-
 <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
     xmlns:tools="http://schemas.android.com/tools"
@@ -25,7 +24,6 @@
         android:layout_height="wrap_content"
         android:layout_marginTop="16dp"
         app:errorEnabled="true"
-        app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintEnd_toStartOf="@id/ssss_view_show_password"
         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintTop_toBottomOf="@id/bootstrapDescriptionText">
@@ -34,11 +32,11 @@
             android:id="@+id/ssss_passphrase_enter_edittext"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            tools:hint="@string/passphrase_enter_passphrase"
             android:imeOptions="actionDone"
             android:maxLines="3"
             android:singleLine="false"
             android:textColor="?android:textColorPrimary"
+            tools:hint="@string/passphrase_enter_passphrase"
             tools:inputType="textPassword" />
 
         <!-- This is inside the TIL, if not the keyboard will hide it when in bottomsheet -->
@@ -46,9 +44,9 @@
         <im.vector.riotx.core.ui.views.PasswordStrengthBar
             android:id="@+id/ssss_passphrase_security_progress"
             android:layout_width="match_parent"
-            android:layout_marginBottom="2dp"
+            android:layout_height="4dp"
             android:layout_marginTop="2dp"
-            android:layout_height="4dp" />
+            android:layout_marginBottom="2dp" />
 
         <TextView
             android:id="@+id/bootstrapWarningInfo"
@@ -56,12 +54,12 @@
             android:layout_height="wrap_content"
             android:layout_marginTop="8dp"
             android:layout_marginBottom="8dp"
-            android:textSize="12sp"
-            android:gravity="center_vertical"
             android:drawableStart="@drawable/ic_alert_triangle"
-            android:drawableTint="@color/riotx_destructive_accent"
             android:drawablePadding="4dp"
-            android:text="@string/bootstrap_dont_reuse_pwd" />
+            android:drawableTint="@color/riotx_destructive_accent"
+            android:gravity="center_vertical"
+            android:text="@string/bootstrap_dont_reuse_pwd"
+            android:textSize="12sp" />
 
     </com.google.android.material.textfield.TextInputLayout>
 
@@ -78,6 +76,13 @@
         app:layout_constraintStart_toEndOf="@+id/ssss_passphrase_enter_til"
         app:layout_constraintTop_toTopOf="@+id/ssss_passphrase_enter_til" />
 
+    <com.google.android.material.button.MaterialButton
+        android:id="@+id/bootstrapSubmit"
+        style="@style/VectorButtonStyleText"
+        android:text="@string/_continue"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/ssss_passphrase_enter_til" />
 
     <!--    <TextView-->
     <!--        android:id="@+id/bootstrapWarningInfo"-->
diff --git a/vector/src/main/res/layout/fragment_bootstrap_migrate_backup.xml b/vector/src/main/res/layout/fragment_bootstrap_migrate_backup.xml
new file mode 100644
index 0000000000..ac1b70d2c9
--- /dev/null
+++ b/vector/src/main/res/layout/fragment_bootstrap_migrate_backup.xml
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:padding="16dp">
+
+    <TextView
+        android:id="@+id/bootstrapDescriptionText"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="8dp"
+        android:textColor="?riotx_text_primary"
+        android:textSize="14sp"
+        app:layout_constraintBottom_toTopOf="@id/bootstrapRecoveryKeyEnterTil"
+        app:layout_constraintTop_toTopOf="parent"
+        tools:text="@string/bootstrap_enter_recovery" />
+
+    <com.google.android.material.textfield.TextInputLayout
+        android:id="@+id/bootstrapRecoveryKeyEnterTil"
+        style="@style/VectorTextInputLayout"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="16dp"
+        android:layout_marginBottom="8dp"
+        app:errorEnabled="true"
+        app:layout_constraintEnd_toStartOf="@id/bootstrapMigrateShowPassword"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/bootstrapDescriptionText">
+
+        <com.google.android.material.textfield.TextInputEditText
+            android:id="@+id/bootstrapMigrateEditText"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:imeOptions="actionDone"
+            android:maxLines="3"
+            android:singleLine="false"
+            android:textColor="?android:textColorPrimary"
+            tools:hint="@string/keys_backup_restore_key_enter_hint"
+            tools:inputType="textPassword" />
+
+
+        <com.google.android.material.button.MaterialButton
+            android:id="@+id/bootstrapMigrateUseFile"
+            style="@style/Widget.MaterialComponents.Button.TextButton"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/use_file"
+            android:textAllCaps="false"
+            app:icon="@drawable/ic_file"
+            app:iconTint="@color/button_positive_text_color_selector"
+            tools:visibility="visible" />
+
+        <TextView
+            android:id="@+id/bootstrapMigrateForgotPassphrase"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:visibility="gone"
+            tools:text="@string/keys_backup_restore_with_passphrase_helper_with_link"
+            tools:visibility="visible" />
+
+    </com.google.android.material.textfield.TextInputLayout>
+
+    <ImageView
+        android:id="@+id/bootstrapMigrateShowPassword"
+        android:layout_width="@dimen/layout_touch_size"
+        android:layout_height="@dimen/layout_touch_size"
+        android:layout_marginTop="8dp"
+        android:background="?attr/selectableItemBackground"
+        android:scaleType="center"
+        android:src="@drawable/ic_eye_black"
+        android:tint="?colorAccent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toEndOf="@+id/bootstrapRecoveryKeyEnterTil"
+        app:layout_constraintTop_toTopOf="@+id/bootstrapRecoveryKeyEnterTil" />
+
+    <com.google.android.material.button.MaterialButton
+        android:id="@+id/bootstrapMigrateContinueButton"
+        style="@style/VectorButtonStyleText"
+        android:layout_marginTop="@dimen/layout_vertical_margin"
+        android:text="@string/_continue"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/bootstrapRecoveryKeyEnterTil" />
+
+</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/vector/src/main/res/layout/fragment_deactivate_account.xml b/vector/src/main/res/layout/fragment_deactivate_account.xml
new file mode 100644
index 0000000000..1bf04ba81e
--- /dev/null
+++ b/vector/src/main/res/layout/fragment_deactivate_account.xml
@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:padding="16dp">
+
+        <TextView
+            android:id="@+id/deactivateAccountContent"
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:text="@string/deactivate_account_content"
+            android:textColor="?riotx_text_primary"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent" />
+
+        <androidx.appcompat.widget.SwitchCompat
+            android:id="@+id/deactivateAccountEraseCheckbox"
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="16dp"
+            android:text="@string/deactivate_account_delete_checkbox"
+            android:textColor="?riotx_text_primary"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toBottomOf="@+id/deactivateAccountContent" />
+
+        <TextView
+            android:id="@+id/deactivateAccountPromptPassword"
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="16dp"
+            android:text="@string/deactivate_account_prompt_password"
+            android:textColor="?riotx_text_primary"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toBottomOf="@+id/deactivateAccountEraseCheckbox" />
+
+        <FrameLayout
+            android:id="@+id/deactivateAccountPasswordContainer"
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="8dp"
+            android:hint="@string/auth_password_placeholder"
+            android:inputType="textPassword"
+            android:maxLines="1"
+            android:nextFocusDown="@+id/login_password"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toBottomOf="@+id/deactivateAccountPromptPassword">
+
+
+            <com.google.android.material.textfield.TextInputLayout
+                android:id="@+id/deactivateAccountPasswordTil"
+                style="@style/VectorTextInputLayout"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:hint="@string/login_signup_password_hint"
+                app:errorEnabled="true"
+                app:errorIconDrawable="@null">
+
+                <com.google.android.material.textfield.TextInputEditText
+                    android:id="@+id/deactivateAccountPassword"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:ems="10"
+                    android:inputType="textPassword"
+                    android:maxLines="1"
+                    android:paddingEnd="48dp"
+                    android:paddingRight="48dp"
+                    tools:ignore="RtlSymmetry" />
+
+            </com.google.android.material.textfield.TextInputLayout>
+
+            <ImageView
+                android:id="@+id/deactivateAccountPasswordReveal"
+                android:layout_width="@dimen/layout_touch_size"
+                android:layout_height="@dimen/layout_touch_size"
+                android:layout_gravity="end"
+                android:layout_marginTop="8dp"
+                android:background="?attr/selectableItemBackground"
+                android:scaleType="center"
+                android:src="@drawable/ic_eye_black"
+                android:tint="?attr/colorAccent"
+                tools:contentDescription="@string/a11y_show_password" />
+
+        </FrameLayout>
+
+        <Button
+            android:id="@+id/deactivateAccountSubmit"
+            style="@style/VectorButtonStyleDestructive"
+            android:layout_marginTop="16dp"
+            android:layout_marginBottom="16dp"
+            android:text="@string/deactivate_account_submit"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintTop_toBottomOf="@+id/deactivateAccountPasswordContainer" />
+
+    </androidx.constraintlayout.widget.ConstraintLayout>
+
+</androidx.core.widget.NestedScrollView>
diff --git a/vector/src/main/res/layout/fragment_login.xml b/vector/src/main/res/layout/fragment_login.xml
index 3f2443440e..894a7598c8 100644
--- a/vector/src/main/res/layout/fragment_login.xml
+++ b/vector/src/main/res/layout/fragment_login.xml
@@ -82,6 +82,7 @@
                         android:layout_width="match_parent"
                         android:layout_height="wrap_content"
                         android:ems="10"
+                        android:imeOptions="actionDone"
                         android:inputType="textPassword"
                         android:maxLines="1"
                         android:paddingEnd="48dp"
@@ -104,19 +105,18 @@
 
             </FrameLayout>
 
-            <RelativeLayout
+            <androidx.constraintlayout.widget.ConstraintLayout
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
-                android:layout_marginTop="22dp"
-                android:orientation="horizontal">
+                android:layout_marginTop="22dp">
 
                 <com.google.android.material.button.MaterialButton
                     android:id="@+id/forgetPasswordButton"
                     style="@style/Style.Vector.Login.Button.Text"
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
-                    android:layout_gravity="start"
-                    android:text="@string/auth_forgot_password" />
+                    android:text="@string/auth_forgot_password"
+                    app:layout_constraintStart_toStartOf="parent" />
 
                 <com.google.android.material.button.MaterialButton
                     android:id="@+id/loginSubmit"
@@ -124,12 +124,12 @@
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
                     android:layout_alignParentEnd="true"
-                    android:layout_gravity="end"
                     android:text="@string/auth_login"
+                    app:layout_constraintEnd_toEndOf="parent"
                     tools:enabled="false"
                     tools:ignore="RelativeOverlap" />
 
-            </RelativeLayout>
+            </androidx.constraintlayout.widget.ConstraintLayout>
 
         </LinearLayout>
 
diff --git a/vector/src/main/res/layout/fragment_ssss_access_from_key.xml b/vector/src/main/res/layout/fragment_ssss_access_from_key.xml
new file mode 100644
index 0000000000..2f6945bc5b
--- /dev/null
+++ b/vector/src/main/res/layout/fragment_ssss_access_from_key.xml
@@ -0,0 +1,112 @@
+<?xml version="1.0" encoding="utf-8"?>
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:id="@+id/ssss__root"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content">
+
+        <ImageView
+            android:id="@+id/ssss_shield"
+            android:layout_width="24dp"
+            android:layout_height="24dp"
+            android:layout_marginStart="16dp"
+            android:tint="?riotx_text_primary"
+            app:layout_constraintBottom_toBottomOf="@+id/ssss_restore_with_key"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="@+id/ssss_restore_with_key"
+            android:src="@drawable/ic_message_key" />
+
+        <TextView
+            android:id="@+id/ssss_restore_with_key"
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:layout_marginStart="8dp"
+            android:layout_marginTop="36dp"
+            android:layout_marginEnd="16dp"
+            android:text="@string/recovery_key"
+            android:textColor="?riotx_text_primary"
+            android:textSize="20sp"
+            android:textStyle="bold"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toEndOf="@id/ssss_shield"
+            app:layout_constraintTop_toTopOf="parent" />
+
+
+        <TextView
+            android:id="@+id/ssss_restore_with_key_text"
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:layout_margin="16dp"
+            android:textColor="?riotx_text_primary"
+            android:textSize="16sp"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toBottomOf="@id/ssss_restore_with_key"
+            tools:text="@string/enter_secret_storage_input_key" />
+
+
+        <com.google.android.material.textfield.TextInputLayout
+            android:id="@+id/ssss_key_enter_til"
+            style="@style/VectorTextInputLayout"
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:layout_marginStart="16dp"
+            android:layout_marginEnd="16dp"
+            android:layout_marginTop="16dp"
+            app:errorEnabled="true"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toBottomOf="@id/ssss_restore_with_key_text">
+
+            <com.google.android.material.textfield.TextInputEditText
+                android:id="@+id/ssss_key_enter_edittext"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:hint="@string/recovery_key"
+                android:imeOptions="actionDone"
+                android:maxLines="3"
+                android:singleLine="false"
+                android:textColor="?android:textColorPrimary"
+                tools:inputType="textMultiLine" />
+
+        </com.google.android.material.textfield.TextInputLayout>
+
+        <!--        -->
+
+
+        <com.google.android.material.button.MaterialButton
+            android:id="@+id/ssss_key_use_file"
+            style="@style/Widget.MaterialComponents.Button.TextButton.Icon"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/use_file"
+            app:icon="@drawable/ic_file"
+            tools:ignore="MissingConstraints" />
+
+        <com.google.android.material.button.MaterialButton
+            android:id="@+id/ssss_key_submit"
+            style="@style/Widget.MaterialComponents.Button.TextButton"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/_continue"
+            tools:ignore="MissingConstraints" />
+
+        <androidx.constraintlayout.helper.widget.Flow
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginStart="16dp"
+            android:layout_marginEnd="@dimen/layout_horizontal_margin"
+            android:layout_marginBottom="@dimen/layout_vertical_margin_big"
+            app:constraint_referenced_ids="ssss_key_use_file,ssss_key_submit"
+            app:flow_horizontalStyle="spread_inside"
+            app:flow_wrapMode="chain"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintTop_toBottomOf="@+id/ssss_key_enter_til" />
+
+    </androidx.constraintlayout.widget.ConstraintLayout>
+</ScrollView>
\ No newline at end of file
diff --git a/vector/src/main/res/layout/fragment_ssss_access_from_passphrase.xml b/vector/src/main/res/layout/fragment_ssss_access_from_passphrase.xml
index db50cfd34d..6192e87259 100644
--- a/vector/src/main/res/layout/fragment_ssss_access_from_passphrase.xml
+++ b/vector/src/main/res/layout/fragment_ssss_access_from_passphrase.xml
@@ -12,14 +12,14 @@
 
         <ImageView
             android:id="@+id/ssss_shield"
-            android:layout_width="20dp"
-            android:layout_height="20dp"
+            android:layout_width="24dp"
+            android:layout_height="24dp"
             android:layout_marginStart="16dp"
-            android:src="@drawable/key_big"
             android:tint="?riotx_text_primary"
             app:layout_constraintBottom_toBottomOf="@+id/ssss_restore_with_passphrase"
             app:layout_constraintStart_toStartOf="parent"
-            app:layout_constraintTop_toTopOf="@+id/ssss_restore_with_passphrase" />
+            app:layout_constraintTop_toTopOf="@+id/ssss_restore_with_passphrase"
+            android:src="@drawable/ic_message_password" />
 
         <TextView
             android:id="@+id/ssss_restore_with_passphrase"
@@ -28,7 +28,7 @@
             android:layout_marginStart="8dp"
             android:layout_marginTop="36dp"
             android:layout_marginEnd="16dp"
-            android:text="@string/enter_secret_storage_passphrase"
+            android:text="@string/recovery_passphrase"
             android:textColor="?riotx_text_primary"
             android:textSize="20sp"
             android:textStyle="bold"
@@ -47,20 +47,7 @@
             app:layout_constraintEnd_toEndOf="parent"
             app:layout_constraintStart_toStartOf="parent"
             app:layout_constraintTop_toBottomOf="@id/ssss_restore_with_passphrase"
-            tools:text="@string/enter_secret_storage_passphrase_warning_text" />
-
-
-        <TextView
-            android:id="@+id/ssss_restore_with_passphrase_warning_reason"
-            android:layout_width="0dp"
-            android:layout_height="wrap_content"
-            android:layout_margin="16dp"
-            android:textColor="?riotx_text_primary"
-            android:textSize="16sp"
-            app:layout_constraintEnd_toEndOf="parent"
-            app:layout_constraintStart_toStartOf="parent"
-            app:layout_constraintTop_toBottomOf="@id/ssss_restore_with_passphrase_warning_text"
-            tools:text="@string/enter_secret_storage_passphrase_reason_verify" />
+            tools:text="@string/enter_secret_storage_passphrase_or_key" />
 
 
         <com.google.android.material.textfield.TextInputLayout
@@ -74,7 +61,7 @@
             app:errorEnabled="true"
             app:layout_constraintEnd_toStartOf="@id/ssss_view_show_password"
             app:layout_constraintStart_toStartOf="parent"
-            app:layout_constraintTop_toBottomOf="@id/ssss_restore_with_passphrase_warning_reason">
+            app:layout_constraintTop_toBottomOf="@id/ssss_restore_with_passphrase_warning_text">
 
             <com.google.android.material.textfield.TextInputEditText
                 android:id="@+id/ssss_passphrase_enter_edittext"
@@ -102,30 +89,37 @@
             app:layout_constraintStart_toEndOf="@+id/ssss_passphrase_enter_til"
             app:layout_constraintTop_toTopOf="@+id/ssss_passphrase_enter_til" />
 
+        <!--        -->
+
+
+        <com.google.android.material.button.MaterialButton
+            android:id="@+id/ssss_passphrase_use_key"
+            style="@style/Widget.MaterialComponents.Button.TextButton.Icon"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/use_recovery_key"
+            app:icon="@drawable/ic_message_key"
+            tools:ignore="MissingConstraints" />
 
         <com.google.android.material.button.MaterialButton
             android:id="@+id/ssss_passphrase_submit"
-            style="@style/VectorButtonStylePositive"
-            android:layout_marginTop="@dimen/layout_vertical_margin_big"
-            android:layout_marginEnd="@dimen/layout_horizontal_margin"
-            android:layout_marginBottom="@dimen/layout_vertical_margin_big"
-            android:minWidth="200dp"
+            style="@style/Widget.MaterialComponents.Button.TextButton"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
             android:text="@string/_continue"
-            app:layout_constraintEnd_toEndOf="parent"
-            app:layout_constraintTop_toBottomOf="@+id/ssss_passphrase_enter_til" />
+            tools:ignore="MissingConstraints" />
 
-
-        <com.google.android.material.button.MaterialButton
-            android:id="@+id/ssss_passphrase_cancel"
-            style="@style/VectorButtonStyleDestructive"
-            android:layout_marginTop="8dp"
+        <androidx.constraintlayout.helper.widget.Flow
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginStart="16dp"
             android:layout_marginEnd="@dimen/layout_horizontal_margin"
             android:layout_marginBottom="@dimen/layout_vertical_margin_big"
-            android:minWidth="200dp"
-            android:text="@string/cancel"
+            app:constraint_referenced_ids="ssss_passphrase_use_key,ssss_passphrase_submit"
+            app:flow_horizontalStyle="spread_inside"
+            app:flow_wrapMode="chain"
             app:layout_constraintBottom_toBottomOf="parent"
-            app:layout_constraintEnd_toEndOf="parent"
-            app:layout_constraintTop_toBottomOf="@+id/ssss_passphrase_submit" />
+            app:layout_constraintTop_toBottomOf="@+id/ssss_passphrase_enter_til" />
 
     </androidx.constraintlayout.widget.ConstraintLayout>
 </ScrollView>
\ No newline at end of file
diff --git a/vector/src/main/res/layout/item_generic_button.xml b/vector/src/main/res/layout/item_generic_button.xml
new file mode 100644
index 0000000000..d2af2663d3
--- /dev/null
+++ b/vector/src/main/res/layout/item_generic_button.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:orientation="vertical"
+    android:padding="16dp">
+
+    <com.google.android.material.button.MaterialButton
+        android:id="@+id/itemGenericItemButton"
+        style="@style/Widget.MaterialComponents.Button.TextButton.Icon"
+        android:textAllCaps="false"
+        tools:icon="@drawable/ic_shield_warning"
+        app:iconGravity="textStart"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        tools:text="Action Name" />
+
+</LinearLayout>
\ No newline at end of file
diff --git a/vector/src/main/res/layout/item_timeline_event_base.xml b/vector/src/main/res/layout/item_timeline_event_base.xml
index 77eaeae05c..3ae80424cc 100644
--- a/vector/src/main/res/layout/item_timeline_event_base.xml
+++ b/vector/src/main/res/layout/item_timeline_event_base.xml
@@ -62,6 +62,24 @@
         android:layout_height="0dp"
         tools:layout_marginStart="52dp" />
 
+    <Space
+        android:id="@+id/decorationSpace"
+        android:layout_width="4dp"
+        android:layout_height="8dp"
+        android:layout_toEndOf="@id/messageStartGuideline"
+        />
+
+    <ImageView
+        android:id="@+id/messageE2EDecoration"
+        android:layout_width="16dp"
+        android:layout_height="16dp"
+        android:layout_alignTop="@id/viewStubContainer"
+        android:layout_marginTop="7dp"
+        android:layout_alignEnd="@id/decorationSpace"
+        android:visibility="gone"
+        tools:src="@drawable/ic_shield_warning"
+        tools:visibility="visible" />
+
     <FrameLayout
         android:id="@+id/viewStubContainer"
         android:layout_width="match_parent"
diff --git a/vector/src/main/res/layout/item_timeline_event_base_noinfo.xml b/vector/src/main/res/layout/item_timeline_event_base_noinfo.xml
index 3e959bcda8..8d0d9bb513 100644
--- a/vector/src/main/res/layout/item_timeline_event_base_noinfo.xml
+++ b/vector/src/main/res/layout/item_timeline_event_base_noinfo.xml
@@ -58,11 +58,23 @@
             android:id="@+id/messageContentMergedCreationStub"
             style="@style/TimelineContentStubBaseParams"
             android:layout="@layout/item_timeline_event_merged_room_creation_stub"
-            tools:layout_marginTop="160dp"
+            tools:layout_marginTop="240dp"
             tools:visibility="visible" />
 
     </FrameLayout>
 
+    <ImageView
+        android:id="@+id/messageE2EDecoration"
+        android:layout_width="16dp"
+        android:layout_height="16dp"
+        android:layout_alignParentTop="true"
+        android:layout_marginTop="8dp"
+        android:layout_toStartOf="@id/viewStubContainer"
+        android:visibility="gone"
+        tools:src="@drawable/ic_shield_warning"
+        tools:visibility="visible" />
+
+
     <im.vector.riotx.core.ui.views.ReadReceiptsView
         android:id="@+id/readReceiptsView"
         android:layout_width="wrap_content"
diff --git a/vector/src/main/res/layout/item_timeline_event_base_state.xml b/vector/src/main/res/layout/item_timeline_event_base_state.xml
index af20c3f549..58496e1da4 100644
--- a/vector/src/main/res/layout/item_timeline_event_base_state.xml
+++ b/vector/src/main/res/layout/item_timeline_event_base_state.xml
@@ -54,6 +54,18 @@
 
     </FrameLayout>
 
+
+    <ImageView
+        android:id="@+id/messageE2EDecoration"
+        android:layout_width="16dp"
+        android:layout_height="16dp"
+        android:layout_marginTop="4dp"
+        android:layout_alignTop="@id/viewStubContainer"
+        android:layout_toStartOf="@id/viewStubContainer"
+        android:visibility="gone"
+        tools:src="@drawable/ic_shield_warning"
+        tools:visibility="visible" />
+
     <ImageView
         android:id="@+id/messageFailToSendIndicator"
         android:layout_width="14dp"
diff --git a/vector/src/main/res/layout/item_verification_wait.xml b/vector/src/main/res/layout/item_verification_wait.xml
new file mode 100644
index 0000000000..a5c4ae6f1b
--- /dev/null
+++ b/vector/src/main/res/layout/item_verification_wait.xml
@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:id="@+id/itemVerificationNoticeText"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:contentDescription="@string/use_other_session_content_description"
+    android:paddingStart="16dp"
+    android:paddingEnd="16dp"
+    android:paddingBottom="8dp">
+
+    <TextView
+        android:id="@+id/use_latest_riot"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:gravity="start"
+        android:text="@string/use_latest_riot"
+        android:textColor="?riotx_text_primary"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
+
+    <ImageView
+        android:id="@+id/monitorIcon"
+        android:layout_width="40dp"
+        android:layout_height="40dp"
+        android:layout_marginTop="16dp"
+        android:scaleType="fitCenter"
+        android:src="@drawable/ic_monitor"
+        android:tint="?vctr_notice_secondary"
+        app:layout_constraintEnd_toStartOf="@id/smartphoneIcon"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/use_latest_riot" />
+
+    <ImageView
+        android:id="@+id/smartphoneIcon"
+        android:layout_width="40dp"
+        android:layout_height="40dp"
+        android:layout_marginTop="16dp"
+        android:scaleType="fitCenter"
+        android:src="@drawable/ic_smartphone"
+        android:tint="?vctr_notice_secondary"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toEndOf="@id/monitorIcon"
+        app:layout_constraintTop_toBottomOf="@+id/use_latest_riot" />
+
+
+    <TextView
+        android:id="@+id/riot_desktop_web"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="8dp"
+        android:gravity="center"
+        android:text="@string/riot_desktop_web"
+        android:textColor="?riotx_text_primary"
+        app:layout_constraintEnd_toEndOf="@id/monitorIcon"
+        app:layout_constraintStart_toStartOf="@id/monitorIcon"
+        app:layout_constraintTop_toBottomOf="@id/monitorIcon" />
+
+    <TextView
+        android:id="@+id/riot_ios_android"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="8dp"
+        android:gravity="center"
+        android:text="@string/riot_ios_android"
+        android:textColor="?riotx_text_primary"
+        app:layout_constraintEnd_toEndOf="@id/smartphoneIcon"
+        app:layout_constraintStart_toStartOf="@id/smartphoneIcon"
+        app:layout_constraintTop_toBottomOf="@id/smartphoneIcon" />
+
+    <androidx.constraintlayout.widget.Barrier
+        android:id="@+id/labelsBarrier"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        app:barrierDirection="bottom"
+        app:constraint_referenced_ids="riot_ios_android,riot_desktop_web" />
+
+
+    <TextView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="16dp"
+        android:gravity="center"
+        android:text="@string/or_other_mx_capabale_client"
+        android:textColor="?riotx_text_secondary"
+        android:textSize="12sp"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/labelsBarrier" />
+
+</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/vector/src/main/res/layout/merge_composer_layout.xml b/vector/src/main/res/layout/merge_composer_layout.xml
index 571831a24d..b0c733c349 100644
--- a/vector/src/main/res/layout/merge_composer_layout.xml
+++ b/vector/src/main/res/layout/merge_composer_layout.xml
@@ -39,6 +39,13 @@
         tools:ignore="MissingConstraints"
         tools:src="@tools:sample/avatars" />
 
+    <ImageView
+        android:id="@+id/composer_shield"
+        android:layout_width="0dp"
+        android:layout_height="0dp"
+        tools:ignore="MissingConstraints"
+        tools:src="@drawable/ic_shield_black" />
+
     <TextView
         android:id="@+id/composer_related_message_sender"
         android:layout_width="0dp"
diff --git a/vector/src/main/res/menu/vector_media_viewer.xml b/vector/src/main/res/menu/vector_media_viewer.xml
new file mode 100644
index 0000000000..09b6cedacd
--- /dev/null
+++ b/vector/src/main/res/menu/vector_media_viewer.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto">
+    <item
+        android:id="@+id/mediaViewerShareAction"
+        android:icon="@drawable/ic_material_share"
+        android:title="@string/share"
+        app:iconTint="?attr/colorAccent"
+        app:showAsAction="ifRoom" />
+</menu>
\ No newline at end of file
diff --git a/vector/src/main/res/values-bn-rIN/strings.xml b/vector/src/main/res/values-bn-rIN/strings.xml
index a0af9661d4..ac67c0aec5 100644
--- a/vector/src/main/res/values-bn-rIN/strings.xml
+++ b/vector/src/main/res/values-bn-rIN/strings.xml
@@ -27,7 +27,7 @@
     <string name="keys_backup_is_not_finished_please_wait">কী ব্যাকআপ শেষ হয়নি, দয়া করে অপেক্ষা করুন …</string>
     <string name="sign_out_bottom_sheet_warning_no_backup">আপনি এখন সাইন আউট করলে আপনার এনক্রিপ্ট হওয়া বার্তাগুলি হারিয়ে ফেলবেন</string>
     <string name="sign_out_bottom_sheet_warning_backing_up">অগ্রগতি কী ব্যাকআপ। আপনি এখন সাইন আউট করলে আপনি আপনার এনক্রিপ্ট করা বার্তাগুলির অ্যাক্সেস হারাবেন।</string>
-    <string name="sign_out_bottom_sheet_warning_backup_not_active">আপনার এনক্রিপ্ট করা বার্তাগুলির অ্যাক্সেস হারাতে এড়াতে আপনার সমস্ত ডিভাইসগুলিতে নিরাপদ কী ব্যাকআপ সক্রিয় থাকা উচিত।</string>
+    <string name="sign_out_bottom_sheet_warning_backup_not_active">আপনার এনক্রিপ্ট করা বার্তাগুলির অ্যাক্সেস হারাতে এড়াতে আপনার সমস্ত সেশানগুলিতে নিরাপদ কী ব্যাকআপ সক্রিয় থাকা উচিত।</string>
     <string name="sign_out_bottom_sheet_dont_want_secure_messages">আমি আমার এনক্রিপ্টেড বার্তা চাই না</string>
     <string name="sign_out_bottom_sheet_backing_up_keys">কী ব্যাকআপ করছে…</string>
     <string name="keys_backup_activate">কী ব্যাকআপ ব্যবহার করুন</string>
@@ -71,7 +71,7 @@
     <string name="missing_permissions_error">অনুপস্থিত অনুমতিগুলির কারণে, এই পদক্ষেপটি সম্ভব নয়।</string>
     <string name="missing_permissions_to_start_conf_call">আপনি এই রুমে একটি সম্মেলন শুরু করার জন্য আমন্ত্রণ করার অনুমতি প্রয়োজন</string>
     <string name="missing_permissions_title_to_start_conf_call">কল শুরু করা গেলো না</string>
-    <string name="device_information">যন্ত্রের তথ্য</string>
+    <string name="device_information">সেশানের তথ্য</string>
     <string name="room_no_conference_call_in_encrypted_rooms">কনফারেন্স কল এনক্রিপ্ট কক্ষগুলিতে সমর্থিত নয়</string>
     <string name="call_anyway">যেকোন ভাবেই কল করুন</string>
     <string name="send_anyway">যেকোন ভাবেই পাঠাও</string>
@@ -236,9 +236,9 @@
     <string name="auth_reset_password_missing_password">একটি নতুন পাসওয়ার্ড প্রবেশ করা আবশ্যক।</string>
     <string name="auth_reset_password_email_validation_message">একটি ইমেল %s কে পাঠানো হয়েছে। একবার এটিতে থাকা লিঙ্কটি অনুসরণ করার পরে, নীচে ক্লিক করুন।</string>
     <string name="auth_reset_password_error_unauthorized">ইমেল ঠিকানা যাচাই করতে ব্যর্থ: ইমেলটিতে লিঙ্কে আপনি ক্লিক করেছেন তা নিশ্চিত করুন</string>
-    <string name="auth_reset_password_success_message">আপনার পাসওয়ার্ড পুনরায় সেট করা হয়েছে।
-\n
-\nআপনি সমস্ত ডিভাইস থেকে লগ আউট করা হয়েছে এবং আর পুশ বিজ্ঞপ্তি পাবেন না। বিজ্ঞপ্তিগুলি পুনরায় সক্ষম করতে, প্রতিটি ডিভাইসে পুনরায় লগ ইন করুন।</string>
+    <string name="auth_reset_password_success_message">আপনার পাসওয়ার্ড পুনরায় সেট করা হয়েছে। 
+\n 
+\nআপনি সমস্ত সেশান থেকে লগ আউট করা হয়েছে এবং আর পুশ বিজ্ঞপ্তি পাবেন না। বিজ্ঞপ্তিগুলি পুনরায় সক্ষম করতে, প্রতিটি ডিভাইসে পুনরায় লগ ইন করুন।</string>
     <string name="auth_accept_policies">পর্যালোচনা করুন এবং এই হোমসার্ভার এর নীতিগুলি গ্রহণ করুন:</string>
 
     <string name="login_error_must_start_http">URL টি http[s]:// দিয়ে শুরু করতে হবে</string>
@@ -260,16 +260,16 @@
     <string name="login_error_user_in_use">এই ব্যাবহারকারী আগেও নাম ব্যবহার করে ছিল</string>
     <string name="login_error_login_email_not_yet">এই ইমেইল লিংক যেটা এখনো ক্লিক করা হয়নি</string>
 
-    <string name="e2e_need_log_in_again">আপনার প্রয়জনীয় পিছনে লগ করা যন্ত্রের জন্য এনক্রিপশন চাবি উৎপন্ন করতে শেষ থেকে শেষে এবং জমা করা জনগণ এর চাবি আপনার ঘরের লোক এর কাছে। 
+    <string name="e2e_need_log_in_again">আপনার প্রয়জনীয় পিছনে লগ করা সেশানের জন্য এনক্রিপশন চাবি উৎপন্ন করতে শেষ থেকে শেষে এবং জমা করা জনগণ এর চাবি আপনার ঘরের লোক এর কাছে। 
 \nএটাই হলো একবার। 
 \nক্ষমা করবেন এটাই হলো অসুবিধা।</string>
 
-    <string name="e2e_re_request_encryption_key"><ও>পুনরায় অনুরোধ এনক্রিপশন চাবিগুলি</ও>আপনার অন্য যন্ত্রগুলি থেকে।</string>
+    <string name="e2e_re_request_encryption_key"><u>পুনরায় অনুরোধ এনক্রিপশন চাবিগুলি</u>আপনার অন্য সেশানগুলি থেকে।</string>
 
     <string name="e2e_re_request_encryption_key_sent">চাবির অনুরোধ পাঠানো।</string>
 
     <string name="e2e_re_request_encryption_key_dialog_title">অনুরোধ পাঠানো</string>
-    <string name="e2e_re_request_encryption_key_dialog_content">দয়া করে শুরু করুন Riot অন্য যন্ত্রে যেটা পারে বর্ণনা করতে বার্তা কে সুতরাং এটা পারে পাঠাতে চাবিগুলো কে যন্ত্র তে.</string>
+    <string name="e2e_re_request_encryption_key_dialog_content">দয়া করে শুরু করুন Riot অন্য সেশান যেটা পারে বর্ণনা করতে বার্তা কে সুতরাং এটা পারে পাঠাতে চাবিগুলো কে যন্ত্র তে.</string>
 
     <string name="read_receipts_list">পড়ো প্রাপ্তিগুলি সারি</string>
 
@@ -409,7 +409,7 @@
     <string name="room_participants_header_admin_tools">অ্যাডমিন সরঞ্জাম</string>
     <string name="room_participants_header_call">কল</string>
     <string name="room_participants_header_direct_chats">সরাসরি বার্তা</string>
-    <string name="room_participants_header_devices">যন্ত্রগুলি</string>
+    <string name="room_participants_header_devices">সেশানগুলি</string>
 
     <string name="room_participants_action_invite">আমন্ত্রণ</string>
     <string name="room_participants_action_leave">এই রুম ছাড়ো</string>
@@ -427,7 +427,7 @@
 \nমনে রাখবেন যে এই পদক্ষেপটি অ্যাপ্লিকেশনটি পুনরায় চালু করবে এবং এটি কিছু সময় নিতে পারে।</string>
     <string name="room_participants_invite_search_another_user">ব্যবহারকারী আইডি, নাম বা ইমেইল</string>
     <string name="room_participants_action_mention">উল্লেখ</string>
-    <string name="room_participants_action_devices_list">ডিভাইস তালিকা প্রদর্শন কর</string>
+    <string name="room_participants_action_devices_list">সেশান তালিকা প্রদর্শন কর</string>
     <string name="room_participants_power_level_prompt">আপনি এই পরিবর্তনটি পূর্বাবস্থায় ফিরিয়ে আনতে সক্ষম হবেন না যেহেতু আপনি ব্যবহারকারীকে একই শক্তি স্তর হিসাবে প্রচার করার জন্য প্রচার করছেন।
 \nআপনি কি নিশ্চিত\?</string>
 
@@ -462,7 +462,7 @@
     <string name="room_message_placeholder_reply_to_not_encrypted">একটি উত্তর পাঠান (এনক্রিপশনবিহীন)…</string>
     <string name="room_offline_notification">সার্ভারের সাথে সংযুক্তি হারিয়ে গেছে।</string>
     <string name="room_unsent_messages_notification">বার্তা পাঠানো হয় নি। %1$s বা %2$s এখন\?</string>
-    <string name="room_unknown_devices_messages_notification">অজানা ডিভাইস উপস্থিত থাকার কারণে বার্তা পাঠানো হয় নি। %1$s বা %2$s এখন\?</string>
+    <string name="room_unknown_devices_messages_notification">অজানা সেশান উপস্থিত থাকার কারণে বার্তা পাঠানো হয় নি। %1$s বা %2$s এখন\?</string>
     <string name="room_prompt_resend">সব আবার পাঠান</string>
     <string name="room_prompt_cancel">সব বাতিল করুন</string>
     <string name="room_resend_unsent_messages">অপ্রচলিত বার্তা আবার পাঠান</string>
@@ -577,9 +577,9 @@
 \nঅনুগ্রহ করে একাউন্ট সেটিংস যাচাই করে নিন।</string>
     <string name="settings_troubleshoot_test_account_settings_quickfix">সক্ষম</string>
 
-    <string name="settings_troubleshoot_test_device_settings_title">যন্ত্র সেটিংস।</string>
-    <string name="settings_troubleshoot_test_device_settings_success">বিজ্ঞপ্তি এই ডিভাইসের জন্য সক্রিয় করা হয়েছে।</string>
-    <string name="settings_troubleshoot_test_device_settings_failed">বিজ্ঞপ্তি এই ডিভাইসের জন্য অনুমতি দেওয়া হয় নি। 
+    <string name="settings_troubleshoot_test_device_settings_title">সেশান সেটিংস।</string>
+    <string name="settings_troubleshoot_test_device_settings_success">বিজ্ঞপ্তি এই সেশানের জন্য সক্রিয় করা হয়েছে।</string>
+    <string name="settings_troubleshoot_test_device_settings_failed">বিজ্ঞপ্তি এই সেশানের জন্য অনুমতি দেওয়া হয় নি। 
 \nRiot এর সেটিংস যাচাই করুন।</string>
     <string name="settings_troubleshoot_test_device_settings_quickfix">সক্ষম</string>
 
@@ -667,13 +667,13 @@
 
     <string name="settings_theme">থিম</string>
 
-    <string name="encryption_information_verify_device_warning">এই ডিভাইসটি বিশ্বাসযোগ্য হতে পারে তা যাচাই করতে, অন্য কোন উপায়ে (যেমন ব্যক্তি বা ফোন কল) ব্যবহার করে তার মালিকের সাথে যোগাযোগ করুন এবং এই ডিভাইসটির জন্য তাদের ব্যবহারকারী সেটিংসে এ কুঞ্জি দেখছে তা তাদের জিজ্ঞাসা করুন নীচের কুঞ্জিটির সাথে মেলে কিনা:</string>
+    <string name="encryption_information_verify_device_warning">এই সেশানটি বিশ্বাসযোগ্য হতে পারে তা যাচাই করতে, অন্য কোন উপায়ে (যেমন ব্যক্তি বা ফোন কল) ব্যবহার করে তার মালিকের সাথে যোগাযোগ করুন এবং এই সেশানটির জন্য তাদের ব্যবহারকারী সেটিংসে এ কুঞ্জি দেখছে তা তাদের জিজ্ঞাসা করুন নীচের কুঞ্জিটির সাথে মেলে কিনা:</string>
     <string name="e2e_enabling_on_app_update">দাঙ্গা এখন শেষ-থেকে-শেষ এনক্রিপশন সমর্থন করে তবে এটি সক্ষম করতে আপনাকে আবার লগ ইন করতে হবে।
 \n
 \nআপনি এখন বা পরে এপ্লিকেশন সেটিংস থেকে এটি করতে পারেন।</string>
 
     <string name="font_size">অক্ষর এর আকার</string>
-    <string name="you_added_a_new_device">আপনি একটি নতুন ডিভাইস \'%s\' যোগ করেছেন, যা এনক্রিপশন কীগুলির জন্য অনুরোধ করছে।</string>
+    <string name="you_added_a_new_device">আপনি একটি নতুন সেশান \'%s\' যোগ করেছেন, যা এনক্রিপশন কীগুলির জন্য অনুরোধ করছে।</string>
     <string name="command_description_clear_scalar_token">ম্যাট্রিক্স অ্যাপ্লিকেশন ব্যবস্থাপনা ঠিক করতে</string>
 
     <string name="encrypted_message">এনক্রিপ্ট করা বার্তা</string>
@@ -693,7 +693,7 @@
     <string name="new_recovery_method_popup_description">একটি নতুন সুরক্ষিত বার্তা কুঞ্জি ব্যাকআপ সনাক্ত করা হয়েছে।
 \n
 \nআপনি যদি নতুন পুনরুদ্ধারের পদ্ধতি সেট না করে থাকেন তবে একজন আক্রমণকারী আপনার অ্যাকাউন্ট অ্যাক্সেস করার চেষ্টা করছেন। আপনার অ্যাকাউন্ট পাসওয়ার্ড পরিবর্তন করুন এবং সেটিংসে অবিলম্বে একটি নতুন পুনরুদ্ধার পদ্ধতি সেট করুন।</string>
-    <string name="title_activity_verify_device">ডিভাইস যাচাই করুন</string>
+    <string name="title_activity_verify_device">সেশন যাচাই করুন</string>
 
     <string name="settings_notification_privacy_no_background_sync">অ্যাপগুলি ব্যাকগ্রাউন্ডে হোম সার্ভারের সাথে সংযোগ করার প্রয়োজন করার প্রয়োজন <b>নেই</b> , এটি ব্যাটারির ব্যবহারকে কমাতে পারে</string>
     <string name="settings_notification_privacy_fcm">• বিজ্ঞপ্তি Firebase ক্লাউড মেসেজিং মাধ্যমে পাঠানো হয়</string>
@@ -704,7 +704,7 @@
 
     <string name="settings_notification_ringtone">বিজ্ঞপ্তি শব্দ</string>
     <string name="settings_enable_all_notif">এই অ্যাকাউন্টের জন্য বিজ্ঞপ্তি সক্রিয় করুন</string>
-    <string name="settings_enable_this_device">এই ডিভাইসের জন্য বিজ্ঞপ্তি সক্রিয় করুন</string>
+    <string name="settings_enable_this_device">এই সেশানের জন্য বিজ্ঞপ্তি সক্রিয় করুন</string>
     <string name="settings_turn_screen_on">স্ক্রিন টি ৩ সেকেন্ডের জন্য চালু করুন</string>
     <string name="settings_noisy_notifications_preferences">হাল্লা বিজ্ঞপ্তিগুলি কনফিগার করুন</string>
     <string name="settings_call_notifications_preferences">কল বিজ্ঞপ্তিগুলি কনফিগার করুন</string>
@@ -751,7 +751,7 @@
     <string name="settings_home_display">হোম প্রদর্শন</string>
     <string name="settings_pin_missed_notifications">মিস বিজ্ঞপ্তি সঙ্গে পিন রুমগুলি</string>
     <string name="settings_pin_unread_messages">অপঠিত বার্তা সঙ্গে পিন কক্ষগুলি</string>
-    <string name="settings_devices_list">যন্ত্রগুলি</string>
+    <string name="settings_devices_list">সেশানগুলি</string>
     <string name="settings_send_typing_notifs_summary">অন্যান্য ব্যবহারকারীদের কে আপনি টাইপ করছেন সেটা জানান।</string>
     <string name="settings_send_markdown">মার্কডাউন বিন্যাস</string>
     <string name="settings_send_markdown_summary">প্রেরিত হওয়ার আগে মার্কডাউন সিনট্যাক্স ব্যবহার করে বার্তাগুলি ফরম্যাট করুন। এটি ইটালিক পাঠ্য প্রদর্শনের জন্য তারকাচিহ্নগুলি ব্যবহার করার মতো উন্নত ফর্ম্যাটিংয়ের জন্য অনুমতি দেয়।</string>
@@ -789,7 +789,7 @@
     <string name="settings_data_save_mode">ডেটা সংরক্ষণ মোড</string>
     <string name="settings_data_save_mode_summary">ডেটা সংরক্ষণ মোড একটি নির্দিষ্ট ফিল্টার প্রয়োগ করে যাতে উপস্থিতি আপডেট এবং টাইপিং বিজ্ঞপ্তি ফিল্টার করা হয়।</string>
 
-    <string name="devices_details_dialog_title">যন্ত্রের তথ্য</string>
+    <string name="devices_details_dialog_title">সেশানের তথ্য</string>
     <string name="devices_details_id_title">আইডি</string>
     <string name="devices_details_name_title">সর্বজনীন নাম</string>
     <string name="devices_details_device_name">সর্বজনীন নাম আপডেট করুন</string>
@@ -899,8 +899,8 @@
     <string name="room_settings_labs_end_to_end">শেষ থেকে শেষ এনক্রিপশন</string>
     <string name="room_settings_labs_end_to_end_is_active">শেষ থেকে শেষ এনক্রিপশন সক্রিয় আছে</string>
     <string name="room_settings_labs_end_to_end_warnings">এনক্রিপশন সক্রিয় করতে সক্ষম হবার জন্য আপনাকে লগআউট করতে হবে।</string>
-    <string name="room_settings_never_send_to_unverified_devices_title">শুধুমাত্র যাচাই ডিভাইসে এনক্রিপ্ট করুন</string>
-    <string name="room_settings_never_send_to_unverified_devices_summary">এই ডিভাইস থেকে এই রুমে যাচাই করা ডিভাইসগুলিতে এনক্রিপ্ট করা বার্তাগুলি কখনও প্রেরণ করবেন না।</string>
+    <string name="room_settings_never_send_to_unverified_devices_title">শুধুমাত্র যাচাই সেশানে এনক্রিপ্ট করুন</string>
+    <string name="room_settings_never_send_to_unverified_devices_summary">এই সেশান থেকে এই রুমে যাচাই করা সেশানগুলিতে এনক্রিপ্ট করা বার্তাগুলি কখনও প্রেরণ করবেন না।</string>
 
     <string name="room_settings_addresses_no_local_addresses">এই রুমে কোন স্থানীয় ঠিকানা নেই</string>
     <string name="room_settings_addresses_add_new_address">নতুন ঠিকানা (যেমন #foo:matrix.org)</string>
@@ -939,11 +939,11 @@
     <string name="encryption_information_session_id">সেশন আইডি</string>
     <string name="encryption_information_decryption_error">ডিক্রিপশন সমস্যা</string>
 
-    <string name="encryption_information_sender_device_information">প্রেরক ডিভাইস তথ্য</string>
+    <string name="encryption_information_sender_device_information">প্রেরক সেশান তথ্য</string>
     <string name="encryption_information_device_name">সর্বজনীন নাম</string>
     <string name="encryption_information_name">সর্বজনীন নাম</string>
     <string name="encryption_information_device_id">আইডি</string>
-    <string name="encryption_information_device_key">যন্ত্রের কুঞ্জি</string>
+    <string name="encryption_information_device_key">সেশানের কুঞ্জি</string>
     <string name="encryption_information_verification">প্রতিপাদন</string>
     <string name="encryption_information_ed25519_fingerprint">Ed25519 ফিঙ্গারপ্রিন্ট</string>
 
@@ -963,15 +963,15 @@
     <string name="encryption_import_room_keys">রুমের কুঞ্জিগুলি ইমপোর্ট করুন</string>
     <string name="encryption_import_room_keys_summary">একটি স্থানীয় ফাইল থেকে কুঞ্জি ইম্পোর্ট করুন</string>
     <string name="encryption_import_import">ইম্পোর্ট</string>
-    <string name="encryption_never_send_to_unverified_devices_title">শুধুমাত্র যাচাই ডিভাইসে এনক্রিপ্ট করুন</string>
-    <string name="encryption_never_send_to_unverified_devices_summary">এই ডিভাইস থেকে যাচাই করা ডিভাইসগুলিতে এনক্রিপ্ট করা বার্তাগুলি কখনও প্রেরণ করবেন না।</string>
+    <string name="encryption_never_send_to_unverified_devices_title">শুধুমাত্র যাচাই সেশানে এনক্রিপ্ট করুন</string>
+    <string name="encryption_never_send_to_unverified_devices_summary">এই সেশান থেকে যাচাই করা সেশানগুলিতে এনক্রিপ্ট করা বার্তাগুলি কখনও প্রেরণ করবেন না।</string>
     <string name="encryption_import_room_keys_success">%1$d/%2$d কুঞ্জি(গুলি) সাফল্য সাথে ইম্পোর্ট করা হয়েছে।</string>
 
     <string name="encryption_information_not_verified">যাচাই করা হয়নি</string>
     <string name="encryption_information_verified">প্রতিপাদিত</string>
     <string name="encryption_information_blocked">কালোতালিকাভুক্ত</string>
 
-    <string name="encryption_information_unknown_device">অজ্ঞাত যন্ত্র</string>
+    <string name="encryption_information_unknown_device">অজ্ঞাত সেশান</string>
     <string name="encryption_information_unknown_ip">অজ্ঞাত ip</string>
     <string name="encryption_information_none">কেউ না</string>
 
@@ -980,16 +980,16 @@
     <string name="encryption_information_block">কালোতালিকা</string>
     <string name="encryption_information_unblock">কালোতালিকাযুক্ত না</string>
 
-    <string name="encryption_information_verify_device">ডিভাইস যাচাই করুন</string>
-    <string name="encryption_information_verify_device_warning2">এটি মিললে, নীচের যাচাই বাটন টিপুন। যদি এটি না হয় তবে অন্য কেউ এই ডিভাইসটিকে আটক করছে এবং আপনাকে সম্ভবত এটি কালো তালিকাভুক্ত করা উচিত। ভবিষ্যতে এই যাচাই প্রক্রিয়া আরো পরিশীলিত হবে।</string>
+    <string name="encryption_information_verify_device">সেশান যাচাই করুন</string>
+    <string name="encryption_information_verify_device_warning2">এটি মিললে, নীচের যাচাই বাটন টিপুন। যদি এটি না হয় তবে অন্য কেউ এই সেশানটিকে আটক করছে এবং আপনাকে সম্ভবত এটি কালো তালিকাভুক্ত করা উচিত। ভবিষ্যতে এই যাচাই প্রক্রিয়া আরো পরিশীলিত হবে।</string>
     <string name="encryption_information_verify_key_match">আমি যে কি মেলে মেলে যাচাই</string>
 
-    <string name="unknown_devices_alert_title">রুমে অজানা ডিভাইস রয়েছে</string>
-    <string name="unknown_devices_alert_message">এই রুমে অজানা ডিভাইস রয়েছে যা যাচাই করা হয়নি।
-\nএর অর্থ এই যে ডিভাইসগুলি যে ব্যবহারকারীদের দাবি করে সেগুলির সাথে ডিভাইসগুলির কোনও নিশ্চয়তা নেই।
-\nআমরা আপনাকে চালিয়ে যাওয়ার আগে প্রতিটি ডিভাইসের জন্য যাচাইকরণ প্রক্রিয়ার মধ্য দিয়ে যেতে পরামর্শ দিই তবে আপনি যদি পছন্দ করেন তবে যাচাই না করে বার্তাটি পুনরায় পাঠাতে পারেন।
-\n
-\nঅজানা ডিভাইস:</string>
+    <string name="unknown_devices_alert_title">রুমে অজানা সেশান রয়েছে</string>
+    <string name="unknown_devices_alert_message">এই রুমে অজানা সেশান রয়েছে যা যাচাই করা হয়নি। 
+\nএর অর্থ এই যে সেশানগুলি যে ব্যবহারকারীদের দাবি করে সেগুলির সাথে সেশানগুলির কোনও নিশ্চয়তা নেই। 
+\nআমরা আপনাকে চালিয়ে যাওয়ার আগে প্রতিটি সেশানের জন্য যাচাইকরণ প্রক্রিয়ার মধ্য দিয়ে যেতে পরামর্শ দিই তবে আপনি যদি পছন্দ করেন তবে যাচাই না করে বার্তাটি পুনরায় পাঠাতে পারেন। 
+\n 
+\nঅজানা সেশানগুলি:</string>
 
     <string name="select_room_directory">একটি রুম ডিরেক্টরি নির্বাচন করুন</string>
     <string name="directory_server_fail_to_retrieve_server">সার্ভার অনুপলব্ধ বা ওভারলোড হতে পারে</string>
@@ -1070,15 +1070,15 @@
     <string name="settings_labs_enable_send_voice">ভয়েস বার্তা পাঠান</string>
     <string name="settings_labs_enable_send_voice_summary">এই বিকল্প বার্তা রেকর্ড করার জন্য একটি তৃতীয় পক্ষের অ্যাপ্লিকেশন প্রয়োজন।</string>
 
-    <string name="you_added_a_new_device_with_info">একটি নতুন ডিভাইস এনক্রিপশন কুঞ্জি অনুরোধ করছে।
-\nডিভাইসের নাম: %1$s
-\nশেষ দেখা হয়েছে: %2$s
-\nআপনি অন্য ডিভাইসে লগ ইন না করলে, এই অনুরোধটি উপেক্ষা করুন।</string>
-    <string name="your_unverified_device_requesting">আপনার যাচাই না করা ডিভাইস \'%s\' এনক্রিপশন কুঞ্জি অনুরোধ করছে।</string>
-    <string name="your_unverified_device_requesting_with_info">একটি যাচাইকরণ ডিভাইস এনক্রিপশন কুঞ্জি অনুরোধ করছে।
-\nডিভাইসের নাম: %1$s
-\nশেষ দেখা হয়েছে: %2$s
-\nআপনি অন্য ডিভাইসে লগ ইন না করলে, এই অনুরোধটি উপেক্ষা করুন।</string>
+    <string name="you_added_a_new_device_with_info">একটি নতুন সেশান এনক্রিপশন কুঞ্জি অনুরোধ করছে। 
+\nসেশানের নাম: %1$s 
+\nশেষ দেখা হয়েছে: %2$s 
+\nআপনি অন্য সেশানে লগ ইন না করলে, এই অনুরোধটি উপেক্ষা করুন।</string>
+    <string name="your_unverified_device_requesting">আপনার যাচাই না করা সেশান \'%s\' এনক্রিপশন কুঞ্জি অনুরোধ করছে।</string>
+    <string name="your_unverified_device_requesting_with_info">একটি যাচাইকরণ সেশান এনক্রিপশন কুঞ্জি অনুরোধ করছে। 
+\nসেশানের নাম: %1$s 
+\nশেষ দেখা হয়েছে: %2$s 
+\nআপনি অন্য সেশানে লগ ইন না করলে, এই অনুরোধটি উপেক্ষা করুন।</string>
 
     <string name="start_verification">যাচাই শুরু করুন</string>
     <string name="start_verification_short_label">যাচাই</string>
@@ -1148,7 +1148,7 @@
     <string name="settings_integration_manager">ইন্টিগ্রেশন ম্যানেজার</string>
 
     <string name="encryption_information_device_name_with_warning">সর্বজনীন নাম (যাদের সাথে আপনি যোগাযোগ করেন তাদের কাছে দৃশ্যমান)</string>
-    <string name="device_name_warning">একটি ডিভাইসের সর্বজনীন নাম আপনি যাদের সাথে যোগাযোগ করেন তাদের কাছে দৃশ্যমান</string>
+    <string name="device_name_warning">একটি সেশানের সর্বজনীন নাম আপনি যাদের সাথে যোগাযোগ করেন তাদের কাছে দৃশ্যমান</string>
     <string name="room_widget_activity_title">উইজেট</string>
     <string name="room_widget_permission_title">উইজেট লোড করুন</string>
     <string name="room_widget_permission_added_by">এই উইজেটটি যুক্ত করেছেন:</string>
@@ -1192,4 +1192,76 @@
     <string name="markdown_has_been_disabled">মার্কডাউন অক্ষম করা হয়েছে।</string>
 
     <string name="notification_off">অফ</string>
+    <string name="login_error_no_homeserver_found">এটি কোনও বৈধ ম্যাট্রিক্স সার্ভারের ঠিকানা নয়</string>
+    <string name="notification_silent">নিঃশব্দ</string>
+    <string name="notification_noisy">সশব্দ</string>
+
+    <string name="create">সৃষ্টি</string>
+    <string name="create_community">সম্প্রদায় তৈরি করুন</string>
+    <string name="community_name">সম্প্রদায়ের নাম</string>
+    <string name="community_name_hint">উদাহরণ</string>
+    <string name="community_id">সম্প্রদায়ের আইডি</string>
+    <string name="community_id_hint">উদাহরণ</string>
+
+    <string name="group_details_home">ঘর</string>
+    <string name="group_details_people">লোক</string>
+    <string name="group_details_rooms">ঘরগুলি</string>
+    <string name="no_users_placeholder">কোন ব্যবহারকারি নেই</string>
+
+    <string name="rooms">ঘরগুলি</string>
+    <string name="invited">আমন্ত্রিত</string>
+    <string name="filter_group_members">গোষ্ঠীর সদস্যদের ফিল্টার করুন</string>
+    <string name="filter_group_rooms">গোষ্ঠীর ঘরগুলো ফিল্টার করুন</string>
+
+    <plurals name="group_members">
+        <item quantity="one">১ জন সদস্য</item>
+        <item quantity="other">%d জন সদস্য</item>
+    </plurals>
+
+    <plurals name="group_rooms">
+        <item quantity="one">১ টি ঘর</item>
+        <item quantity="other">%d টি ঘর</item>
+    </plurals>
+    <string name="group_no_long_description">সম্প্রদায় প্রশাসক এই সম্প্রদায়ের জন্য দীর্ঘ বিবরণ সরবরাহ করেনি।</string>
+
+    <string name="has_been_banned">%2$s দ্বারা আপনাকে %1$s থেকে নিষিদ্ধ করা হয়েছে।</string>
+    <string name="reason_colon">কারণ: %1$s</string>
+    <string name="rejoin">পুনরায় যুক্ত</string>
+    <string name="forget_room">ঘর ভুলে যান</string>
+
+    <string name="receipt_avatar">রিসিপ্ট অবতার</string>
+    <string name="notice_avatar">অবতার নোট করুন</string>
+    <string name="avatar">আবতার</string>
+
+    <string name="dialog_user_consent_content">"%1$s হোমসার্ভারটি ব্যবহার চালিয়ে যেতে আপনাকে অবশ্যই শর্তাদিটি কে পর্যালোচনা এবং সম্মত  করতে হবে।"</string>
+    <string name="dialog_user_consent_submit">এখনই পর্যালোচনা করুন</string>
+
+    <string name="deactivate_account_title">অ্যাকাউন্ট নিষ্ক্রিয় করুন</string>
+    <string name="deactivate_account_content">এটি আপনার অ্যাকাউন্টকে স্থায়ীভাবে অকেজো করে তুলবে। আপনি লগ ইন করতে সক্ষম হবেন না এবং কেউ একই ব্যবহারকারীর আইডি পুনরায় নিবন্ধন করতে সক্ষম হবেন না। এটি আপনার অ্যাকাউন্টের অংশ নিচ্ছে এমন সমস্ত কক্ষ ছেড়ে দেবে এবং এটি আপনার পরিচয় সার্ভার থেকে আপনার অ্যাকাউন্টের বিশদ সরিয়ে দেবে। <b> এই ক্রিয়াটি অপরিবর্তনীয় </b>।
+\n
+\nআপনার অ্যাকাউন্টটি নিষ্ক্রিয় করা <b> ডিফল্টরূপে আমাদের পাঠানো বার্তাগুলি ভুলে যাওয়ার কারণ নয় </b>। আপনি যদি আমাদের বার্তা ভুলে যেতে চান তবে দয়া করে নীচের বাক্সটি টিক দিন।
+\n
+\nম্যাট্রিক্সে বার্তার দৃশ্যমানতা ইমেলের অনুরূপ। আমাদের আপনার বার্তাগুলি ভুলে যাওয়ার অর্থ হ\'ল আপনি যে বার্তাগুলি প্রেরণ করেছেন সেগুলি কোনও নতুন বা নিবন্ধিত ব্যবহারকারীদের সাথে ভাগ করা হবে না, তবে নিবন্ধিত ব্যবহারকারীরা যাদের ইতিমধ্যে এই বার্তাগুলিতে অ্যাক্সেস রয়েছে তাদের কপিটিতে এখনও অ্যাক্সেস থাকবে।</string>
+    <string name="deactivate_account_delete_checkbox">আমার অ্যাকাউন্টটি নিষ্ক্রিয় করার সময় আমি যে সমস্ত বার্তা প্রেরণ করেছি তা ভুলে যান (সতর্কতা: এটি ভবিষ্যতের ব্যবহারকারীদের কথোপকথনের একটি অসম্পূর্ণ দৃশ্য দেখতে পাবে)</string>
+    <string name="deactivate_account_prompt_password">চালিয়ে যেতে, দয়া করে আপনার পাসওয়ার্ড লিখুন:</string>
+    <string name="deactivate_account_submit">অ্যাকাউন্ট নিষ্ক্রিয় করুন</string>
+
+    <string name="error_empty_field_enter_user_name">দয়া করে একটি ব্যবহারকারীর নাম লিখুন।</string>
+    <string name="error_empty_field_your_password">আপনার পাসওয়ার্ড দিন।</string>
+    <string name="room_tombstone_versioned_description">এই ঘরটি প্রতিস্থাপন করা হয়েছে এবং এটি আর সক্রিয় নেই</string>
+    <string name="room_tombstone_continuation_link">কথোপকথন এখানে অবিরত</string>
+    <string name="room_tombstone_continuation_description">এই ঘরটি অন্য কথোপকথনের একটি ধারাবাহিকতা</string>
+    <string name="room_tombstone_predecessor_link">পুরানো বার্তা দেখতে এখানে ক্লিক করুন</string>
+
+    <string name="resource_limit_exceeded_title">সংস্থান সীমা অতিক্রম করেছে</string>
+    <string name="resource_limit_contact_action">প্রশাসকের সাথে যোগাযোগ করুন</string>
+
+    <string name="resource_limit_contact_admin">আপনার পরিষেবা প্রশাসকের সাথে যোগাযোগ করুন</string>
+
+    <string name="resource_limit_soft_default">এই হোমসার্ভারটি এর একটি রিসোর্স সীমা অতিক্রম করেছে সুতরাং <b> কিছু ব্যবহারকারী লগ ইন করতে পারবেন না </b>।</string>
+    <string name="resource_limit_hard_default">এই হোমসার্ভারটি এর অন্যতম এক রিসোর্স সীমা অতিক্রম করেছে।</string>
+
+    <string name="resource_limit_soft_mau"> এই হোমসার্ভারটি তার মাসিক অ্যাক্টিভ ব্যবহারকারীর সীমাটিতে আঘাত করেছে তাই <b> কিছু ব্যবহারকারী লগ ইন করতে পারবেন না </b>।</string>
+    <string name="resource_limit_hard_mau">এই হোমসার্ভারটি তার মাসিক সক্রিয় ব্যবহারকারীর সীমাতে ছুঁয়েছে।</string>
+
 </resources>
diff --git a/vector/src/main/res/values-cs/strings.xml b/vector/src/main/res/values-cs/strings.xml
index bbbc7b5af4..3722dca202 100644
--- a/vector/src/main/res/values-cs/strings.xml
+++ b/vector/src/main/res/values-cs/strings.xml
@@ -1,9 +1,9 @@
 <?xml version='1.0' encoding='UTF-8'?>
 <resources>
-    <string name="light_theme">Světlý motiv</string>
-    <string name="black_them">Černý motiv</string>
+    <string name="light_theme">Světlý vzhled</string>
+    <string name="black_them">Černý vzhled</string>
 
-    <string name="dark_theme">Tmavý motiv</string>
+    <string name="dark_theme">Tmavý vzhled</string>
     <string name="title_activity_home">Zprávy</string>
     <string name="title_activity_room">Místnost</string>
     <string name="title_activity_settings">Nastavení</string>
@@ -28,7 +28,7 @@
     <string name="resources_country_code">CZ</string>
 
     <string name="forget_room">Zapomenout místnost</string>
-    <string name="notification_sync_in_progress">Synchronizuji..</string>
+    <string name="notification_sync_in_progress">Probíhá synchronizace…</string>
     <string name="notification_noisy_notifications">Hlasitá oznámení</string>
     <string name="notification_silent_notifications">Tichá oznámení</string>
 
@@ -46,8 +46,8 @@
     <string name="view_decrypted_source">Zobraz dešifrovaný zdroj</string>
     <string name="report_content">Nahlásit obsah</string>
     <string name="active_call">Aktivní hovor</string>
-    <string name="ongoing_conference_call">Probíhající konferenční hovor.
-\nPřipojit se jako %1$s nebo %2$s.</string>
+    <string name="ongoing_conference_call">Probíhající konferenční hovor. 
+\nPřipojit se jako %1$s nebo %2$s</string>
     <string name="ongoing_conference_call_voice">Hlasem</string>
     <string name="ongoing_conference_call_video">Videem</string>
     <string name="cannot_start_call">Nemohu spustit hovor, prosím zkusit později</string>
@@ -72,7 +72,7 @@
     <string name="disable">Zakázat</string>
 
     <string name="dialog_title_confirmation">Potvrzení</string>
-    <string name="dialog_title_warning">Upozornění</string>
+    <string name="dialog_title_warning">Varování</string>
 
     <string name="bottom_action_home">Domů</string>
     <string name="bottom_action_favourites">Oblíbené</string>
@@ -99,13 +99,12 @@
 
     <string name="rooms_header">Místnosti</string>
     <string name="rooms_directory_header">Adresář místností</string>
-    <string name="no_room_placeholder">Žádne místností</string>
+    <string name="no_room_placeholder">Žádné místnosti</string>
     <string name="no_public_room_placeholder">Žádné veřejné mistnosti nejsou k dispozici</string>
     <plurals name="public_room_nb_users">
-        <item quantity="one">1 uživatel</item>
+        <item quantity="one">Jeden uživatel</item>
         <item quantity="few">%d uživatelé</item>
-        <item quantity="many">%d uživatelé</item>
-        <item quantity="other" />
+        <item quantity="other">%d uživatelů</item>
     </plurals>
 
     <string name="groups_invite_header">Pozvat</string>
@@ -140,9 +139,9 @@
     <string name="start_voice_call">Začít hlasový hovor</string>
     <string name="start_video_call">Začít video hovor</string>
 
-    <string name="start_new_chat_prompt_msg">Jste si jisti, že chcete začít nový rozhovor s %s?</string>
-    <string name="start_voice_call_prompt_msg">Jste si jisti, že chcete zahájit hlasový hovor?</string>
-    <string name="start_video_call_prompt_msg">Jste si jisti, že chcete zahájit video hovor?</string>
+    <string name="start_new_chat_prompt_msg">Opravdu chcete začít novou konverzaci s %s\?</string>
+    <string name="start_voice_call_prompt_msg">Opravdu chcete zahájit hlasový hovor\?</string>
+    <string name="start_video_call_prompt_msg">Opravdu chcete zahájit videohovor\?</string>
 
     <string name="option_send_files">Odeslat soubory</string>
     <string name="option_take_photo_video">Pořídit fotku nebo video</string>
@@ -153,9 +152,9 @@
     <string name="auth_register">Vytvořit účet</string>
     <string name="auth_submit">Potvrdit</string>
     <string name="auth_skip">Přeskočit</string>
-    <string name="auth_send_reset_email">Odeslat reset email</string>
+    <string name="auth_send_reset_email">Odeslat obnovovací e-mail</string>
     <string name="auth_return_to_login">Návrat na přihlašovací obrazovku</string>
-    <string name="auth_user_id_placeholder">Email nebo uživatelské jméno</string>
+    <string name="auth_user_id_placeholder">E-mail nebo uživatelské jméno</string>
     <string name="auth_password_placeholder">Heslo</string>
     <string name="auth_new_password_placeholder">Nové heslo</string>
     <string name="auth_user_name_placeholder">Uživatelské jméno</string>
@@ -169,33 +168,33 @@
     <string name="auth_invalid_user_name">Uživatelské jméno může obsahovat pouze písmena, číslice, tečky, pomlčky a podtržítka</string>
     <string name="auth_invalid_password">Heslo je velmi krátké (min 6)</string>
     <string name="auth_missing_password">Chybí heslo</string>
-    <string name="auth_invalid_email">Zdá se, že toto není platná emailová adresa</string>
+    <string name="auth_invalid_email">Zdá se, že toto není platná e-mailová adresa</string>
     <string name="auth_invalid_phone">Zdá se, že toto není platné telefonní číslo</string>
-    <string name="auth_email_already_defined">Tato emailová adresa je již použita.</string>
-    <string name="auth_missing_email">Chybí emailová adresa</string>
+    <string name="auth_email_already_defined">Tato e-mailová adresa je již použita.</string>
+    <string name="auth_missing_email">Chybí e-mailová adresa</string>
     <string name="auth_missing_phone">Chybí telefonní číslo</string>
-    <string name="auth_missing_email_or_phone">Chybí emailová adresa nebo telefonní číslo</string>
+    <string name="auth_missing_email_or_phone">Chybí e-mailová adresa nebo telefonní číslo</string>
     <string name="auth_invalid_token">Neplatný token</string>
     <string name="auth_password_dont_match">Hesla se neshodují</string>
     <string name="auth_forgot_password">Zapomenuté heslo?</string>
     <string name="auth_use_server_options">Použít vlastní možnosti serveru (pokročilé)</string>
-    <string name="auth_email_validation_message">Prosím zkontrolujte své emaily, abyste mohli pokračovat v registraci</string>
+    <string name="auth_email_validation_message">Prosím zkontrolujte své e-maily, abyste mohli pokračovat v registraci</string>
     <string name="auth_recaptcha_message">Tento domovský server by se rád přesvědčil, že nejste robot</string>
     <string name="auth_username_in_use">Uživatelské jméno je použito</string>
     <string name="auth_home_server">Domácí server:</string>
     <string name="auth_identity_server">Server identity:</string>
     <string name="auth_reset_password_next_step_button">Ověřil/a jsem svoji e-mailovou adresu</string>
     <string name="auth_reset_password_message">K resetování hesla vložte e-mailovou adresu spojenou s vaším účtem:</string>
-    <string name="auth_reset_password_missing_email">Musíte zadat emailovou adresu spojenou s vaším účtem.</string>
+    <string name="auth_reset_password_missing_email">Musíte zadat e-mailovou adresu spojenou s vaším účtem.</string>
     <string name="auth_reset_password_missing_password">Musíte zadat nové heslo.</string>
-    <string name="auth_reset_password_email_validation_message">Na adresu %s byla odeslána zpráva. Potom, co přejdete na odkaz z této zprávy, klikněte níže.</string>
-    <string name="auth_reset_password_error_unauthorized">E-mailovou adresu se nepodařilo ověřit. Přesvědčte se, že jste kliknul/a na zaslaný odkaz</string>
+    <string name="auth_reset_password_email_validation_message">Na adresu %s byla odeslána zpráva. Potom, co přejdete na odkaz z této zprávy, klepněte níže.</string>
+    <string name="auth_reset_password_error_unauthorized">E-mailovou adresu se nepodařilo ověřit. Přesvědčte se, že jste klepli na zaslaný odkaz</string>
     <string name="login_error_must_start_http">URL musí začínat s http[s]://</string>
     <string name="login_error_network_error">Nelze se příhlásit: Síťová chyba</string>
     <string name="login_error_unable_login">Nelze se příhlásit</string>
     <string name="login_error_registration_network_error">Nelze se registrovat: Síťová chyba</string>
     <string name="login_error_unable_register">Nelze se registrovat</string>
-    <string name="login_error_unable_register_mail_ownership">Nelze se registrovat: chyba oveření vlastnictví emailu</string>
+    <string name="login_error_unable_register_mail_ownership">Nelze se registrovat: chyba ověření vlastnictví e-mailu</string>
     <string name="login_error_invalid_home_server">Prosím, zadejte platné URL</string>
     <string name="login_mobile_device">Mobil</string>
 
@@ -203,7 +202,7 @@
     <string name="login_error_bad_json">Poškozený JSON</string>
     <string name="login_error_limit_exceeded">Příliš mnoho požadavků bylo odeslano</string>
     <string name="login_error_user_in_use">Toto uživatelské jméno je již použito</string>
-    <string name="status_theme">Motiv Status.im</string>
+    <string name="status_theme">Motiv vzhledu Status.im</string>
 
     <string name="title_activity_choose_sticker">Odeslat nálepku</string>
 
@@ -240,19 +239,19 @@
 
 Vaši e-mailovou adresu můžete přidat k profilu v nastavení.</string>
     <string name="auth_reset_password_success_message">Vaše heslo bylo obnoveno. 
-\n
-\nByli jste odhlášeni ze všech relací a již nebudete dostávat oznámení. Pro opětovnou aktivaci oznámení se znovu přihlašte na každém zařízení.</string>
+\n 
+\nByli jste odhlášeni ze všech relací a již nebudete dostávat oznámení. Pro opětovnou aktivaci oznámení se znovu přihlaste na každém zařízení.</string>
     <string name="auth_accept_policies">Prosím, přečtěte si a souhlaste s pravidly tohoto serveru:</string>
 
     <string name="login_error_unknown_token">Přistupový token nebyl rozpoznán</string>
     <string name="login_error_not_json">Neobsahuje platný JSON</string>
-    <string name="login_error_login_email_not_yet">E-mailový odkaz, na který ještě nebylo kliknuto</string>
+    <string name="login_error_login_email_not_yet">E-mailový odkaz, na který ještě nebylo klepnuto</string>
 
-    <string name="e2e_need_log_in_again">Je nutné se znovu přihlásit, aby byly vygenerovány E2E šifrovací klíče pro toto zařízení a odeslán veřejný klíč Vašemu homeserveru.
+    <string name="e2e_need_log_in_again">Je nutné se znovu přihlásit, aby byly vygenerovány E2E šifrovací klíče pro toto zařízení a odeslán veřejný klíč vašemu homeserveru.
 \nToto je nutné pouze jednou. 
 \nOmlouváme se za způsobené nepříjemnosti.</string>
 
-    <string name="e2e_re_request_encryption_key"><u>Znovu požádat o šifrovací klíče </u> z Vašich ostatních relací.</string>
+    <string name="e2e_re_request_encryption_key">Znovu požádat o šifrovací klíče z vašich ostatních relací.</string>
 
     <string name="e2e_re_request_encryption_key_sent">Žádost o klíče odeslána.</string>
 
@@ -358,33 +357,29 @@ Vaši e-mailovou adresu můžete přidat k profilu v nastavení.</string>
     </plurals>
     <string name="room_title_one_member">1 člen</string>
     <plurals name="format_time_s">
-        <item quantity="one">1s</item>
-        <item quantity="few">%ds</item>
-        <item quantity="many">%ds</item>
-        <item quantity="other" />
+        <item quantity="one">1 s</item>
+        <item quantity="few">%d s</item>
+        <item quantity="other">%d s</item>
     </plurals>
     <plurals name="format_time_m">
-        <item quantity="one">1min</item>
-        <item quantity="few">%dmin</item>
-        <item quantity="many">%dmin</item>
-        <item quantity="other" />
+        <item quantity="one">1 min</item>
+        <item quantity="few">%d min</item>
+        <item quantity="other">%d min</item>
     </plurals>
     <plurals name="format_time_h">
-        <item quantity="one">1h</item>
-        <item quantity="few">%dh</item>
-        <item quantity="many">%dh</item>
-        <item quantity="other" />
+        <item quantity="one">1 h</item>
+        <item quantity="few">%d h</item>
+        <item quantity="other">%d h</item>
     </plurals>
     <plurals name="format_time_d">
-        <item quantity="one">1d</item>
-        <item quantity="few">%dd</item>
-        <item quantity="many">%dd</item>
-        <item quantity="other" />
+        <item quantity="one">1 d</item>
+        <item quantity="few">%d d</item>
+        <item quantity="other">%d d</item>
     </plurals>
 
     <string name="room_participants_leave_prompt_title">Opustit místnost</string>
-    <string name="room_participants_leave_prompt_msg">Jste si jisti, že chcete opustit tuto místnost?</string>
-    <string name="room_participants_remove_prompt_msg">Jste si jisti, že chcete vyhodit %s z této konverzace?</string>
+    <string name="room_participants_leave_prompt_msg">Opravdu chcete opustit tuto místnost\?</string>
+    <string name="room_participants_remove_prompt_msg">Opravdu chcete vyhodit %s z této konverzace\?</string>
     <string name="room_participants_create">Vytvořit</string>
 
     <string name="room_participants_online">On-line</string>
@@ -415,15 +410,14 @@ Vaši e-mailovou adresu můžete přidat k profilu v nastavení.</string>
     <string name="room_preview_room_interactions_disabled">Toto je náhled místnosti. Interakce s místností byla vypnuta.</string>
 
     <plurals name="room_participants_kick_prompt_msg">
-        <item quantity="one">Jste si jisti, že chcete vyhodit tohoto uživatele z této konverzace?</item>
-        <item quantity="few">Jste si jisti, že chcete vyhodit tyto uživatele z této konverzace?</item>
-        <item quantity="many">Jste si jisti, že chcete vyhodit tyto uživatele z této konverzace?</item>
-        <item quantity="other" />
+        <item quantity="one">Opravdu chcete vyhodit tohoto uživatele z této konverzace\?</item>
+        <item quantity="few">Opravdu chcete vyhodit tyto uživatele z této konverzace\?</item>
+        <item quantity="other">Opravdu chcete vyhodit tyto uživatele z této konverzace\?</item>
     </plurals>
-    <string name="room_participants_ban_prompt_msg">Jste si jisti, že chcete zakázat vstup tohoto uživatele do této konverzace?</string>
+    <string name="room_participants_ban_prompt_msg">Opravdu chcete zakázat vstup tohoto uživatele do této konverzace\?</string>
     <string name="reason_hint">Důvod</string>
 
-    <string name="room_participants_invite_prompt_msg">Jste si jisti, že chcete pozvat %s do této konverzace?</string>
+    <string name="room_participants_invite_prompt_msg">Opravdu chcete pozvat uživatele %s do této konverzace\?</string>
     <string name="room_participants_invite_join_names">"%1$s, "</string>
     <string name="room_participants_invite_join_names_and">%1$s a %2$s</string>
     <string name="room_participants_invite_join_names_combined">%1$s %2$s</string>
@@ -478,43 +472,43 @@ Vaši e-mailovou adresu můžete přidat k profilu v nastavení.</string>
     <string name="title_activity_keys_backup_setup">Záloha klíče</string>
     <string name="title_activity_keys_backup_restore">Použít zálohu klíče</string>
 
-    <string name="keys_backup_is_not_finished_please_wait">Záloha klíče není ještě dokončena, prosím počkejte…</string>
-    <string name="sign_out_bottom_sheet_warning_no_backup">Pokud se nyní odhlásíte, ztratíte vaše zašifrované zprávy</string>
-    <string name="sign_out_bottom_sheet_warning_backing_up">Probíhá záloha klíče. Pokud se nyní odhlásíte, ztratíte přístup k vašim zašifrovaným zprávám.</string>
+    <string name="keys_backup_is_not_finished_please_wait">Záloha klíčů není ještě dokončena, prosím počkejte…</string>
+    <string name="sign_out_bottom_sheet_warning_no_backup">Pokud se nyní odhlásíte, přijdete o své zašifrované zprávy</string>
+    <string name="sign_out_bottom_sheet_warning_backing_up">Probíhá záloha klíče. Pokud se nyní odhlásíte, ztratíte přístup ke svým zašifrovaným zprávám.</string>
     <string name="sign_out_bottom_sheet_warning_backup_not_active">Zabezpečená záloha klíčů by měla být aktivní na všech vašich relacích, aby se předešlo ztrátě přístupu k vašim zašifrovaným zprávám.</string>
     <string name="sign_out_bottom_sheet_dont_want_secure_messages">Nechci své zašifrované zprávy</string>
     <string name="sign_out_bottom_sheet_backing_up_keys">Zálohuji klíče…</string>
     <string name="keys_backup_activate">Použít zálohu klíče</string>
-    <string name="are_you_sure">Jste si jisti\?</string>
+    <string name="are_you_sure">Opravdu\?</string>
     <string name="backup">Záloha</string>
-    <string name="sign_out_bottom_sheet_will_lose_secure_messages">Pokud neprovedete zálohu vašich klíčů před odhlášením, ztratíte přístup k vašim zašifrovaným zprávám.</string>
+    <string name="sign_out_bottom_sheet_will_lose_secure_messages">Pokud nezazálohujete své klíče před odhlášením, přijdete o přístup ke svým zašifrovaným zprávám.</string>
 
     <string name="stay">Zůstat</string>
     <string name="skip">Přeskočit</string>
     <string name="done">Hotovo</string>
     <string name="abort">Přerušit</string>
 
-    <string name="action_sign_out_confirmation_simple">Jste si jisti, že se chcete odhlásit\?</string>
+    <string name="action_sign_out_confirmation_simple">Opravdu se chcete odhlásit\?</string>
     <string name="video_call_in_progress">Probíhá video hovor…</string>
 
     <string name="permissions_rationale_msg_camera_and_audio">Riot potřebuje oprávnění pro přístup k Vaší kameře a mikrofonu pro uskutečnění video hovoru.
 \n
 \nProsím, povolte přístup na následující hlášce abyste mohli uskutečnit hovor.</string>
-    <string name="permissions_rationale_msg_contacts">Riot může nahlédnout do Vašeho adresáře, aby nalezl ostatní uživatele Matrixu na základě jejich emailu a telefonního čísla. Pokud souhlasíte se sdílením svého adresáře za tímto účelem, prosím, povolte přístup v příští hlášce.</string>
-    <string name="permissions_msg_contacts_warning_other_androids">Riot může nahlédnout do Vašeho adresáře, aby nalezl ostatní uživatele Matrixu na základě jejich emailu a telefonního čísla. 
+    <string name="permissions_rationale_msg_contacts">Riot může nahlédnout do vašeho adresáře, aby nalezl ostatní uživatele Matrixu na základě jejich e-mailu a telefonního čísla. Pokud souhlasíte se sdílením svého adresáře za tímto účelem, prosím, povolte přístup v příští hlášce.</string>
+    <string name="permissions_msg_contacts_warning_other_androids">Riot může nahlédnout do vašeho adresáře, aby nalezl ostatní uživatele Matrixu na základě jejich e-mailu a telefonního čísla. 
 \n 
-\nSouhlasíte se sdílením svěho adresáře za tímto účelem\?</string>
+\nSouhlasíte se sdílením svého adresáře za tímto účelem\?</string>
 
     <string name="room_preview_unlinked_email_warning">Pozvánka byla odeslána na %s, což není spárováno s tímto účtem. 
-\nPřihlaste se s jiným účtem nebo přidejte tento email k svému současnému účtu.</string>
+\nPřihlaste se s jiným účtem nebo přidejte tento e-mail ke svému současnému účtu.</string>
     <string name="room_preview_try_join_an_unknown_room">Snažíte se přistupovat k %s. Chcete vstoupit, abyste se mohli podílet na diskuzi\?</string>
     <string name="room_participants_action_unignore_prompt">Zobrazit všechny zprávy od tohoto uživatele\?
 \n
 \nTato akce provede restart aplikace a může nějakou dobu trvat.</string>
-    <string name="room_participants_power_level_prompt">Nebudete schopni tuto změnu vrátit protože povyšujete uživatele na stejnou úroveň jako jste vy.
-\nJste si jisti\?</string>
+    <string name="room_participants_power_level_prompt">Tuto změnu nelze vrátit, protože povyšujete uživatele na stejnou úroveň, jakou máte vy. 
+\nOpravdu to chcete udělat\?</string>
 
-    <string name="people_search_invite_by_id_dialog_description">Prosím zadejte jednu nebo více emailových adres nebo Matrix ID</string>
+    <string name="people_search_invite_by_id_dialog_description">Prosím zadejte jednu nebo více e-mailových adres nebo Matrix ID</string>
     <string name="room_unknown_devices_messages_notification">Zprávy nebyly odeslány z důvodu přítomnosti neznámých relací. %1$s nebo %2$s nyní\?</string>
     <string name="ssl_cert_not_trust">Toto by mohlo znamenat, že někdo škodlivě zachytává Vaši komunikaci nebo že Váš telefon nedůvěřuje certifikátu poskytnutému vzdáleným serverem.</string>
     <string name="ssl_cert_new_account_expl">Pokud administrátor serveru řekl že toto je předpokládané, ujistěte se, že otisk níže se shoduje s otiskem který Vám poskytl.</string>
@@ -522,7 +516,7 @@ Vaši e-mailovou adresu můžete přidat k profilu v nastavení.</string>
     <string name="ssl_expected_existing_expl">Certifikát se změnil z předtím důvěryhodného na nyní nedůvěryhodný. Server mohl obnovit svůj certifikát. Kontaktujte administrátora pro ověření předpokládaného otisku.</string>
     <string name="ssl_only_accept">Přijměte certifikát pouze pokud administrátor serveru publikoval otisk který odpovídá tomu uvedenému výše.</string>
 
-    <string name="malformed_id">Neplatné ID. Mělo by být buď emailová adresa nebo Matrix ID např. \'@localpart:domain\'</string>
+    <string name="malformed_id">Neplatné ID. Mělo by být buď e-mailová adresa nebo Matrix ID např. \'@localpart:example.com\'</string>
     <string name="room_details_people_invited_group_name">POZVÁN</string>
     <string name="room_details_people_present_group_name">PŘIPOJEN</string>
 
@@ -588,19 +582,19 @@ Vaši e-mailovou adresu můžete přidat k profilu v nastavení.</string>
 
     <string name="settings_profile_picture">Profilová fotografie</string>
     <string name="settings_display_name">Zobrazované jméno</string>
-    <string name="settings_email_address">Email</string>
-    <string name="settings_add_email_address">Přidat emailovou adresu</string>
+    <string name="settings_email_address">E-mail</string>
+    <string name="settings_add_email_address">Přidat e-mailovou adresu</string>
     <string name="settings_phone_number">Telefon</string>
     <string name="settings_add_phone_number">Přidat telefonní číslo</string>
     <string name="settings_app_info_link_title">Informace o aplikaci</string>
     <string name="settings_app_info_link_summary">Zobrazit informace o aplikaci v systémovém nastavení.</string>
 
 
-    <string name="settings_notification_advanced">Pokročilé nestavení upozornění</string>
-    <string name="settings_notification_advanced_summary">Nastavit důležitost upozornění na základě události, nastavení zvuku, LED, vibrací</string>
-    <string name="settings_notification_by_event">Důležitost upozornění na základě události</string>
+    <string name="settings_notification_advanced">Rozšířená nestavení oznámení</string>
+    <string name="settings_notification_advanced_summary">Nastavit důležitost oznámení na základě události, nastavení zvuku, LED, vibrací</string>
+    <string name="settings_notification_by_event">Důležitost oznámení na základě události</string>
 
-    <string name="notification_sync_init">Inicializuji službu</string>
+    <string name="notification_sync_init">Spouštím služby</string>
     <string name="title_activity_verify_device">Ověřte relaci</string>
 
     <string name="disconnect">Odpojit</string>
@@ -623,10 +617,10 @@ Vaši e-mailovou adresu můžete přidat k profilu v nastavení.</string>
     <string name="call_failed_dont_ask_again">Dále se netázat</string>
 
     <string name="auth_login_sso">Přihlásit se se single sign-on</string>
-    <string name="auth_add_email_message_2">Nastavte email pro obnovení účtu a volitelně aby jej později lidé, kteří Vás znají, mohli najít.</string>
+    <string name="auth_add_email_message_2">Nastavte e-mail pro obnovení účtu a volitelně aby jej později lidé, kteří vás znají, mohli najít.</string>
     <string name="auth_add_phone_message_2">Nastavte telefonní číslo, aby později bylo volitelně k nalezení lidmi, kteří Vás znají.</string>
-    <string name="auth_add_email_phone_message_2">Nastavte email pro obnovení účtu. Použijte email nebo telefonní číslo volitelně později, aby je našli lidé, kteří Vás znají.</string>
-    <string name="auth_add_email_and_phone_message_2">Nastavte email pro obnovení účtu. Použijte email nebo telefonní číslo volitelně později, aby je našli lidé, kteří Vás znají.</string>
+    <string name="auth_add_email_phone_message_2">Nastavte e-mail pro obnovení účtu. Použijte e-mail nebo telefonní číslo volitelně později, aby je našli lidé, kteří vás znají.</string>
+    <string name="auth_add_email_and_phone_message_2">Nastavte e-mail pro obnovení účtu. Použijte e-mail nebo telefonní číslo volitelně později, aby je našli lidé, kteří vás znají.</string>
     <string name="login_error_unknown_host">Toto URL není dostupné, prosím, prověřte</string>
     <string name="login_error_no_homeserver_found">To není platná adresa Matrix serveru</string>
     <string name="login_error_homeserver_not_found">Homeserver není dostupný na tomto URL, prosím, prověřte</string>
@@ -640,35 +634,35 @@ Vaši e-mailovou adresu můžete přidat k profilu v nastavení.</string>
 
 
     <string name="settings_notification_privacy">Soukromí oznámení</string>
-    <string name="settings_notification_troubleshoot">Řešit oznámení</string>
+    <string name="settings_notification_troubleshoot">Problém s oznámeními</string>
     <string name="settings_troubleshoot_diagnostic">Řešit diagnostiku</string>
     <string name="settings_troubleshoot_diagnostic_run_button_title">Spustit testy</string>
     <string name="settings_troubleshoot_diagnostic_running_status">Spouštím… (%1$d z %2$d)</string>
-    <string name="settings_troubleshoot_diagnostic_success_status">Základní diagnostika je ok. Pokud stále ještě nedocházejí oznámení, prosím, pomůžete nám s vyšetřováním, nahlásíte-li chybu.</string>
+    <string name="settings_troubleshoot_diagnostic_success_status">Základní diagnostika je OK. Pokud stále ještě nedostáváte oznámení, pomůžete nám s vyšetřováním, nahlásíte-li nám to jako chybu.</string>
     <string name="settings_troubleshoot_diagnostic_failure_status_with_quickfix">Jeden či více testů selhalo, zkuste navržené opravy.</string>
     <string name="settings_troubleshoot_diagnostic_failure_status_no_quickfix">Jeden či více testů selhalo, prosím, pomůžete nám s vyšetřováním, nahlásíte-li chybu.</string>
 
     <string name="settings_troubleshoot_test_system_settings_title">Systémová nastavení.</string>
-    <string name="settings_troubleshoot_test_system_settings_success">Oznámení jsou zapnuta v systémových nastavení.</string>
-    <string name="settings_troubleshoot_test_system_settings_failed">Oznámení jsou vypnuta v systémových nastavení.
+    <string name="settings_troubleshoot_test_system_settings_success">Oznámení jsou zapnuta v nastavení systému.</string>
+    <string name="settings_troubleshoot_test_system_settings_failed">Oznámení jsou vypnuta v nastavení systému. 
 \nProsím, prověřte systémová nastavení.</string>
     <string name="open_settings">Otevřít nastavení</string>
 
     <string name="settings_troubleshoot_test_account_settings_title">Nastavení účtu.</string>
-    <string name="settings_troubleshoot_test_account_settings_success">Oznámení jsou zapnuta pro Váš účet.</string>
-    <string name="settings_troubleshoot_test_account_settings_failed">Oznámení jsou vypnuta pro Váš účet.
-\nProsím, prověřte systémová nastavení.</string>
+    <string name="settings_troubleshoot_test_account_settings_success">Oznámení jsou pro vás účet zapnuta.</string>
+    <string name="settings_troubleshoot_test_account_settings_failed">Oznámení jsou pro váš účet vypnuta. 
+\nProsím, prověřte nastavení systému.</string>
     <string name="settings_troubleshoot_test_account_settings_quickfix">Zapnout</string>
 
     <string name="settings_troubleshoot_test_device_settings_title">Nastavení relací.</string>
     <string name="settings_troubleshoot_test_device_settings_success">Oznámení jsou zapnuta pro tuto relaci.</string>
-    <string name="settings_troubleshoot_test_device_settings_failed">Oznámení nejosu zapnuta pro tuto relaci.
+    <string name="settings_troubleshoot_test_device_settings_failed">Oznámení nejsou zapnuta pro tuto relaci. 
 \nProsím, prověřte nastavení Riotu.</string>
     <string name="settings_troubleshoot_test_device_settings_quickfix">Zapnout</string>
 
     <string name="settings_troubleshoot_test_bing_settings_title">Vlastní nastavení.</string>
-    <string name="settings_troubleshoot_test_bing_settings_success_with_warn">Všimněte si, že některé typy zpráv jsou jsou umlčeny (vyvolají oznámeni bez zvuku).</string>
-    <string name="settings_troubleshoot_test_bing_settings_failed">Některá oznámení jsou vypnuta ve vlastních nastavení.</string>
+    <string name="settings_troubleshoot_test_bing_settings_success_with_warn">Všimněte si, že některé typy zpráv jsou ztišeny (vyvolají oznámeni bez zvuku).</string>
+    <string name="settings_troubleshoot_test_bing_settings_failed">Některá oznámení jsou vypnuta ve vlastním nastavení.</string>
     <string name="settings_troubleshoot_test_bing_settings_failed_to_load_rules">Načtení vlastních pravidel selhalo, prosím, zkuste znovu.</string>
     <string name="settings_troubleshoot_test_bing_settings_quickfix">Kontrola nastavení</string>
 
@@ -698,8 +692,8 @@ Vaši e-mailovou adresu můžete přidat k profilu v nastavení.</string>
 
     <string name="settings_troubleshoot_test_foreground_service_started_title">Služba oznámení</string>
     <string name="settings_troubleshoot_test_foreground_service_startedt_success">Služba oznámení je v chodu.</string>
-    <string name="settings_troubleshoot_test_foreground_service_started_failed">Služba oznámení není v chodu.
-\nZkuste restarovat aplikaci.</string>
+    <string name="settings_troubleshoot_test_foreground_service_started_failed">Služba oznámení není v chodu. 
+\nZkuste restartovat aplikaci.</string>
     <string name="settings_troubleshoot_test_foreground_service_started_quickfix">Spustit službu</string>
 
     <string name="settings_troubleshoot_test_service_restart_title">Auto-restart služby oznámení</string>
@@ -721,7 +715,7 @@ Vaši e-mailovou adresu můžete přidat k profilu v nastavení.</string>
 
     <string name="settings_troubleshoot_test_battery_title">Optimalizace baterie</string>
     <string name="settings_troubleshoot_test_battery_success">Optimalizace baterie nemá na Riot vliv.</string>
-    <string name="settings_troubleshoot_test_battery_failed">Nechá-li uživatel zařízení vytažený ze zásuvky a v klidu po nějakou dobu a s obrazovkou vypnutou, zařízení vstoupí do stavu spánku. Ten zamezí aplikacím přístup k síti a odloží jejich úlohy, synchronizaci a standartní upozornění.</string>
+    <string name="settings_troubleshoot_test_battery_failed">Nechá-li uživatel zařízení vytažený ze zásuvky a v klidu po nějakou dobu a s obrazovkou vypnutou, zařízení vstoupí do stavu spánku. Ten zamezí aplikacím přístup k síti a odloží jejich úlohy, synchronizaci a běžná upozornění.</string>
     <string name="settings_troubleshoot_test_battery_quickfix">Ignorovat optimalizaci</string>
 
     <string name="settings_notification_privacy_normal">Normální</string>
@@ -812,7 +806,7 @@ Vaši e-mailovou adresu můžete přidat k profilu v nastavení.</string>
     <string name="settings_always_show_timestamps">Zobrazit časovou značku u všech zpráv</string>
     <string name="settings_12_24_timestamps">Zobrazit časovou značku ve 12-hodinovém formátu</string>
     <string name="settings_show_read_receipts">Ukázat potvrzení o přečtení</string>
-    <string name="settings_show_read_receipts_summary">Kliknout na potvrzení o přečtení pro podrobnosti.</string>
+    <string name="settings_show_read_receipts_summary">Klepněte na potvrzení o přečtení pro podrobnosti.</string>
     <string name="settings_show_join_leave_messages">Ukázat události příchodů a odchodů</string>
     <string name="settings_show_join_leave_messages_summary">Nemá vliv na pozvánky, nakopnutí a zákazy.</string>
     <string name="settings_show_avatar_display_name_changes_messages">Ukázat události účtu</string>
@@ -868,12 +862,12 @@ Vaši e-mailovou adresu můžete přidat k profilu v nastavení.</string>
     <string name="settings_select_language">Zvolit jazyk</string>
 
     <string name="account_email_validation_title">Čekám na potvrzení</string>
-    <string name="account_email_validation_message">Prosím, zkontrolujte svůj email a klikněte na odkaz v něm. Jakmile hotovo, klikněte pokračovat.</string>
-    <string name="account_email_validation_error">Nemohu potvrdit emailovou adresu. Prosím, zkontrolujte svůj email a klikněte na odkaz v něm. Jakmile hotovo, klikněte pokračovat.</string>
-    <string name="account_email_already_used_error">Tato emailová adresa byla již zadána.</string>
-    <string name="account_email_not_found_error">Tato emailová adresa nebyla nalezena.</string>
+    <string name="account_email_validation_message">Prosím, zkontrolujte svůj e-mail a klepněte na odkaz v něm. Poté klepněte na pokračovat.</string>
+    <string name="account_email_validation_error">E-mailovou adresu nelze ověřit. Zkontrolujte svůj e-mail a klepněte na odkaz v něm. Poté klepněte na pokračovat.</string>
+    <string name="account_email_already_used_error">Tato e-mailová adresa byla již zadána.</string>
+    <string name="account_email_not_found_error">Tato e-mailová adresa nebyla nalezena.</string>
     <string name="account_phone_number_already_used_error">Toto telefonní číslo bylo již zadáno.</string>
-    <string name="account_email_error">Při potvrzování Vaší emailové adresy došlo k chybě.</string>
+    <string name="account_email_error">Při potvrzování vaší e-mailové adresy došlo k chybě.</string>
 
     <string name="settings_password">Heslo</string>
     <string name="settings_change_password">Změnit heslo</string>
@@ -888,9 +882,9 @@ Vaši e-mailovou adresu můžete přidat k profilu v nastavení.</string>
 \nPřipomínám, že tato akce restartuje aplikaci a může chvíli trvat.</string>
     <string name="passwords_do_not_match">Hesla se neshodují</string>
 
-    <string name="settings_delete_notification_targets_confirmation">Jste si jisti, že chcete odstranit tento cíl oznámení\?</string>
+    <string name="settings_delete_notification_targets_confirmation">Opravdu chcete odstranit tento cíl oznámení\?</string>
 
-    <string name="settings_delete_threepid_confirmation">Jste si jisti, že chcete odstranit %1$s %2$s\?</string>
+    <string name="settings_delete_threepid_confirmation">Opravdu chcete odstranit %1$s %2$s\?</string>
 
     <string name="settings_select_country">Vybrat zemi</string>
 
@@ -913,7 +907,7 @@ Vaši e-mailovou adresu můžete přidat k profilu v nastavení.</string>
     <string name="media_source_choose">Vybrat</string>
     <string name="settings_play_shutter_sound">Přehrát zvuk uzávěrky</string>
 
-    <string name="settings_flair">Flér</string>
+    <string name="settings_flair">Příslušnost ke skupinám</string>
     <string name="settings_without_flair">Zatím nejste členem žádné komunity.</string>
 
     <string name="media_saving_period_3_days">3 dny</string>
@@ -954,7 +948,7 @@ Vaši e-mailovou adresu můžete přidat k profilu v nastavení.</string>
     <string name="room_settings_category_advanced_title">Pokročilé</string>
     <string name="room_settings_room_internal_id">Interní ID této místnosti</string>
     <string name="room_settings_addresses_pref_title">Adresa</string>
-    <string name="room_settings_labs_pref_title">Labs</string>
+    <string name="room_settings_labs_pref_title">Experimentální funkce</string>
     <string name="room_settings_labs_warning_message">Toto jsou experimentální funkce, které mohou selhat neočekávanými způsoby. Použijte obezřetně.</string>
     <string name="room_settings_labs_end_to_end">Šifrování end-to-end</string>
     <string name="room_settings_labs_end_to_end_is_active">Šifrování end-to-end je aktivní</string>
@@ -987,7 +981,7 @@ Vaši e-mailovou adresu můžete přidat k profilu v nastavení.</string>
 \n(varování: nelze vypnout!)</string>
 
     <string name="directory_title">Adresář</string>
-    <string name="settings_theme">Motiv</string>
+    <string name="settings_theme">Motiv vzhledu</string>
 
     <string name="failed_to_load_timeline_position">%s se pokusil načíst určitý okamžik v historii této místnosti, ale nemohl jej najít.</string>
 
@@ -1045,4 +1039,1306 @@ Vaši e-mailovou adresu můžete přidat k profilu v nastavení.</string>
     <string name="encryption_information_unblock">Odebrat z černé listiny</string>
 
     <string name="encryption_information_verify_device">Potvrdit relaci</string>
+    <string name="font_size">Velikost písma</string>
+    <string name="tiny">Velmi malé</string>
+    <string name="small">Malé</string>
+    <string name="normal">Normální</string>
+    <string name="large">Velké</string>
+    <string name="larger">Větší</string>
+    <string name="largest">Největší</string>
+    <string name="huge">Obrovské</string>
+
+    <string name="login_signup_password_hint">Heslo</string>
+    <string name="login_signup_submit">Další</string>
+    <string name="soft_logout_signin_password_hint">Heslo</string>
+    <string name="encryption_information_verify_key_match">Potvrzuji, že klíče se shodují</string>
+
+    <string name="you_added_a_new_device">Přidal/a jste novou relaci \'%s\', která požaduje šifrovací klíče.</string>
+    <string name="keys_backup_setup_step1_manual_export">Exportovat klíče ručně</string>
+
+    <string name="keys_backup_setup_step3_text_line1">Probíhá zálohování vašich klíčů.</string>
+    <string name="keys_backup_setup_backup_started_message">Na pozadí právě probíhá zálohování vašich klíčů na domovský server. Prvotní zálohování může trvat několik minut.</string>
+
+
+    <string name="keys_backup_restoring_downloading_backup_waiting_message">Stahuji klíče…</string>
+    <string name="keys_backup_restoring_importing_keys_waiting_message">Importuji klíče…</string>
+    <plurals name="keys_backup_restore_success_description_part1">
+        <item quantity="one">Obnovena záloha s %d klíčem.</item>
+        <item quantity="few">Obnovena záloha s %d klíči.</item>
+        <item quantity="other">Obnovena záloha s %d klíči.</item>
+    </plurals>
+    <plurals name="keys_backup_restore_success_description_part2">
+        <item quantity="one">Do této relace byl přidán %d nový klíč.</item>
+        <item quantity="few">Do této relace byly přidány %d nové klíče.</item>
+        <item quantity="other">Do této relace bylo přidáno %d nových klíčů.</item>
+    </plurals>
+
+    <string name="keys_backup_banner_in_progress">Zálohuji klíče…</string>
+
+    <string name="keys_backup_info_keys_all_backup_up">Všechny klíče zazálohovány</string>
+    <plurals name="keys_backup_info_keys_backing_up">
+        <item quantity="one">Zálohuji %d klíč…</item>
+        <item quantity="few">Zálohuji %d klíče…</item>
+        <item quantity="other">Zálohuji %d klíčů…</item>
+    </plurals>
+
+    <string name="import_e2e_keys_from_file">Importovat e2e klíče ze souboru \"%1$s\".</string>
+
+    <string name="encryption_information_verify_device_warning">Abyste ověřili důvěryhodnost této relace, prosím, kontaktujte jejího majitele nějakým jiným způsobem (např. osobně nebo telefonátem) s otázkou, zda se klíč, jenž je zobrazen v jejich Nastavení uživatele, shoduje s klíčem níže:</string>
+    <string name="encryption_information_verify_device_warning2">Pokud se shoduje, klepněte na tlačítko ověřit. Pokud ne, pak někdo jiný zachycuje tuto relaci a měli byste je snad zadat na černou listinu. V budoucnu bude tento ověřovací proces sofistikovanější.</string>
+    <string name="e2e_enabling_on_app_update">Riot nyní podporuje šifrování end-to-end, ale pro aktivaci se musíte se opět přihlásit.
+\n
+\nMůžete to provést nyní nebo později z aplikačních nastavení.</string>
+
+    <string name="unknown_devices_alert_title">Místnost obsahuje neznámé relace</string>
+    <string name="unknown_devices_alert_message">Tato místnost obsahuje neznámé relace, která nebyla ověřena.
+\nNelze tedy zaručit, že sezení patří těm uživatelům, o nichž to tvrdí.
+\nDoporučujeme, abyste prošli ověřovacím procesem pro každou relaci, než budete pokračovat, ale můžete poslat zprávu bez ověření, pokud si tak přejete.
+\n
+\nNeznámé relace:</string>
+
+    <string name="select_room_directory">Vybrat adresář místností</string>
+    <string name="directory_server_fail_to_retrieve_server">Server je partně nedostupný nebo přetížený</string>
+    <string name="directory_server_type_homeserver">Zadejte homeserver, z něhož si žádáte seznam veřejných místností</string>
+    <string name="directory_server_placeholder">URL homeserveru</string>
+    <string name="directory_server_all_rooms_on_server">Všechny místnosti na serveru %s</string>
+    <string name="directory_server_native_rooms">Všech %s vlastních místností</string>
+
+    <string name="lock_screen_hint">Zadat zde…</string>
+
+    <plurals name="notification_unread_notified_messages">
+        <item quantity="one">1 nepřečtená oznámená zpráva</item>
+        <item quantity="few">%d nepřečtené oznámené zprávy</item>
+        <item quantity="other">%d nepřečtených oznámených zpráv</item>
+    </plurals>
+    <plurals name="notification_unread_notified_messages_in_room_msgs">
+        <item quantity="one">1 nepřečtená oznámená zpráva</item>
+        <item quantity="few">%d nepřečtené oznámené zprávy</item>
+        <item quantity="other">%d nepřečtených oznámených zpráv</item>
+    </plurals>
+    <plurals name="notification_unread_notified_messages_in_room_rooms">
+        <item quantity="one">1 místnost</item>
+        <item quantity="few">%d místnosti</item>
+        <item quantity="other">%d místností</item>
+    </plurals>
+
+    <plurals name="notification_compat_summary_line_for_room">
+        <item quantity="one">%1$s: 1 zpráva</item>
+        <item quantity="few">%1$s: %2$d zprávy</item>
+        <item quantity="other">%1$s: %2$d zpráv</item>
+    </plurals>
+    <plurals name="notification_compat_summary_title">
+        <item quantity="one">%d oznámení</item>
+        <item quantity="few">%d oznámení</item>
+        <item quantity="other">%d oznámení</item>
+    </plurals>
+
+    <string name="notification_unread_notified_messages_in_room">%1$s v %2$s</string>
+    <string name="notification_unknown_new_event">Nová událost</string>
+    <string name="notification_unknown_room_name">Místnost</string>
+    <string name="notification_new_messages">Nové zprávy</string>
+    <string name="notification_new_invitation">Nová pozvánka</string>
+    <string name="notification_sender_me">Já</string>
+    <string name="notification_inline_reply_failed">** Odeslání selhalo - prosím, otevřete místnost</string>
+
+    <string name="historical_placeholder">Hledej v minulosti</string>
+
+    <string name="widget_no_power_to_manage">Pro správu widgetů v této místnosti potřebujete oprávnění</string>
+    <string name="widget_creation_failure">Založení widgetu se nezdařilo</string>
+    <string name="event_formatter_widget_added">%2$s přidal %1$s</string>
+    <string name="event_formatter_widget_removed">%2$s odstranil(a) %1$s</string>
+    <string name="settings_labs_create_conference_with_jitsi">Založit konferenční hovor s jitsi</string>
+    <string name="widget_delete_message_confirmation">Jste si jisti, že chcete smazat widget z této místnosti\?</string>
+    <plurals name="active_widgets">
+        <item quantity="one">1 aktivní widget</item>
+        <item quantity="few">%d aktivní widgety</item>
+        <item quantity="other">%d aktivních widgetů</item>
+    </plurals>
+
+
+    <string name="room_widget_activity_title">Widget</string>
+    <string name="room_widget_permission_title">Načíst widget</string>
+    <string name="room_widget_permission_added_by">Tento widget přidal:</string>
+    <string name="room_widget_permission_webview_shared_info_title">Použitím může dojít k nastavení cookie a sdílení dat s %s:</string>
+    <string name="room_widget_permission_shared_info_title">Použitím může dojít k sdílení dat s %s:</string>
+    <string name="room_widget_failed_to_load">Načtení widgetu se nezdařilo.
+\n%s</string>
+    <string name="room_widget_reload">Opět načíst widget</string>
+    <string name="room_widget_open_in_browser">Otevřít v prohlížeči</string>
+    <string name="room_widget_revoke_access">Zrušit přístup pro mě</string>
+
+    <string name="room_widget_permission_display_name">Vaše veřejné jméno</string>
+    <string name="room_widget_permission_avatar_url">URL Vašeho avatara</string>
+    <string name="room_widget_permission_user_id">Vaše uživatelské ID</string>
+    <string name="room_widget_permission_theme">Váš motiv</string>
+    <string name="room_widget_permission_widget_id">ID widgetu</string>
+    <string name="room_widget_permission_room_id">ID místnosti</string>
+
+
+    <string name="error_jitsi_not_supported_on_old_device">Promiňte, konferenční hovory s Jitsi nejsou podporovány na starších zařízeních (zařízení s Androidem nižším než 5.0)</string>
+    <string name="room_widget_resource_permission_title">Widget si žádá použití následujících zdrojů:</string>
+    <string name="room_widget_resource_grant_permission">Povolit</string>
+    <string name="room_widget_resource_decline_permission">Zamítnout vše</string>
+    <string name="room_widget_webview_access_camera">Použít fotoaparát</string>
+    <string name="room_widget_webview_access_microphone">Použít mikrofon</string>
+    <string name="room_widget_webview_read_protected_media">Číst media chráněná DRM</string>
+
+    <string name="widget_integration_unable_to_create">Nelze založit widget.</string>
+    <string name="widget_integration_failed_to_send_request">Odeslání požadavku selhalo.</string>
+    <string name="widget_integration_positive_power_level">Energetická hladina musí být pozitivní celé číslo.</string>
+    <string name="widget_integration_must_be_in_room">Nejste v této místnosti.</string>
+    <string name="widget_integration_no_permission_in_room">Nemáte oprávnění tak učinit v této místnosti.</string>
+    <string name="widget_integration_missing_room_id">V požadavku chybí id místnosti.</string>
+    <string name="widget_integration_missing_user_id">V požadavku chybí id uživatele.</string>
+    <string name="widget_integration_room_not_visible">Místnost %s není viditelná.</string>
+    <string name="widget_integration_missing_parameter">Požadovaný parametr chybí.</string>
+    <string name="widget_integration_invalid_parameter">Parametr není platný.</string>
+    <string name="integration_manager_not_configured">Žádný správce integrací není konfigurován.</string>
+    <string name="room_add_matrix_apps">Přidat aplikace Matrix</string>
+    <string name="settings_labs_native_camera">Použít vestavěný fotoaparát</string>
+    <string name="settings_labs_native_camera_summary">Spustit systémový fotoaprát místo vlastní obrazovky fotoaparátu.</string>
+    <string name="settings_labs_keyboard_options_to_send_message">Stisknout enter na klávesníci k odeslání zprávy</string>
+    <string name="settings_labs_enable_send_voice">Poslat hlasovou zprávu</string>
+    <string name="settings_labs_enable_send_voice_summary">Tato volba požaduje pro nahrání zprávy aplikaci třetí strany.</string>
+    <string name="widget_integration_review_terms">Před pokračováním musíte přijmout Podmínky této služby.</string>
+
+    <string name="you_added_a_new_device_with_info">Nová relace požaduje šifrovací klíč. Jméno relace: %1$s
+\nNaposledy viděna: %2$s
+\nPokud jste se nepřihlásili do jiné relace, ignorujte tento požadavek.</string>
+    <string name="your_unverified_device_requesting">Vaše neověřená relace \'%s\' požaduje šifrovací klíče.</string>
+    <string name="your_unverified_device_requesting_with_info">Neověřená relace požaduje šifrovací klíče.
+\nJméno relace: %1$s
+\nNaposledy viděna: %2$s
+\nPokud jste se nepřihlásili do jiné relace, ignorujte tento požadavek.</string>
+
+    <string name="start_verification">Spustit ověření</string>
+    <string name="start_verification_short_label">Ověřit</string>
+    <string name="share_without_verifying">Sdílet bez ověření</string>
+    <string name="share_without_verifying_short_label">Sdílet</string>
+    <string name="key_share_request">Požadavek na sdílení klíče</string>
+    <string name="ignore_request">Ignorovat požadavek</string>
+    <string name="ignore_request_short_label">Ignorovat</string>
+
+    <string name="conference_call_warning_title">Varování!</string>
+    <string name="conference_call_warning_message">Konferenční hovory jsou ve vývoji a mohou být nespolehlivé.</string>
+
+    <string name="command_error">Chyba příkazu</string>
+    <string name="unrecognized_command">Neznámý příkaz: %s</string>
+    <string name="command_problem_with_parameters">Příkaz \"%s\" potřebuje více parametrů nebo některé parametry jsou nesprávné.</string>
+    <string name="command_description_emote">Zobrazí akce</string>
+    <string name="command_description_ban_user">Zakáže uživatele s daným id</string>
+    <string name="command_description_unban_user">Zruší zákaz uživateli s daným id</string>
+    <string name="command_description_op_user">Určit úroveň pokročilosti uživatele</string>
+    <string name="command_description_invite_user">Pozve uživatele s daným id do této místnosti</string>
+    <string name="command_description_join_room">Vstoupí do místnosti s daným aliasem</string>
+    <string name="command_description_part_room">Opustit místnost</string>
+    <string name="command_description_topic">Určit téma místnosti</string>
+    <string name="command_description_kick_user">Nakopne uživatele s daným id</string>
+    <string name="command_description_nick">Změní Vaši veřejnou přezdívku</string>
+    <string name="command_description_markdown">Markdown zap/vyp</string>
+    <string name="command_description_deop_user">Odebere práva uživateli s daným id</string>
+    <string name="command_description_clear_scalar_token">Opravit správu aplikací Matrix</string>
+
+    <string name="markdown_has_been_enabled">Markdown byl zapnut.</string>
+    <string name="markdown_has_been_disabled">Markdown byl vypnut.</string>
+
+    <string name="notification_off">Vypnout</string>
+    <string name="notification_silent">Tiché</string>
+    <string name="notification_noisy">Hlučné</string>
+
+    <string name="create">Založit</string>
+    <string name="create_community">Založit komunitu</string>
+    <string name="community_name">Jméno komunity</string>
+    <string name="community_name_hint">Příklad</string>
+    <string name="community_id">Id komunity</string>
+    <string name="community_id_hint">příklad</string>
+
+    <string name="group_details_home">Doma</string>
+    <string name="group_details_people">Lidé</string>
+    <string name="group_details_rooms">Místnosti</string>
+    <string name="no_users_placeholder">Žádní uživatelé</string>
+
+    <string name="rooms">Místnosti</string>
+    <string name="joined">Přítomní</string>
+    <string name="invited">Pozvaní</string>
+    <string name="filter_group_members">Filtrovat členy skupiny</string>
+    <string name="filter_group_rooms">Filtrovat místnosti skupiny</string>
+
+    <plurals name="group_members">
+        <item quantity="one">1 člen</item>
+        <item quantity="few">%d členové</item>
+        <item quantity="other">%d členů</item>
+    </plurals>
+
+    <plurals name="group_rooms">
+        <item quantity="one">1 místnost</item>
+        <item quantity="few">%d místnosti</item>
+        <item quantity="other">%d místností</item>
+    </plurals>
+    <string name="group_no_long_description">Správce komunity neposkytl podrobný popis této lomunity.</string>
+
+    <string name="has_been_kicked">%2$s Vás vykopnul z %1$s</string>
+    <string name="has_been_banned">%2$s Vám zakázal %1$s</string>
+    <string name="reason_colon">Důvod: %1$s</string>
+    <string name="rejoin">Opět se přidejte</string>
+    <string name="receipt_avatar">Avatar přijetí</string>
+    <string name="notice_avatar">Avatar vypovězení</string>
+    <string name="avatar">Avatar</string>
+
+    <string name="dialog_user_consent_content">Abyste mohli dále používat homeserver %1$s, musíte prohlédnout všeobecné podmínky a souhlasit s nimi.</string>
+    <string name="dialog_user_consent_submit">Prohlédnout nyní</string>
+
+    <string name="deactivate_account_title">Deaktivovat účet</string>
+    <string name="deactivate_account_content">To učiní Váš účet trvale nepoužitelným. Nebudete se moci přihlásit a nikdo nebude moci registrovat stejné uživatelské ID. Způsobí odchod Vašeho účtu ze všech místností, jichž se účastní a odstraní podrobnosti Vašeho účtu z ověřovacího serveru. <b>Tato akce je nevratná</b>.
+\n
+\nDeaktivace Vašeho účtu <b>samosebou nezpůsobí zapomenutí zpráv, jež jste poslali</b>. Pokud si přejete, abychom Vaše zprávy zapomněli, zaškrtněte box níže.
+\n
+\nViditelnost zpráv v Matrixu je podobná emailu. To, že zapomeneme Vaše zprávy, znamená, že nebudou ani s novými, ani neregistrovanými uživateli sdíleny, ale registrovaní uživatelé, kteří již přístup k Vašim zprávám mají, jej budou mít k jejich kopiím.</string>
+    <string name="deactivate_account_delete_checkbox">Prosím, při deaktivaci mého účtu zapomeňte všechny zprávy, které jsem poslal(a) (Varování: způsobí, že budoucí uživatelé uvidí neúplné konverzace)</string>
+    <string name="deactivate_account_prompt_password">Pokračujte po zadání svého hesla:</string>
+    <string name="deactivate_account_submit">Deaktivovat účet</string>
+
+    <string name="error_empty_field_enter_user_name">Prosím, zadejte uživatelské jméno.</string>
+    <string name="error_empty_field_your_password">Prosím, zadejte své heslo.</string>
+    <string name="room_tombstone_versioned_description">Tato místnost byla nahrazena a není již aktivní</string>
+    <string name="room_tombstone_continuation_link">Konverzace pokračuje tady</string>
+    <string name="room_tombstone_continuation_description">Tato místnost je pokračováním jiné konverzace</string>
+    <string name="room_tombstone_predecessor_link">Po kliknutí zde uvidíte starší zprávy</string>
+
+    <string name="resource_limit_exceeded_title">Mez zdrojů překročena</string>
+    <string name="resource_limit_contact_action">Kontaktovat správce</string>
+
+    <string name="resource_limit_contact_admin">kontaktovat Vašeho správce služby</string>
+
+    <string name="resource_limit_soft_default">Tento homeserver překročil jednu ze svých mezí zdrojů, a tak <b>se někteří uživatelé nebudou moci přihlásit</b>.</string>
+    <string name="resource_limit_hard_default">Tento homeserver překročil jednu ze svých mezí zdrojů.</string>
+
+    <string name="resource_limit_soft_mau"> Tent homeserver narazil na svoji měsíční mez aktivních uživatelů, a tak <b>se někteří uživatelé nebudou moci přihlásit</b>.</string>
+    <string name="resource_limit_hard_mau">Tento homeserver narazil na svoji měsíční mez aktivních uživatelů.</string>
+
+    <string name="resource_limit_soft_contact">Prosím, %s, aby zvýšili mez.</string>
+    <string name="resource_limit_hard_contact">Prosím, %s, abyste mohli službu dále používate.</string>
+
+    <string name="settings_lazy_loading_title">Pomalé načítání členů místností</string>
+    <string name="settings_lazy_loading_description">Zvýší výkon tím, že načte členy místnosti při prvním náhledu.</string>
+    <string name="error_lazy_loading_not_supported_by_home_server">Váš homeserver dosud nepodporuje pomalé načtení členů místností. Zkuste později.</string>
+
+    <string name="unknown_error">Omlouváme se, došlo k chybě</string>
+
+    <string name="merged_events_expand">rozbalit</string>
+    <string name="merged_events_collapse">sbalit</string>
+
+    <string name="settings_info_area_show">Ukázat informační pole</string>
+    <string name="show_info_area_always">Vždy</string>
+    <string name="show_info_area_messages_and_errors">U zpráv a chyb</string>
+    <string name="show_info_area_only_errors">Jen u chyb</string>
+
+    <string name="generic_label">%1$s:</string>
+    <string name="generic_label_and_value">%1$s: %2$s</string>
+    <string name="plus_x">+%d</string>
+    <string name="x_plus">%d+</string>
+    <string name="no_valid_google_play_services_apk">Žádný platný APK Google Plaz Services nenalezen. Oznámení možná nebudou pracovat spolehlivě.</string>
+
+    <string name="store_title">Riot.im - Komunikujte, svým způsobem</string>
+    <string name="store_whats_new">Stále měníme a vylepšujeme Riot.im. Úplný seznam změn je k nalezení zde: %1$s. Abyste zajistili, že nic nezmeškáte, ponechte aktualizace zapnuté.</string>
+    <string name="store_short_description">Univerzální zabezpečená chat aplikace zcela pod Vaší kontrolou.</string>
+    <string name="store_full_description">Chat aplikace pod Vaší kontrolou a zcela flexibilní. Riot Vás nechá komunikovat způsobem, kterým chcete. Vytvořena pro [matrix] - standard otevřené, decentralizované komunikace.
+\n
+\nZaložte si bezplatný účet u matrix.org, založte si svůj server na https://modular.im nebo použijte jiný Matrix server.
+\n
+\nProč zvolit Riot.im\?
+\n
+\n• KOMPLETNÍ KOMUNIKACE: Zakládejte místnosti pro své týmy, přátele, komunitu - jakkoli chcete! Chatujte, sdílejte soubory, přidávejte widgety, komunikujte hovorem či video hovorem - vše bezplatně.
+\n
+\n• HLUBOKÉ INTEGRACE: Používejte Riot.im s nástroji, jež znáte a máte rádi. S Riot.im můžete dokonce chatovat s uživateli a skupinami s jinými chat aplikacemi.
+\n
+\n• SOUKROMÁ A ZABEZBEČENÁ: Udržujte své konverzace tajné. Nejmodernější end-to-end šifrování zaručí, že soukromé konverzace soukromými zůstanou. 
+\n
+\n• OTEVŘENÁ, NE ZAVŘENÁ: Open source a postavená na Matrixu. Staňte se vlastníky svých dat tím, že si založíte vlastní server, nebo si zvolíte ten, jemuž důvěřujete.
+\n
+\n• KDEKOLI JSTE: Zůstaňte v kontaktu, ať už jste kdekoli, s plně synchronizovanou historií zpráv přes všechna svá zařízení nebo online u https://riot.im.</string>
+
+    <string name="passphrase_create_passphrase">Založit heslo</string>
+    <string name="passphrase_confirm_passphrase">Potvrdit heslo</string>
+    <string name="passphrase_enter_passphrase">Zadat heslo</string>
+    <string name="passphrase_passphrase_does_not_match">Heslo se neshoduje</string>
+    <string name="passphrase_empty_error_message">Prosím, zadejte heslo</string>
+    <string name="passphrase_passphrase_too_weak">Heslo je příliš slabé</string>
+
+    <string name="keys_backup_passphrase_not_empty_error_message">Prosím, smažte heslo, přejete-lis si, aby Riot generoval klíč pro obnovu.</string>
+    <string name="keys_backup_no_session_error">Žádná relace Matrix není dostupná</string>
+
+    <string name="keys_backup_setup_step1_title">Nikdy neztraťte šifrované zprávy</string>
+    <string name="keys_backup_setup_step1_description">Zprávy v šifrovaných místnostech jsou zabezpečeny pomocí end.to-end šifrováním. Pouze Vy a adresát(i) máte klíče ke čtení těchto zpráv.</string>
+    <string name="keys_backup_setup">Začít používat zálohu klíčů</string>
+    <string name="keys_backup_setup_step1_advanced">(Pokročilé)</string>
+    <string name="keys_backup_setup_step2_text_title">Zabezpečit zálohu heslem.</string>
+    <string name="keys_backup_setup_step2_text_description">Uložíme zašifrovanou kopii Vašich klíčů na Vašem homeserveru. Chraňte svoji zálohu heslem, abyste ji udrželi v bezpečí.
+\n
+\nZ důvodu nejvyšší bezpečnosti by se mělo lišit od hesla účtu.</string>
+    <string name="keys_backup_setup_step2_button_title">Nastavit heslo</string>
+    <string name="keys_backup_setup_creating_backup">Zálohuji</string>
+    <string name="keys_backup_setup_step1_recovery_key_alternative">Nebo zabezpečte svoji zálohu pomocí klíče obnovy, uloženého někde v bezpečí.</string>
+    <string name="keys_backup_setup_step2_skip_button_title">(Pokročilé) Nastavit s klíčem obnovy</string>
+    <string name="keys_backup_setup_step3_success_title">Podařilo se!</string>
+    <string name="keys_backup_setup_step3_text_line2">Váš klíč obnovy je záchranná síť - lze jej použít pro obnovu Vašich šifrovaných zpráv, pokud zapomenete své heslo.
+\nUchovávejte svůj klíč obnovy velmi bezpečně, např. ve správci hesel (nebo trezoru)</string>
+    <string name="keys_backup_setup_step3_text_line2_no_passphrase">Uchovávejte svůj klíč obnovy velmi bezpečně, např. ve správci hesel (nebo trezoru)</string>
+    <string name="keys_backup_setup_step3_button_title">Hotovo</string>
+    <string name="keys_backup_setup_step3_button_title_no_passphrase">Udělal jsem kopii</string>
+    <string name="keys_backup_setup_step3_copy_button_title">Uložit klíč obnovy</string>
+    <string name="keys_backup_setup_step3_share_recovery_file">Sdílet</string>
+    <string name="keys_backup_setup_step3_save_button_title">Uložit jako soubor</string>
+    <string name="recovery_key_export_saved_as_warning">Klíč obnovy byl uložen do %s\'.
+\n
+\nVarování: může dojít ke smazání tohoto souboru, pokud odstraníte aplikaci.</string>
+
+    <string name="keys_backup_setup_override_backup_prompt_tile">Záloha již existuje na Vašem homeserveru</string>
+    <string name="keys_backup_setup_override_backup_prompt_description">Vypadá to, že jste již nastavili zálohu klíče z jiné relace. Chcete ji nahradit zálohou, již právě provádíte\?</string>
+    <string name="keys_backup_setup_override_replace">Nahradit</string>
+    <string name="keys_backup_setup_override_stop">Zastavit</string>
+
+    <string name="keys_backup_setup_step3_please_make_copy">Prosím, udělat kopii</string>
+    <string name="keys_backup_setup_step3_share_intent_chooser_title">Sdílet klíč obnovy s…</string>
+    <string name="keys_backup_setup_step3_generating_key_status">Generuji klíč obnovy pomocí hesla, tento proces může trvat několi vteřin.</string>
+    <string name="recovery_key">Klíč obnovy</string>
+    <string name="unexpected_error">Neočekávaná chyba</string>
+    <string name="keys_backup_setup_backup_started_title">Zálohování se spustilo</string>
+    <string name="keys_backup_setup_skip_title">Jste si jisti\?</string>
+    <string name="keys_backup_setup_skip_msg">Můžete ztratit přístup ke svým zprávám, pokud se odhlásíte nebo ztratíte toto zařízení.</string>
+
+    <string name="keys_backup_restore_is_getting_backup_version">Načítám verzi zálohy…</string>
+    <string name="keys_backup_restore_with_passphrase">Použijte heslo obnovy k odemknutí historie svých šifrovaných zpráv</string>
+    <string name="keys_backup_restore_use_recovery_key">použít klíč obnovy</string>
+    <string name="keys_backup_restore_with_passphrase_helper_with_link">Neznám Vaše heslo obnovy, můžete %s.</string>
+
+    <string name="keys_backup_restore_with_recovery_key">Použijte svůj klíč obnovy k odemknutí historie svých šifrovaných zpráv</string>
+    <string name="keys_backup_restore_key_enter_hint">Zadat klíč obnovy</string>
+
+    <string name="keys_backup_restore_setup_recovery_key">Obnova zpráv</string>
+
+    <string name="keys_backup_restore_with_key_helper">Ztratili jste klíč obnovy\? Můžete nastavit nový v nastavení.</string>
+    <string name="keys_backup_passphrase_error_decrypt">Zálohu nebylo možno s tímto heslem dešifrovat: prosím, ověřit, že jste zadali správné heslo obnovy.</string>
+    <string name="network_error_please_check_and_retry">Síťová chyba: prosím, ověřte své spojení a opakujte.</string>
+
+    <string name="keys_backup_restoring_waiting_message">Obnovuji zálohu:</string>
+    <string name="keys_backup_restoring_computing_key_waiting_message">Kalkuluji klíč zálohy…</string>
+    <string name="keys_backup_unlock_button">Odemknout historii</string>
+    <string name="keys_backup_recovery_code_empty_error_message">Prosím, zadejte klíč obnovy</string>
+    <string name="keys_backup_recovery_code_error_decrypt">Zálohu nebylo možno s tímto heslem dešifrovat: prosím, ověřte, že jste zadali správný klíč obnovy.</string>
+
+    <string name="keys_backup_restore_success_title">Záloha obnovena %s !</string>
+    <string name="keys_backup_restore_success_description">Obnoveno %1$d relačních klíčů a doplněno %2$d nových klíčů, které této relaci nebyly známy</string>
+    <string name="keys_backup_get_version_error">Načtení poslední verze klíčů obnovy selhalo (%s).</string>
+    <string name="keys_backup_no_keysbackup_sdk_error">Krypto relace není zapnuto</string>
+
+
+    <string name="keys_backup_settings_restore_backup_button">Obnovit ze zálohy</string>
+    <string name="keys_backup_settings_delete_backup_button">Smazat zálohu</string>
+
+    <string name="keys_backup_settings_status_ok">Klíč zálohy byl pro tuto relaci správně nastaven.</string>
+    <string name="keys_backup_settings_status_ko">Záloha klíču není pro tuto relaci zapnuta.</string>
+    <string name="keys_backup_settings_status_not_setup">Vaše klíče nejsou z této relace zálohovány.</string>
+
+    <string name="keys_backup_settings_signature_from_unknown_device">Záloha je podepsána neznámou relací s ID %s.</string>
+    <string name="keys_backup_settings_valid_signature_from_this_device">Záloha má platný podpis z této relace.</string>
+    <string name="keys_backup_settings_valid_signature_from_verified_device">Záloha má platný podpis z ověřené relace %s.</string>
+    <string name="keys_backup_settings_valid_signature_from_unverified_device">Záloha má platný podpis z neověřené relace %s</string>
+    <string name="keys_backup_settings_invalid_signature_from_verified_device">Záloha má neplatný podpis z ověřené relace %s</string>
+    <string name="keys_backup_settings_invalid_signature_from_unverified_device">Záloha má neplatný podpis z neověřené relace %s</string>
+    <string name="keys_backup_get_trust_error">Načtení informace o důvěryhodnosti zálohy (%s) se nezdařilo.</string>
+
+    <string name="keys_backup_settings_untrusted_backup">Abyste použili zálohu klíčů na tuto relaci, obnovte nyní pomocí svého hesla nebo klíče obnovy.</string>
+    <string name="keys_backup_settings_deleting_backup">Odstraňuji zálohu…</string>
+    <string name="keys_backup_settings_delete_backup_error">Odstranění zálohy (%s) selhalo</string>
+
+    <string name="keys_backup_settings_checking_backup_state">Kontroluji stav zálohy</string>
+    <string name="keys_backup_settings_delete_confirm_title">Smazat zálohu</string>
+    <string name="keys_backup_settings_delete_confirm_message">Smazat Vaše zálohované šifrovací klíče ze serveru\? Ke čtení šifrované historie zpráv již nebude moci použít klíč obnovy.</string>
+
+    <string name="new_recovery_method_popup_title">Nová záloha klíče</string>
+    <string name="new_recovery_method_popup_description">Nová bezpečná záloha klíče zpráv byla nalezena.
+\n
+\nPokud jste nenastavili novou metodu obnovy, útočník se může pokoušet o přístup k Vašemu účtu. Ihned změňte heslo svého účtu a nastavte novou metodu obnovy v nastavení.</string>
+    <string name="new_recovery_method_popup_was_me">To jsem byl já</string>
+    <string name="keys_backup_banner_setup_line1">Nikdy neztraťte šifrované zprávy</string>
+    <string name="keys_backup_banner_setup_line2">Začněte používat zálohu klíče</string>
+
+    <string name="keys_backup_banner_recover_line1">Nikdy neztraťte šifrované zprávy</string>
+    <string name="keys_backup_banner_recover_line2">Použíjte zálohu klíče</string>
+
+    <string name="keys_backup_banner_update_line1">Nový bezpečný klíč zpráv</string>
+    <string name="keys_backup_banner_update_line2">Správa v záloze klíčů</string>
+
+    <string name="keys_backup_info_title_version">Verze</string>
+    <string name="keys_backup_info_title_algorithm">Algoritmus</string>
+    <string name="keys_backup_info_title_signature">Podpis</string>
+
+    <string name="autodiscover_invalid_response">Neplatná odpověď z hledání homeserverů</string>
+    <string name="autodiscover_well_known_autofill_dialog_title">Volby serveru automaticky</string>
+    <string name="autodiscover_well_known_autofill_dialog_message">"Riot nalezl vlastní konfiguraci serveru pro doménu Vašeho uživatelského Id  \"%1$s\":
+\n%2$s"</string>
+    <string name="autodiscover_well_known_autofill_confirm">Použít konfiguraci</string>
+
+    <string name="invalid_or_expired_credentials">Byli jste odhlášení kvůli chybným či neplatným ověřovacím údajům.</string>
+
+    <string name="sas_verify_title">Ověřit pomocí srovnání krátkého textového řetězce.</string>
+    <string name="sas_security_advise">Pro nejvyšší bezpečnost doporučujeme, abyste to provedli osobně nebo jiným způsobem důvěryhodné komunikace.</string>
+    <string name="sas_verify_start_button_title">Začít ověření</string>
+    <string name="sas_incoming_request_title">Příchozí požadavek na ověření</string>
+    <string name="sas_incoming_request_description">Ověřuji tuto relaci, abych ji označil za důvěryhodnou. Důvěřování relacím partnerů Vám dodá více klidu mysli, používáte-li end-to-end šifrované zprávy.</string>
+    <string name="sas_incoming_request_description_2">Ověření této relace ji označí za důvěryhodnou a také označí Vaši relaci důvěryhodnou Vašemu partnerovi.</string>
+
+    <string name="sas_emoji_description">Ověřit tuto relaci potvrzením, že se následující emoji ukáže na obrazovce partnera</string>
+    <string name="sas_decimal_description">Ověřit tuto relaci potvrzením, že se následující čísla ukážou na obrazovce partnera</string>
+
+    <string name="sas_incoming_verification_request_dialog">Obdrželi jste příchozí žádost o ověření.</string>
+    <string name="sas_view_request_action">Ukázat žádost</string>
+    <string name="sas_waiting_for_partner">Čekám na potvrzení od partnera…</string>
+
+    <string name="sas_verified">Ověřeno!</string>
+    <string name="sas_verified_successful">Úspěšně jste ověřili tuto relaci.</string>
+    <string name="sas_verified_successful_description">Zabezpečené zprávy s tímto uživatelem jsou end-to-end šifrovány a nemohou být čteny třetími stranami.</string>
+    <string name="sas_got_it">Rozumím</string>
+
+    <string name="sas_verifying_keys">Nic se neukazuje\? Dosud nepodporují všichni klienti interaktivní ověření. Použijte tradiční ověření.</string>
+    <string name="sas_legacy_verification_button_title">Použijte tradiční ověření.</string>
+
+    <string name="sas_verification_request_notification_channel_title">Ověření klíče</string>
+    <string name="sas_cancelled_dialog_title">Žádost zrušena</string>
+    <string name="sas_cancelled_by_other">Druhá strana zrušila ověření.
+\n%s</string>
+    <string name="sas_cancelled_by_me">Ověření je zrušeno.
+\nDůvod: %s</string>
+
+    <string name="sas_verification_request_notification_channel">Interaktivní ověření relace</string>
+    <string name="sas_incoming_request_notif_title">Žádost na ověření</string>
+    <string name="sas_incoming_request_notif_content">%s chce ověřit Vaši relaci</string>
+
+    <string name="sas_error_m_user">Uživatel zrušil ověření</string>
+    <string name="sas_error_m_timeout">Čas ověřovacího procesu vypršel</string>
+    <string name="sas_error_m_unknown_transaction">Tato relace neví o té transakci</string>
+    <string name="sas_error_m_unknown_method">Tato relace se nemůže shodnout na dohodě o klíčích, MAC nebo metodě SAS</string>
+    <string name="sas_error_m_mismatched_commitment">Závazek o haši se neshodnul</string>
+    <string name="sas_error_m_mismatched_sas">SAS se neshodnul</string>
+    <string name="sas_error_m_unexpected_message">Relace obdržela neočekávanou zprávu</string>
+    <string name="sas_error_m_invalid_message">Byla obdržena neplatná zpráva</string>
+    <string name="sas_error_m_key_mismatch">Neshoda klíčů</string>
+    <string name="sas_error_m_user_error">Neshoda uživatelů</string>
+    <string name="sas_error_unknown">Neznámá chyba</string>
+
+    <string name="identity_server_not_defined">Nepoužíváte žádný server pro identity</string>
+    <string name="identity_server_not_defined_for_password_reset">Není konfigurován žádný server pro identity, musíte přenastavit heslo.</string>
+
+    <string name="security_warning_identity_server">Předchozí verze Riotu měly bezpečnostní chybu, jež umožnila serveru pro identity (%1$s) přístup k Vašemu účtu. Pokud důvěřujete %2$s, můžete ignorovat; jinak se, prosím, odhlašte a znovu přihlašte.
+\n
+\nDetaily zde:
+\nhttps://medium.com/@RiotChat/36b4792ea0d6</string>
+
+    <string name="error_user_already_logged_in">Vypadá to, že se chcete připojit k jinému homeserveru. Chcete se odhlásit\?</string>
+
+    <string name="edit">Upravit</string>
+    <string name="reply">Odpovědět</string>
+
+    <string name="global_retry">Opakovat</string>
+    <string name="room_list_empty">Začněte používat aplikaci vstupem do mísnosti.</string>
+    <string name="send_you_invite">Poslali Vám pozvánku</string>
+    <string name="invited_by">%s Vás pozval</string>
+
+    <string name="room_list_catchup_empty_title">Vše jste dohnali!</string>
+    <string name="room_list_catchup_empty_body">Nemáte již žádné nepřečtené zprávy</string>
+    <string name="room_list_catchup_welcome_title">Vítejte doma!</string>
+    <string name="room_list_catchup_welcome_body">Zde doženete nepřečtené zprávy</string>
+    <string name="room_list_people_empty_title">Konverzace</string>
+    <string name="room_list_people_empty_body">Tady budou zobrazeny Vaše přímé konverzace</string>
+    <string name="room_list_rooms_empty_title">Místnosti</string>
+    <string name="room_list_rooms_empty_body">Tady budou zobrazeny Vaše místnosti</string>
+
+    <string name="title_activity_emoji_reaction_picker">Reakce</string>
+    <string name="reactions_agree">Souhlasit</string>
+    <string name="reactions_like">Líbí se</string>
+    <string name="message_add_reaction">Přidat reakci</string>
+    <string name="message_view_reaction">Ukázat reakce</string>
+    <string name="reactions">Reakce</string>
+
+    <string name="event_redacted_by_user_reason">Událost smazána uživatelem</string>
+    <string name="event_redacted_by_admin_reason">Událost moderována správcem místnosti</string>
+    <string name="last_edited_info_message">Naposledy upravil %1$s dne %2$s</string>
+
+
+    <string name="malformed_message">Nečitelná událost, nelze zobrazit</string>
+    <string name="create_new_room">Založit novou místnost</string>
+    <string name="error_no_network">Žádná síť. Prosím, zkontrolujte své spojení do internetu.</string>
+    <string name="action_change">Změnit</string>
+    <string name="change_room_directory_network">Změnit síť</string>
+    <string name="please_wait">Prosím, čekejte…</string>
+    <string name="group_all_communities">Všechny komunity</string>
+
+    <string name="room_preview_no_preview">Nelze provést náhled této místnosti</string>
+    <string name="room_preview_world_readable_room_not_supported_yet">Náhled místnosti čitelné pro všechny zatím RiotX nepodporuje</string>
+
+    <string name="fab_menu_create_room">Místnosti</string>
+    <string name="fab_menu_create_chat">Přímé zprávy</string>
+
+    <string name="create_room_title">Nová místnost</string>
+    <string name="create_room_action_create">ZALOŽIT</string>
+    <string name="create_room_name_hint">Jméno místnosti</string>
+    <string name="create_room_public_title">Veřejná</string>
+    <string name="create_room_public_description">Kdokoli smí vstoupit do této místnosti</string>
+    <string name="create_room_directory_title">Adresář místností</string>
+    <string name="create_room_directory_description">Zveřejnit tuto místnost v adresáři místností</string>
+
+    <string name="keys_backup_unable_to_get_trust_info">Při načítání důvěryhodnosti došlo k chybě</string>
+    <string name="keys_backup_unable_to_get_keys_backup_data">Při načítání dat zálohy klíčů došlo k chybě</string>
+
+    <string name="alpha_disclaimer_title">Vítejte v betě!</string>
+    <string name="alpha_disclaimer_content_line_1">Protože RiotX je v raném vývoji, některé funkce mohou chybět a mohou se objevit i chyby.</string>
+    <string name="alpha_disclaimer_content_line_2_gplay">Seznam nejnovějších funkcí je vždy na %1$s a pokud nejdete chyby, prosím, zapište hlášení v levém horním menu na domovské obrazovce. Opravíme je tak brzy, jak jen můžeme.</string>
+    <string name="alpha_disclaimer_content_line_2_gplay_colored_part">Popis v Play Store</string>
+    <string name="alpha_disclaimer_content_line_2_fdroid">Pokud nejdete chyby, prosím, zapište hlášení v levém horním menu na domovské obrazovce. Opravíme je tak brzy, jak jen můžeme.</string>
+
+    <string name="settings_sdk_version">Verze Matrix SDK</string>
+    <string name="settings_other_third_party_notices">Jiná oznámení třetích stran</string>
+    <string name="navigate_to_room_when_already_in_the_room">Již se díváte do této místnosti!</string>
+
+    <string name="quick_reactions">Rychlé reakce</string>
+
+    <string name="settings_general_title">Obecná</string>
+    <string name="settings_preferences">Možnosti</string>
+    <string name="settings_security_and_privacy">Bezpečí &amp; Soukromí</string>
+    <string name="settings_expert">Expert</string>
+    <string name="settings_push_rules">Push pravidla</string>
+    <string name="settings_push_rules_no_rules">Žádná push pravidla nejsou definována</string>
+    <string name="settings_push_gateway_no_pushers">Žádné push brány nejsou registrovány</string>
+
+    <string name="push_gateway_item_app_id">app_id:</string>
+    <string name="push_gateway_item_push_key">push_klíč:</string>
+    <string name="push_gateway_item_app_display_name">app_display_name:</string>
+    <string name="push_gateway_item_device_name">jméno_relace:</string>
+    <string name="push_gateway_item_url">Url:</string>
+    <string name="push_gateway_item_format">Formát:</string>
+
+    <string name="preference_voice_and_video">Hlas &amp; Video</string>
+    <string name="preference_root_help_about">Nápověda &amp; O aplikaci</string>
+
+
+    <string name="settings_troubleshoot_test_token_registration_quick_fix">Registrovat token</string>
+
+    <string name="send_suggestion">Učinit návrh</string>
+    <string name="send_suggestion_content">Prosím, zapište svůj návrh níže.</string>
+    <string name="send_suggestion_report_placeholder">Popište svůj návrh tady</string>
+    <string name="send_suggestion_sent">Děkujeme, návrh byl úspěšně odeslán</string>
+    <string name="send_suggestion_failed">Odeslání návrhu selhalo (%s)</string>
+
+    <string name="settings_labs_show_hidden_events_in_timeline">Ukázat skryté události v časovém sledu</string>
+
+    <string name="store_riotx_title">RiotX - Klient Matrixu pro příští generaci</string>
+    <string name="store_riotx_short_description">Rychlejši a lehčí klient Matrixu s nejnovějšími konstrukcemi Androidu</string>
+    <string name="store_riotx_full_description">"RiotX je nový klient protokolu Matrix (Matrix.org): otevřená síť pro bezpečnou, decentralizovanou komunikaci. RiotX je úplný přepis klienta Riot Android založený na úplném přepisu Matrix Android SDK.
+\n
+\nProhlášení: Toto je beta verze. RiotX nyní prochází aktivním vývojem, obsahuje omezení a (doufáme, že ne moc) chyby. Veškerý feedback je vítán.
+\n
+\nRiotX podporuje: • Přihlášní do existujícího účtu  • Založení místnosti a vstup do veřejných místností  • Přijetí a odmítnutí pozvánek  • Seznam místností uživatelů  • Náhled podrobností místnosti  • Odesílání textových zpráv  • Odesílání příloh  • Čtení a psaní zpráv v zašifrovaných místnostech  • Krypto: záloha klíčů E2E, pokročilé ověření zařízení, požadavek na sdílení klíče a jeho uspokojení   • Push oznámení  • Světlý, tmavý a černý motiv
+\n
+\nJeště nejsou všechny funkce Riotu v RiotX implementovány. Hlavní chybějící funkce (přijdou brzy!): • Nastavení místnosti (seznam členů místnosti, atd.) • Hovory • Widgety • …"</string>
+
+    <string name="bottom_action_people_x">Přímé zprávy</string>
+
+    <string name="send_file_step_idle">Čekám…</string>
+    <string name="send_file_step_encrypting_thumbnail">Šifruji miniaturu…</string>
+    <string name="send_file_step_sending_thumbnail">Odesílám miniaturu (%1$s / %2$s)</string>
+    <string name="send_file_step_encrypting_file">Šifruji soubor…</string>
+    <string name="send_file_step_sending_file">Odesílám soubor (%1$s / %2$s)</string>
+
+    <string name="downloading_file">Stahuji soubor %1$s…</string>
+    <string name="downloaded_file">Soubor %1$s byl stažen!</string>
+
+    <string name="edited_suffix">(upraveno)</string>
+
+    <string name="riotx_no_registration_notice">%1$s pro založení účtu.</string>
+    <string name="riotx_no_registration_notice_colored_part">Použít zastaralou aplikaci</string>
+
+
+    <string name="message_edits">Úpravy zpráv</string>
+    <string name="no_message_edits_found">Úpravy nenalezeny</string>
+
+    <string name="room_filtering_filter_hint">Vytřídit konverzace…</string>
+    <string name="room_filtering_footer_title">Nemůžete najít, co hledáte\?</string>
+    <string name="room_filtering_footer_create_new_room">Založit novou místnost</string>
+    <string name="room_filtering_footer_create_new_direct_message">Poslat novou přímou zprávu</string>
+    <string name="room_filtering_footer_open_room_directory">Ukázat adresář místností</string>
+
+    <string name="room_directory_search_hint">Jméno nebo ID (#example:matrix.org)</string>
+
+    <string name="labs_swipe_to_reply_in_timeline">Zapnout přetažení pro odpověď v časovém sledu</string>
+
+    <string name="link_copied_to_clipboard">Odkaz zkopírován do schránky</string>
+
+    <string name="add_by_matrix_id">Přidat pomocí matrix ID</string>
+    <string name="creating_direct_room">Zakládám místnost…</string>
+    <string name="direct_room_no_known_users">Žádný výsledek nenalezen, použijte Přidat pomocí matrix ID k hledání na serveru.</string>
+    <string name="direct_room_start_search">K obdržení výsledků začněte zadávat</string>
+    <string name="direct_room_filter_hint">Vytřídit uživatelským jménem nebo ID…</string>
+
+    <string name="joining_room">Vstupuji do místnosti…</string>
+
+    <string name="message_view_edit_history">Ukázat historii úprav</string>
+
+    <string name="terms_of_service">Všeobecné podmínky</string>
+    <string name="review_terms">Pročíst všeobecné podmínky</string>
+    <string name="terms_description_for_identity_server">Nechte se nalézt druhými</string>
+    <string name="terms_description_for_integration_manager">Použijte boty, můstky, widgety a nálepky</string>
+
+    <string name="read_at">Čtěte na</string>
+
+
+    <string name="identity_server">Server pro identity</string>
+    <string name="disconnect_identity_server">Odpojit server pro identity</string>
+    <string name="add_identity_server">Nastavit server pro identity</string>
+    <string name="change_identity_server">Změnit server pro identity</string>
+    <string name="settings_discovery_identity_server_info">Nyní používáte %1$s, abyste nalezli a byli nalezeni existujícími kontakty, které znáte.</string>
+    <string name="settings_discovery_identity_server_info_none">Nyní nepoužíváte server pro identity. Abyste existující známé kontakty nalezli a nechali se jimi nalézt, nastavte nějaký níže.</string>
+    <string name="settings_discovery_emails_title">Emailová adresa k nalezení</string>
+    <string name="settings_discovery_no_mails">Volby pro nalezení se ukážou, jakmile doplníte email.</string>
+    <string name="settings_discovery_no_msisdn">Volby pro nalezení se ukážou, jakmile doplníte telefonní číslo.</string>
+    <string name="settings_discovery_disconnect_identity_server_info">Odpojení od serveru identit bude znamenat, že Vás jiní uživatelé nebudou moci nalézt a Vy nebudete moci pozvat druhé pomocí emailu nebo telefonního čísla.</string>
+    <string name="settings_discovery_msisdn_title">Telefonní čísla pro nalezení</string>
+    <string name="settings_discovery_confirm_mail">Poslali jsme Vám potvrzovací email na %s, podívejte se do emailu a klikněte na protvrzovací odkaz</string>
+    <string name="settings_discovery_mail_pending">Nevyřízený</string>
+
+    <string name="settings_discovery_enter_identity_server">Zadejte nový server pro identity</string>
+    <string name="settings_discovery_bad_identity_server">Nemohl jsem se spojit se serverem pro identity</string>
+    <string name="settings_discovery_please_enter_server">Prosím, zadejte url serveru pro identity</string>
+    <string name="settings_discovery_no_terms_title">Server pro identity nemá žádné všeobecné podmínky</string>
+    <string name="settings_discovery_no_terms">Server pro identity, pro který jste se rozhodli, nemá žádné všeobecné podmínky. Pokračujte pouze tehdy, důvěřujete-li vlastníku služby</string>
+    <string name="settings_text_message_sent">Textová zpráva byla odeslána na %s. Prosím, zadejte ověřovací kód v ní obsažený.</string>
+
+    <string name="settings_discovery_disconnect_with_bound_pid">Nyní sdílíte emailovou adresu nebo telefonní číslo na serveru identit %1$s. Budete se muset přepojit na %2$s, abyste je dále nesdíleli.</string>
+    <string name="settings_agree_to_terms">Souhlaste se všeobecnými podmínkami serveru identit (%s), abyste byli k nalezení podle emailové adresy nebo telefonního čísla.</string>
+
+    <string name="labs_allow_extended_logging">Zapnout podrobné záznamy.</string>
+    <string name="labs_allow_extended_logging_summary">Podrobné záznamy pomohou vývojářům mnoha podrobnostmi, odešlete-li RageShake. I když jsou zapnuty, aplikace nezaznamenává obsah zpráv nebo jakákoli soukromá data.</string>
+
+
+    <string name="error_terms_not_accepted">Prosím, opakujte, jakmile jste přijali všeobecné podmínky svého homeserveru.</string>
+
+    <string name="error_network_timeout">Vypadá to, že serveru dlouho trvá odpovědět, to může být způsobeno buď slabým spojením nebo chybou na serveru. Prosím, opakujte za chvíli.</string>
+
+    <string name="send_attachment">Poslat přílohu</string>
+
+    <string name="a11y_open_drawer">Otevřít navigační zásuvku</string>
+    <string name="a11y_create_menu_open">Otevřít menu založení místnosti</string>
+    <string name="a11y_create_menu_close">Zavřít menu založení místnosti…</string>
+    <string name="a11y_create_direct_message">Založit novou přímou konverzaci</string>
+    <string name="a11y_create_room">Založit novou místnost</string>
+    <string name="a11y_close_keys_backup_banner">Zavřít titulek zálohy klíčů</string>
+    <string name="a11y_show_password">Ukázat heslo</string>
+    <string name="a11y_hide_password">Skrýt heslo</string>
+    <string name="a11y_jump_to_bottom">Přeskočit až dolů</string>
+
+    <string name="two_and_some_others_read">%1$s, %2$s a %3$d dalších přečetli</string>
+    <string name="three_users_read">%1$s, %2$s a %3$s přečetli</string>
+    <string name="two_users_read">%1$s a %2$s přečetli</string>
+    <string name="one_user_read">%s přečetl(a)</string>
+    <plurals name="fallback_users_read">
+        <item quantity="one">1 uživatel přečetl</item>
+        <item quantity="few">%d uživatelé přečetli</item>
+        <item quantity="other">%d uživatelů přečetlo</item>
+    </plurals>
+
+    <string name="error_file_too_big">Soubor \'%1$s\' (%2$s) je příliš velký k nahrání. Limit je %3$s.</string>
+
+    <string name="error_attachment">Během načítání přílohy došlo k chybě.</string>
+    <string name="attachment_type_file">Soubor</string>
+    <string name="attachment_type_contact">Kontakt</string>
+    <string name="attachment_type_camera">Fotoaparát</string>
+    <string name="attachment_type_audio">Audio</string>
+    <string name="attachment_type_gallery">Galerie</string>
+    <string name="attachment_type_sticker">Nálepka</string>
+    <string name="error_handling_incoming_share">Nemohl jsem zpracovat sdílená data</string>
+
+    <string name="report_content_spam">Je to spam</string>
+    <string name="report_content_inappropriate">Je to nepatřičné</string>
+    <string name="report_content_custom">Vlastní hlášení…</string>
+    <string name="report_content_custom_title">Nahlásit tento obsah</string>
+    <string name="report_content_custom_hint">Důvod k nahlášení tohoto obsahu</string>
+    <string name="report_content_custom_submit">HLÁŠENÍ</string>
+    <string name="block_user">ZABLOKOVAT UŽIVATELE</string>
+
+    <string name="content_reported_title">Obsah ohlášen</string>
+    <string name="content_reported_content">Tento obsah byl ohlášen.
+\n
+\nPokud si dále nepřejete vidět více obsahu tohoto uživatele, můžete jej zablokovat a tím skrýt jejich zprávy</string>
+    <string name="content_reported_as_spam_title">Nahlášeno jako spam</string>
+    <string name="content_reported_as_spam_content">Tento obsah byl nahlášen jako spam.
+\n
+\nPokud si dále nepřejete vidět více obsahu tohoto uživatele, můžete jej zablokovat a tím skrýt jejich zprávy</string>
+    <string name="content_reported_as_inappropriate_title">Nahlášeno jako nepatřičné</string>
+    <string name="content_reported_as_inappropriate_content">Obsah byl nahlášen jako nepatřičný.
+\n
+\nPokud si dále nepřejete vidět obsah tohoto uživatele, můžete jej zablokovat a tím skrýt jejich zprávy</string>
+
+    <string name="permissions_rationale_msg_keys_backup_export">Riot potřebuje práva k uložení Vašich E2E klíčů na disk.
+\n
+\nProsím, povolte přístup v příštím dialogu, abyste mohli exportovat své klíče manuálně.</string>
+
+    <string name="no_network_indicator">Právě nyní není k dispozici žádné síťové spojení</string>
+
+    <string name="message_ignore_user">Zablokovat uživatele</string>
+
+    <string name="room_list_quick_actions_notifications_all_noisy">Všechny zprávy (hlučné)</string>
+    <string name="room_list_quick_actions_notifications_all">Všechny zprávy</string>
+    <string name="room_list_quick_actions_notifications_mentions">Pouze zmínky</string>
+    <string name="room_list_quick_actions_notifications_mute">Utišit</string>
+    <string name="room_list_quick_actions_settings">Nastavení</string>
+    <string name="room_list_quick_actions_leave">Opustit místnost</string>
+    <string name="notice_member_no_changes">%1$s neučinil žádné změny</string>
+    <string name="command_description_spoiler">Odeslat danou zprávu jako spoiler</string>
+    <string name="spoiler">Spoiler</string>
+    <string name="reaction_search_type_hint">Pro nalezení reakce zadejte klíčové slovo.</string>
+
+    <string name="no_ignored_users">Neignorujete žádné uživatele</string>
+
+    <string name="help_long_click_on_room_for_more_options">Více možností po dlouhém stisku na místnost</string>
+
+
+    <string name="room_join_rules_public">%1$s učinil místnost veřejnou pro kohokoli znalého odkazu.</string>
+    <string name="room_join_rules_invite">%1$s nastavil místnost jen pro pozvané.</string>
+    <string name="timeline_unread_messages">Nepřečtené zprávy</string>
+
+    <string name="login_splash_title">Osvoboďte svou komunikaci</string>
+    <string name="login_splash_text1">Chatujte s lidmi přímo nebo ve skupinách</string>
+    <string name="login_splash_text2">Udržujte konverzace soukromé pomocí šifrování</string>
+    <string name="login_splash_text3">Rozšiřte &amp; upravte si svůj zážitek</string>
+    <string name="login_splash_submit">Můžeme začít</string>
+
+    <string name="login_server_title">Vybrat server</string>
+    <string name="login_server_text">Jako email, účty mají jeden domov, ačkoli můžete mluvit s kýmkoli</string>
+    <string name="login_server_matrix_org_text">Přidejte se k miliónům svobodným na největším veřejném serveru</string>
+    <string name="login_server_modular_text">Prémiový hosting pro organizace</string>
+    <string name="login_server_modular_learn_more">Dozvědět se víc</string>
+    <string name="login_server_other_title">Další</string>
+    <string name="login_server_other_text">Vlastní &amp; pokročilá nastavení</string>
+
+    <string name="login_continue">Pokračovat</string>
+    <string name="login_connect_to">Připojit k %1$s</string>
+    <string name="login_connect_to_modular">Připojit k Modular</string>
+    <string name="login_connect_to_a_custom_server">Upravit připojení k serveru</string>
+    <string name="login_signin_to">Přihlásit se na %1$s</string>
+    <string name="login_signup">Založit účet</string>
+    <string name="login_signin">Přihlásit se</string>
+    <string name="login_signin_sso">Pokračovat s SSO</string>
+
+    <string name="login_server_url_form_modular_hint">Adresa Modular</string>
+    <string name="login_server_url_form_other_hint">Adresa</string>
+    <string name="login_server_url_form_modular_text">Prémiový hosting pro organizace</string>
+    <string name="login_server_url_form_modular_notice">Zadejte adresu Modular RIot nebo serveru, který chcete použít</string>
+    <string name="login_server_url_form_other_notice">Zadejte adresu serveru nebo Riotu, k němuž se chcete připojit</string>
+
+    <string name="login_sso_error_message">Při načítání stránky došlo k chybě: %1$s (%2$d)</string>
+    <string name="login_mode_not_supported">Aplikace se nemůže přihlásit k tomuto homeserveru. Homeserver podporuje následující typy přihlášení: %1$s.
+\n
+\nChcete se přihlásit webovým klientem\?</string>
+    <string name="login_registration_disabled">Omlouváme se, tento server již nepřijímá nové účty.</string>
+    <string name="login_registration_not_supported">Aplikace nemůže založit účet na tomto homeserveru.
+\n
+\nChcete se přihlásit webovým klientem\?</string>
+
+    <string name="login_login_with_email_error">Tato emailová adresa se nevztahuje k žádnému účtu.</string>
+
+    <string name="login_reset_password_on">Resetovat heslo na %1$s</string>
+    <string name="login_reset_password_notice">Ověřovací email bude odeslán do Vašeho mailboxu za účelem potvrzení nastavení nového heslo.</string>
+    <string name="login_reset_password_submit">Dále</string>
+    <string name="login_reset_password_email_hint">Email</string>
+    <string name="login_reset_password_password_hint">Nové heslo</string>
+
+    <string name="login_reset_password_warning_title">Varování!</string>
+    <string name="login_reset_password_warning_content">Změna hesla přenastaví všechny end-to-end šifrovací klíče pro všechny Vaše relace, a tak učiní zašifrovanou historii chatů nečitelnou. Nastavte zálohu klíčů nebo exportujte své klíče místností z jiné relace, než se rozhodnete pokračovat.</string>
+    <string name="login_reset_password_warning_submit">Pokračovat</string>
+
+    <string name="login_reset_password_error_not_found">Tato emailová adresa se nevztahuje k žádnému účtu</string>
+
+    <string name="login_reset_password_mail_confirmation_title">Nahlédněte do inboxu</string>
+    <string name="login_reset_password_mail_confirmation_notice">Ověřovací email byl odeslán na %1$s.</string>
+    <string name="login_reset_password_mail_confirmation_notice_2">Pro potvrzení svého nového hesla klepněte na odkaz. Jakmile otevřete v něm uvedený odkaz, klikněte níže.</string>
+    <string name="login_reset_password_mail_confirmation_submit">Ověřil(a) jsem svou emailovou adresu</string>
+
+    <string name="login_reset_password_success_title">Hotovo!</string>
+    <string name="login_reset_password_success_notice">Vaše heslo bylo přenastaveno.</string>
+    <string name="login_reset_password_success_notice_2">Byli jste odhlášeni ze všech svých relací a dále již neobdržíte žádná push oznámení. Abyste je opět zapnuli, přihlašte se na každém zařízení.</string>
+    <string name="login_reset_password_success_submit">Zpět na přihlášení</string>
+
+    <string name="login_reset_password_cancel_confirmation_title">Varování</string>
+    <string name="login_reset_password_cancel_confirmation_content">Vaše heslo nebylo dosud změněno.
+\n
+\nZastavit proces změny hesla\?</string>
+
+    <string name="login_set_email_title">Nastavit emailovou adresu</string>
+    <string name="login_set_email_notice">Nastavte emailovou adresu pro obnově svého účtu. Později můžete volitelně dovolit lidem, které znáte, aby Vás podle emailu nalezli.</string>
+    <string name="login_set_email_mandatory_hint">Email</string>
+    <string name="login_set_email_optional_hint">Email (volitelné)</string>
+    <string name="login_set_email_submit">Dále</string>
+
+    <string name="login_set_msisdn_title">Nastavit telefonní číslo</string>
+    <string name="login_set_msisdn_notice">Nastavte telefonní číslo, abyste volitelně dovolili lidem, které znáte, aby Vás nalezli.</string>
+    <string name="login_set_msisdn_notice2">Prosím, použijte mezinárodní formát.</string>
+    <string name="login_set_msisdn_mandatory_hint">Telefonní číslo</string>
+    <string name="login_set_msisdn_optional_hint">Telefonní číslo (volitelné)</string>
+    <string name="login_set_msisdn_submit">Dále</string>
+
+    <string name="login_msisdn_confirm_title">Potvrdit telefonní číslo</string>
+    <string name="login_msisdn_confirm_notice">Právě jsme poslali kód na %1$s. Zadejte jej níže pro ověření, že jste to Vy.</string>
+    <string name="login_msisdn_confirm_hint">Zadejte kód</string>
+    <string name="login_msisdn_confirm_send_again">Poslat znovu</string>
+    <string name="login_msisdn_confirm_submit">Dále</string>
+
+    <string name="login_msisdn_error_not_international">Mezinárodní telefonní čísla musí začít s \'+\'</string>
+    <string name="login_msisdn_error_other">Telefonní číslo se zdá neplatné. Prosím, zkontrolujte</string>
+
+    <string name="login_signup_to">Přihlásit se k %1$s</string>
+    <string name="login_signin_username_hint">Uživatelské jméno nebo email</string>
+    <string name="login_signup_username_hint">Uživatelské jméno</string>
+    <string name="login_signup_error_user_in_use">Toto uživatelské jméno je již obsazeno</string>
+    <string name="login_signup_cancel_confirmation_title">Varování</string>
+    <string name="login_signup_cancel_confirmation_content">Váš účet nebyl ještě založen.
+\n
+\nZastavit registrační proces\?</string>
+
+    <string name="login_a11y_choose_matrix_org">Vybrat matrix.org</string>
+    <string name="login_a11y_choose_modular">Vybrat modular</string>
+    <string name="login_a11y_choose_other">Vybrat upravený homeserver</string>
+    <string name="login_a11y_captcha_container">Prosím, proveďte vybídnutí captcha</string>
+    <string name="login_terms_title">Přijmout všeobecné podmínky a pokračovat</string>
+
+    <string name="login_wait_for_email_title">Prosím, nahlédněte do svého emailu</string>
+    <string name="login_wait_for_email_notice">Právě jsme odeslali email na %1$s.
+\nNež budete pokračovat se založením účtu, prosím, klikněte na odkaz v něm obsažený.</string>
+    <string name="login_validation_code_is_not_correct">Zadaný kód není správný. Prosím, zkontrolujte.</string>
+    <string name="login_error_outdated_homeserver_title">Zastaralý homeserver</string>
+    <string name="login_error_outdated_homeserver_content">Tento homeserver používá za účelem spojení příliš starou verzi. Požádejte správce, aby provedl aktualizaci.</string>
+
+    <plurals name="login_error_limit_exceeded_retry_after">
+        <item quantity="one">Bylo odesláno příliš mnoho požadavků. Můžete opakovat za %1$d vteřinu…</item>
+        <item quantity="few">Bylo odesláno příliš mnoho požadavků. Můžete opakovat za %1$d vteřiny…</item>
+        <item quantity="other">Bylo odesláno příliš mnoho požadavků. Můžete opakovat za %1$d vteřin…</item>
+    </plurals>
+
+    <string name="seen_by">Viděno</string>
+
+    <string name="signed_out_title">Právě jste se odhlásili</string>
+    <string name="signed_out_notice">Může to být způsobeno rozmanitými příčinami:
+\n
+\n• Změnili jste své heslo v jiné relaci.
+\n
+\n• Smazali jste tuto relaci z jiné relace.
+\n
+\n• Správce Vašeho serveru zneplatnil Váš přístup z bezpečnostních důvodů.</string>
+    <string name="signed_out_submit">Znovu se přihlásit</string>
+
+    <string name="soft_logout_title">Právě jste se odhlásili</string>
+    <string name="soft_logout_signin_title">Přihlásit se</string>
+    <string name="soft_logout_signin_notice">Správce Vašeho homeserveru (%1$s) Vás odhlásil z Vašeho účtu %2$s (%3$s).</string>
+    <string name="soft_logout_signin_e2e_warning_notice">Přihlašte se, abyste získali přístup k šifrovacím klíčům uloženým výlučně v tomto zařízení. Potřebujete je ke čtení všech svých zpráv na jakémkoli zařízení.</string>
+    <string name="soft_logout_signin_submit">Přihlásit</string>
+    <string name="soft_logout_clear_data_title">Vyčistit osobní údaje</string>
+    <string name="soft_logout_clear_data_notice">Varování: Vaše osobní údaje (včetně šifrovacích klíčů) jsou dosud uložena v tomto zařízení.
+\n
+\nVyčistěte je, pokud toto zařízení nebudete dále používat nebo se chcete přihlásit k jinému účtu.</string>
+    <string name="soft_logout_clear_data_submit">Vyčistit všechna data</string>
+
+    <string name="soft_logout_clear_data_dialog_title">Vyčistit data</string>
+    <string name="soft_logout_clear_data_dialog_content">Vyčistit všechna data uložená v tomto zařízení\?
+\nPro přístup k účtu a zprávám se znovu se přihlaste.</string>
+    <string name="soft_logout_clear_data_dialog_e2e_warning_content">Ztratíte přístup k šifrovaným zprávám, pokud se nepřihlásíte za účelem obnovy šifrovacích klíčů.</string>
+    <string name="soft_logout_clear_data_dialog_submit">Vyčistit data</string>
+    <string name="soft_logout_sso_not_same_user_error">Tato relace je pro uživatele %1$s a Vy jste zadali údaje pro uživatele %2$s. RiotX toto nepodporuje.
+\nProsím, nejdříve vyčistěte data a pak se přihlaste k jinému účtu.</string>
+
+    <string name="permalink_malformed">Váš odkaz matrix.to byl chybný</string>
+    <string name="bug_report_error_too_short">Popis je příliš krátký</string>
+
+    <string name="notification_initial_sync">Prvotní sync…</string>
+
+    <string name="settings_show_devices_list">Ukázat všechny mé relace</string>
+    <string name="settings_advanced_settings">Pokročilá nastavení</string>
+    <string name="settings_developer_mode">Vývojářský režim</string>
+    <string name="settings_developer_mode_summary">Vývojářský režim aktivuje skryté funkce a může tak učinit aplikaci méně stabilní. Jen pro vývojáře!</string>
+    <string name="settings_rageshake">Rageshake</string>
+    <string name="settings_rageshake_detection_threshold">Práh detekce</string>
+    <string name="settings_rageshake_detection_threshold_summary">Pro test prahu detekce zatřeste svým telefonem</string>
+    <string name="rageshake_detected">Zatřesení detekováno!</string>
+    <string name="settings">Nastavení</string>
+    <string name="devices_current_device">Nynější relace</string>
+    <string name="devices_other_devices">Jiné relace</string>
+
+    <string name="autocomplete_limited_results">Ukazuji jen první výsledky, zadejte více znaků…</string>
+
+    <string name="settings_developer_mode_fail_fast_title">Fail-fast</string>
+    <string name="settings_developer_mode_fail_fast_summary">RiotX se může zbořit častěji, když se objeví neočekávané chyby</string>
+
+    <string name="command_description_verify">Požadavek ověření daného uživatelského ID</string>
+    <string name="command_description_shrug">Předsune ¯\\_(ツ)_/¯ do textové zprávy</string>
+
+    <string name="create_room_encryption_title">Zapnout šifrování</string>
+    <string name="create_room_encryption_description">Jakmile zapnuto, šifrování nelze vypnout.</string>
+
+    <string name="login_error_threepid_denied">Vaše emailová doména není autorizována registrovat se na tomto serveru</string>
+
+    <string name="verification_conclusion_warning">Nedůvěryhodné přihlášení</string>
+    <string name="verification_sas_match">Shodují se</string>
+    <string name="verification_sas_do_not_match">Neshodují se</string>
+    <string name="verify_user_sas_emoji_help_text">Ověřte tohoto uživatele potvrzením, že se následující ojedinělá emoji ukážou na jejich obrazovce ve stejném pořadí.</string>
+    <string name="verify_user_sas_emoji_security_tip">Pro nejvyšší zabezpečení použijte další důvěryhodný způsob komunikace nebo proveďte osobně.</string>
+    <string name="verification_green_shield">Abyste se ujistili o důvěryhodnosti uživatele, dívejte se po zeleném štítu. Pro zabezpečení místnosti důvěřujte všem uživatelům v místnosti.</string>
+
+    <string name="verification_conclusion_not_secure">Nezabezpečené</string>
+    <string name="verification_conclusion_compromised">Něco z následujích je patrně narušeno:
+\n
+\n- Váš homeserver
+\n- Homeserver uživatele, jejž právě ověřujete
+\n- Spojení do internetu Vaše či dalších uživatelů
+\n- Zařízení Vaše či dalších uživatelů</string>
+
+    <string name="sent_a_video">Video.</string>
+    <string name="sent_an_image">Obrázek.</string>
+    <string name="sent_an_audio_file">Audio</string>
+    <string name="sent_a_file">Soubor</string>
+
+    <string name="verification_request_waiting">Čekám…</string>
+    <string name="verification_request_other_cancelled">%s zrušeno</string>
+    <string name="verification_request_you_cancelled">Zrušili jste</string>
+    <string name="verification_request_other_accepted">%s přijal</string>
+    <string name="verification_request_you_accepted">Přijali jste</string>
+    <string name="verification_sent">Ověření odesláno</string>
+    <string name="verification_request">Požadavek na ověření</string>
+
+
+    <string name="verification_verify_device">Ověřit tuto relaci</string>
+    <string name="verification_verify_device_manually">Ověřit manuálně</string>
+
+    <string name="you">Vy</string>
+
+    <string name="verification_scan_notice">Pro bezpečné vzájemné ověření oskenujte kód zařízením druhého uživatele</string>
+    <string name="verification_scan_their_code">Skenovat kód</string>
+    <string name="verification_scan_emoji_title">Nelze skenovat</string>
+    <string name="verification_scan_emoji_subtitle">V případě neosobního ověření porovnejte emoji</string>
+
+    <string name="verification_no_scan_emoji_title">Ověřit porovnáním emoji</string>
+
+    <string name="verify_by_emoji_title">Ověřit pomocí emoji</string>
+    <string name="verify_by_emoji_description">Nemůžete-li skenovat kód nahoře, ověřte porovnáním krátkého, ojedinělého výběru emoji.</string>
+
+    <string name="a13n_qr_code_description">Obrázek QR kódu</string>
+
+    <string name="verification_verify_user">Ověřit %s</string>
+    <string name="verification_verified_user">Ověřeno %s</string>
+    <string name="verification_request_waiting_for">Čekám na %s…</string>
+    <string name="verification_request_alert_description">Pro vyšší zabezpečení ověřte %s kontrolou jednorázového kódu na obou zařízeních.
+\n
+\nPro nejvyšší zabezpečení proveďte osobně.</string>
+    <string name="room_profile_not_encrypted_subtitle">Zprávy v této místnosti nejsou šifrovány end-to-end.</string>
+    <string name="room_profile_encrypted_subtitle">Zprávy v této místnosti jsou šifrovány end-to-end.
+\n
+\nVaše zprávy jsou zabezpečeny zámky a pouze Vy a příjemce máte jedinečné klíče k jejich odemknutí.</string>
+    <string name="room_profile_section_security">Zabezpečení</string>
+    <string name="room_profile_section_security_learn_more">Dozvědět se víc</string>
+    <string name="room_profile_section_more">Více</string>
+    <string name="room_profile_section_more_settings">Nastavení místnosti</string>
+    <string name="room_profile_section_more_notifications">Oznámení</string>
+    <plurals name="room_profile_section_more_member_list">
+        <item quantity="one">Jedna osoba</item>
+        <item quantity="few">%1$d osoby</item>
+        <item quantity="other">%1$d osob</item>
+    </plurals>
+    <string name="room_profile_section_more_uploads">Nahrání</string>
+    <string name="room_profile_section_more_leave">Opustit místnost</string>
+    <string name="room_profile_leaving_room">Opouštím místnost…</string>
+
+    <string name="room_member_power_level_admins">Správci</string>
+    <string name="room_member_power_level_moderators">Moderátoři</string>
+    <string name="room_member_power_level_custom">Vlastní</string>
+    <string name="room_member_power_level_invites">Pozvánky</string>
+    <string name="room_member_power_level_users">Uživatelé</string>
+
+    <string name="room_member_power_level_admin_in">Správce v %1$s</string>
+    <string name="room_member_power_level_moderator_in">Moderátor v %1$s</string>
+    <string name="room_member_power_level_custom_in">Vlastní (%1$d) in %2$s</string>
+
+    <string name="room_member_jump_to_read_receipt">Přeskočit k potvrzení přečtení</string>
+
+    <string name="rendering_event_error_type_of_event_not_handled">RiotX neobstarává události typu \'%1$s\'</string>
+    <string name="rendering_event_error_type_of_message_not_handled">RiotX neobstarává zprávy typu \'%1$s\'</string>
+    <string name="rendering_event_error_exception">RiotX narazil na chybu při převádění obsahu události s id \'%1$s\'</string>
+
+    <string name="unignore">Odignorovat</string>
+
+    <string name="verify_cannot_cross_sign">Tato relace nemůže sdílet toto ověření s jinými z Vašich relací.
+\nToto ověření bude uloženo místně a sdíleno v budoucí verzi aplikace.</string>
+
+    <string name="room_list_sharing_header_recent_rooms">Poslední místnosti</string>
+    <string name="room_list_sharing_header_other_rooms">Další místnosti</string>
+
+    <string name="command_description_rainbow">Odešle danou zprávu zabarvenou jako duha</string>
+    <string name="command_description_rainbow_emote">Odešle daný emote zabarvený jako duha</string>
+
+    <string name="settings_category_timeline">Časová osa</string>
+
+    <string name="settings_category_composer">Editor zpráv</string>
+
+    <string name="room_settings_enable_encryption">Zapnout šifrování end-to-end</string>
+    <string name="room_settings_enable_encryption_warning">Jakmile zapnuto, šifrování nelze vypnout.</string>
+
+    <string name="room_settings_enable_encryption_dialog_title">Zapnout šifrování\?</string>
+    <string name="room_settings_enable_encryption_dialog_content">Jakmile zapnuto, šifrování místnosti nelze vypnout. Zprávy odeslané v zašifrované místnosti nemohou být čteny serverem, ale pouze účastníky místnosti. Zapnutím šifrování mohou boty a můstky přestat správně pracovat.</string>
+    <string name="room_settings_enable_encryption_dialog_submit">Zapnout šifrování</string>
+
+    <string name="verification_request_notice">Za účelem bezpečnosti ověřte %s kontrolou jednorázového kódu.</string>
+    <string name="verification_request_start_notice">Za účelem bezpečnosti to proveďte osobně nebo použijte jiný způsob komunikace.</string>
+
+    <string name="verification_emoji_notice">Porovnejte jedinečná emoji a ujistěte se, že se ukážou ve stejném pořadí.</string>
+    <string name="verification_code_notice">Porovnejte kód s tím na obrazovce druhého uživatele.</string>
+    <string name="verification_conclusion_ok_notice">Zprávy s tímto uživatelem jsou zašifrovány end-to-end a nemohou být čteny třetími stranami.</string>
+    <string name="verification_conclusion_ok_self_notice">Vaše nová relace je nyní ověřena. Má přístup k Vašim zašifrovaným zprávám a ostatní uživatelé ji uvidi jako důvěryhodnou.</string>
+
+
+    <string name="encryption_information_cross_signing_state">Křížový podpis</string>
+    <string name="encryption_information_dg_xsigning_complete">Křížový podpis je zapnut.
+\nPrivátní klíče v zařízení.</string>
+    <string name="encryption_information_dg_xsigning_trusted">Křížový podpis je zapnut
+\nKlíče jsou důvěryhodné.
+\nPrivátní klíče nejsou známy</string>
+    <string name="encryption_information_dg_xsigning_not_trusted">Křížový podpis je zapnut.
+\nKlíče nejsou důvěryhodné</string>
+    <string name="encryption_information_dg_xsigning_disabled">Křížový podpis není zapnut</string>
+
+
+    <string name="settings_active_sessions_list">Aktivní relace</string>
+    <string name="settings_active_sessions_show_all">Ukázat všechny relace</string>
+    <string name="settings_active_sessions_manage">Správa relací</string>
+    <string name="settings_active_sessions_signout_device">Odhlásit se z této relace</string>
+
+    <string name="settings_failed_to_get_crypto_device_info">Žádná kryptografická informace není k dispozici</string>
+
+    <string name="settings_active_sessions_verified_device_desc">Tato relace je důvěryhodná pro bezpečnou komunikaci, protože jste ji ověřili:</string>
+    <string name="settings_active_sessions_unverified_device_desc">Ověřte tuto relaci a tím ji označíte za důvěryhodnou &amp; dovolíte jí přístup k zašifrovaným zprávám. Pokud jste se do této relace nepřihlásili, může být Váš účet ohrožen:</string>
+
+    <plurals name="settings_active_sessions_count">
+        <item quantity="one">%d aktivní relace</item>
+        <item quantity="few">%d aktivní relace</item>
+        <item quantity="other">%d aktivních relací</item>
+    </plurals>
+
+    <string name="crosssigning_verify_this_session">Ověřit tuto relaci</string>
+    <string name="crosssigning_other_user_not_trust">Ostatní uživatelé ji nemusí důvěřovat</string>
+    <string name="complete_security">Dokončit zabezpečení</string>
+
+    <string name="verification_open_other_to_verify">Pro ověření této relace použijte existující relaci, a tím ji udělíte přístup k zašifrovaným zprávám.</string>
+
+
+    <string name="verification_profile_verify">Ověřit</string>
+    <string name="verification_profile_verified">Ověřeno</string>
+    <string name="verification_profile_warning">Varování</string>
+
+    <string name="room_member_profile_failed_to_get_devices">Načtení relací selhalo</string>
+    <string name="room_member_profile_sessions_section_title">Relace</string>
+    <string name="trusted">Důvěryhodné</string>
+    <string name="not_trusted">Nedůvěryhodné</string>
+
+    <string name="verification_profile_device_verified_because">Tato relace je důvěryhodná pro bezpečnou komunikaci, protože %1$s (%2$s) ji ověřili:</string>
+    <string name="verification_profile_device_new_signing">%1$s (%2$s) se příhlásili skrze novou relaci:</string>
+    <string name="verification_profile_device_untrust_info">Dokud tento uživatel nezačne důvěřovat této relaci, zprávy z ní odeslané a v ní přijaté budou označeny varováním. Volitelně ji můžete manuálně ověřit.</string>
+
+
+    <string name="initialize_cross_signing">Spustit křížové podepsání</string>
+    <string name="reset_cross_signing">Resetovat klíče</string>
+
+    <string name="a11y_qr_code_for_verification">QR kód</string>
+
+    <string name="qr_code_scanned_by_other_notice">Skoro u konce! Ukazuje %s totožný štít\?</string>
+    <string name="qr_code_scanned_by_other_yes">Ano</string>
+    <string name="qr_code_scanned_by_other_no">Ne</string>
+
+    <string name="no_connectivity_to_the_server_indicator">Spojení k serveru bylo ztraceno</string>
+
+    <string name="settings_dev_tools">Vývojářské nástroje</string>
+    <string name="settings_account_data">Údaje účtu</string>
+    <plurals name="poll_info">
+        <item quantity="one">%d hlas</item>
+        <item quantity="few">%d hlasy</item>
+        <item quantity="other">%d hlasů</item>
+    </plurals>
+    <plurals name="poll_info_final">
+        <item quantity="one">%d hlas - Konečné výsledky</item>
+        <item quantity="few">%d hlasy - Konečné výsledky</item>
+        <item quantity="other">%d hlasů - Konečné výsledky</item>
+    </plurals>
+    <string name="poll_item_selected_aria">Zvolená možnost</string>
+    <string name="command_description_poll">Založí jednoduchou anketu</string>
+    <string name="verification_cannot_access_other_session">Použijte metodu obnovy</string>
+    <string name="verification_use_passphrase">Pokud se nemůžete dostat do existující relace</string>
+
+    <string name="new_signin">Nové přihlášení</string>
+
+    <string name="enter_secret_storage_invalid">Nemohu najít přihlašovací data v úložišti</string>
+    <string name="enter_secret_storage_passphrase">Zadejte heslo pro úložište údajů</string>
+    <string name="enter_secret_storage_passphrase_warning">Varování:</string>
+    <string name="enter_secret_storage_passphrase_warning_text">Měli byste otevřít úložiště údajů z důvěryhodného zařízení</string>
+
+    <string name="message_action_item_redact">Odstranit…</string>
+    <string name="share_confirm_room">Chcete %1$s poslat tuto přílohu\?</string>
+    <plurals name="send_images_with_original_size">
+        <item quantity="one">Odeslat obrázek v původní velikosti</item>
+        <item quantity="few">Odeslat obrázky v původní velikosti</item>
+        <item quantity="other">Odeslat obrázky v původní velikosti</item>
+    </plurals>
+
+    <string name="delete_event_dialog_title">Potvrďte odstranění</string>
+    <string name="delete_event_dialog_content">Jste si jist, že chcete odstranit (smazat) tuto událost\? Pamatujte, že pokud odstraníte jméno místnosti nebo téma, mohlo by to změnu zvrátit.</string>
+    <string name="delete_event_dialog_reason_checkbox">Udejte důvod</string>
+    <string name="delete_event_dialog_reason_hint">Důvod pro úpravu</string>
+
+    <string name="event_redacted_by_user_reason_with_reason">Událost smazána uživatelem, důvod: %1$s</string>
+    <string name="event_redacted_by_admin_reason_with_reason">Událost moderována správcem místnosti, důvod: %1$s</string>
+
+    <string name="keys_backup_restore_success_title_already_up_to_date">Klíče jsou již aktuální!</string>
+
+    <string name="login_mobile_device_riotx">RiotX Android</string>
+
+    <string name="settings_key_requests">Požadavky na klíče</string>
+
+    <string name="e2e_use_keybackup">Odemknout zašifrovanou historii zpráv</string>
+
+    <string name="refresh">Obnovit</string>
+
+    <string name="new_session">Nové přihlášení. Byli jste to Vy\?</string>
+    <string name="new_session_review">Klepněte pro přehled &amp; ověření</string>
+    <string name="verify_new_session_notice">Použijte tuto relaci k ověření relace nové, a tím ji udělíte přístup k zašifrovaným zprávám.</string>
+    <string name="verify_new_session_was_not_me">To jsem nebyl(a) já</string>
+    <string name="verify_new_session_compromized">Váš účet může být ohrožen</string>
+
+    <string name="verify_cancel_self_verification_from_untrusted">Pokud přerušíte, nebudete moci číst zašifrované zprávy na tomto zařízení a ostatní uživatelé mu nebudou důvěřovat</string>
+    <string name="verify_cancel_self_verification_from_trusted">Pokud přerušíte, nebudete moci číst zašifrované zprávy na svém novém zařízení a ostatní uživatelé mu nebudou důvěřovat</string>
+    <string name="verify_cancel_other">Nebudete moci ověřit %1$s (%2$s), pokud nyní přerušíte. Začněte znovu v jejich uživatelském profilu.</string>
+
+    <string name="verify_not_me_self_verification">Jedno z následujících může být ohroženo:
+\n
+\n- Vaše heslo
+\n- Váš homeserver
+\n- Toto zařízení nebo to druhé
+\n- Spojení do internetu obou zařízení
+\n
+\nDoporučujeme, abyste okamžitě změnili heslo &amp; klíč obnovy v nastavení.</string>
+
+    <string name="verify_cancelled_notice">Ověřit svá zařízení v nastavení.</string>
+    <string name="verification_cancelled">Ověření zrušeno</string>
+
+    <string name="recovery_passphrase">Heslo obnovy</string>
+    <string name="message_key">Klíč zpráv</string>
+    <string name="account_password">Heslo účtu</string>
+
+    <string name="set_recovery_passphrase">Nastavte %s</string>
+    <string name="generate_message_key">Generovat klíč zpráv</string>
+
+    <string name="confirm_recovery_passphrase">Potvrďte %s</string>
+
+    <string name="enter_account_password">Zadejte své %s a pokračujte.</string>
+
+    <string name="bootstrap_info_text">Zabezpečit &amp; odemknout zašifrované zprávy a důvěru s %s.</string>
+    <string name="bootstrap_info_confirm_text">Zadejte opět své %s a potvrďte.</string>
+    <string name="bootstrap_dont_reuse_pwd">Nepoužívejte heslo účtu opakovaně.</string>
+
+
+    <string name="bootstrap_loading_text">To může několik vteřin trvat, prosím, buďte trpěliví.</string>
+    <string name="bootstrap_loading_title">Nastavuji obnovení.</string>
+    <string name="your_recovery_key">Váš klíč obnovení</string>
+    <string name="bootstrap_finish_title">Hotovo!</string>
+    <string name="keep_it_safe">Udržujte v bezpečí</string>
+    <string name="finish">Dokončit</string>
+
+    <string name="bootstrap_save_key_description">Použijte tento %1$s jako záchrannou síť v případě, že zapomenete své %2$s.</string>
+
+    <string name="bootstrap_crosssigning_progress_initializing">Zvěřejňuji založené klíče identity</string>
+    <string name="bootstrap_crosssigning_progress_pbkdf2">Generuji zabezpečené klíče z hesla</string>
+    <string name="bootstrap_crosssigning_progress_default_key">Určuji výchozí klíč SSSS</string>
+    <string name="bootstrap_crosssigning_progress_save_msk">Synchronizuji hlavní klíč</string>
+    <string name="bootstrap_crosssigning_progress_save_usk">Synchronizuji uživatelský klíč</string>
+    <string name="bootstrap_crosssigning_progress_save_ssk">Synchronizuji sebepodpisový klíč</string>
+    <string name="bootstrap_crosssigning_progress_key_backup">Nastavuji zálohu klíčů</string>
+
+
+    <string name="bootstrap_cross_signing_success">Vaše %2$s &amp; %1$s jsou nyní nastaveny.
+\n
+\nUdržujte je v bezpečí! Budete je potřebovat k odemknutí zašifrovaných zpráv a zabezpečených informací, pokud přijdete o všechny své aktivní relace.</string>
+
+    <string name="bootstrap_crosssigning_print_it">Vytiskněte a uložte na bezpečném místě</string>
+    <string name="bootstrap_crosssigning_save_usb">Uložte je na USB nebo zálohový disk</string>
+    <string name="bootstrap_crosssigning_save_cloud">Nahrajte do svého osobního úložiště v cloudu</string>
+
+    <string name="auth_flow_not_supported">To nelze provést z mobilního zařízení</string>
+
+    <string name="bootstrap_skip_text">Nastavení hesla pro obnovení Vám umožní zabezpečit &amp; odemknout zašifrované zprávy a důvěryhodnost.
+\n
+\nPokud nechcete nastavit heslo pro zprávy, založte klíč pro zprávy.</string>
+    <string name="bootstrap_skip_text_no_gen_key">Nastavení hesla pro obnovení Vám umožní zabezpečit &amp; odemknout zašifrované zprávy a důvěryhodnost.</string>
+
+
+    <string name="encryption_enabled">Šifrování zapnuto</string>
+    <string name="encryption_enabled_tile_description">Zprávy v této místnosti jsou zašifrovány end-to-end. Poučte se více &amp; ověřte uživatele v jejich profilech.</string>
+    <string name="encryption_not_enabled">Šifrování není zapnuto</string>
+    <string name="encryption_unknown_algorithm_tile_description">Šifrování použité v této místnosti není podporováno</string>
+
+    <string name="room_created_summary_item">%s založil a nastavil tuto místnost.</string>
+
+    <string name="qr_code_scanned_self_verif_notice">Skoro u konce! Ukazuje druhé zařízení stejný štít\?</string>
+    <string name="qr_code_scanned_verif_waiting_notice">Skoro u konce! Čekám na potvrzení…</string>
+    <string name="qr_code_scanned_verif_waiting">Čekám na %s…</string>
+
+    <string name="error_failed_to_import_keys">Import klíčů selhal</string>
+
+    <string name="settings_notification_configuration">Konfigurace oznámení</string>
+    <string name="settings_messages_at_room">Zprávy obsahující @room</string>
+    <string name="settings_messages_in_e2e_one_to_one">Zašifrované zprávy v chatech one-to-one</string>
+    <string name="settings_messages_in_e2e_group_chat">Zašifrované zprávy ve skupinových chatech</string>
+    <string name="settings_when_rooms_are_upgraded">Když dojde k upgradu místností</string>
+    <string name="settings_troubleshoot_title">Řešit problémy</string>
+    <string name="settings_notification_advanced_summary_riotx">Nastavit důležitost oznámení podle události</string>
+
+    <string name="command_description_plain">Odešle zprávu jako prostý text bez interpretace markdown</string>
+
+    <string name="auth_invalid_login_param_space_in_password">Nesprávné uživatelské jméno a/nebo heslo. Zadané heslo začíná nebo končí mezerami, prosím, zkontrolovat.</string>
+
+    <string name="room_message_placeholder">Zpráva…</string>
+
+    <string name="upgrade_security">Upgrade šifrování je k dispozici</string>
+    <string name="security_prompt_text">Ověřit sebe &amp; ostatní za účelem bezpečí chatů</string>
+
+    <string name="bootstrap_enter_recovery">Zadejte svůj %s a pokračujte</string>
+    <string name="use_file">Použít soubor</string>
+
+    <string name="enter_backup_passphrase">Zadejte %s</string>
+    <string name="backup_recovery_passphrase">Heslo obnovení</string>
+    <string name="bootstrap_invalid_recovery_key">To není platný klíč obnovení</string>
+    <string name="recovery_key_empty_error_message">Prosím, zadejte klíč obnovení</string>
+
+    <string name="bootstrap_progress_checking_backup">Kontroluji klíč zálohy</string>
+    <string name="bootstrap_progress_checking_backup_with_info">Kontroluji klíč zálohy (%s)</string>
+    <string name="bootstrap_progress_compute_curve_key">Generuji klíč curve</string>
+    <string name="bootstrap_progress_generating_ssss">Generuji klíč SSSS z hesla</string>
+    <string name="bootstrap_progress_generating_ssss_with_info">Generuji klíč SSSS z hesla (%s)</string>
+    <string name="bootstrap_progress_generating_ssss_recovery">Generuji klíč SSSS z klíče obnovení</string>
+    <string name="bootstrap_progress_storing_in_sss">Ukládám heslo pro zálohu klíče v SSSS</string>
+    <string name="new_session_review_with_info">%1$s (%2$s)</string>
+
+    <string name="bootstrap_migration_enter_backup_password">Zadejte své heslo pro zálohu klíče a pokračujte.</string>
+    <string name="bootstrap_migration_use_recovery_key">použít svůj klíč obnovy zálohy klíčů</string>
+    <string name="bootstrap_migration_with_passphrase_helper_with_link">Neznáte-li své heslo zálohy klíčů, můžete %s.</string>
+    <string name="bootstrap_migration_backup_recovery_key">Klíč pro obnovu zálohy klíčů</string>
+
+    <string name="settings_security_prevent_screenshots_title">Zamezte screenshotům aplikace</string>
+    <string name="settings_security_prevent_screenshots_summary">Zapnutí toho nastavení doplní značku FLAG_SECURE ke všem aktivitám. Pro aktivaci změny restartujte aplikaci.</string>
+
+    <string name="media_file_added_to_gallery">Mediální soubor byl připojen do galerie</string>
+    <string name="error_adding_media_file_to_gallery">Mediální soubor nemohl být připojen do galerie</string>
+    <string name="change_password_summary">Nastavit nové heslo účtu…</string>
+
 </resources>
diff --git a/vector/src/main/res/values-cy/strings.xml b/vector/src/main/res/values-cy/strings.xml
new file mode 100644
index 0000000000..16dd99d88c
--- /dev/null
+++ b/vector/src/main/res/values-cy/strings.xml
@@ -0,0 +1,13 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<resources>
+    <string name="resources_language">cy</string>
+    <string name="resources_country_code">GB</string>
+    <string name="resources_script">Latn</string>
+
+    <string name="light_theme">Thema Golau</string>
+    <string name="dark_theme">Thema Tywyll</string>
+    <string name="black_them">Thema Du</string>
+    <string name="status_theme">Thema Status.im</string>
+
+    <string name="notification_sync_init">Yn paratoi gwasanaeth</string>
+</resources>
diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml
index 8af2391b5f..c452fbc901 100644
--- a/vector/src/main/res/values-de/strings.xml
+++ b/vector/src/main/res/values-de/strings.xml
@@ -9,7 +9,7 @@
     <string name="title_activity_home">Nachrichten</string>
     <string name="title_activity_room">"Raum</string>
     <string name="title_activity_settings">Einstellungen</string>
-    <string name="title_activity_member_details">Nutzerdetails</string>
+    <string name="title_activity_member_details">Benutzerdetails</string>
     <string name="title_activity_historical">Historisch</string>
 
     <!-- button names -->
@@ -338,7 +338,7 @@ Bist du sicher?</string>
     <string name="room_menu_search">Suchen</string>
     <string name="room_one_user_is_typing">%s schreibt…</string>
     <string name="room_two_users_are_typing">%1$s &amp; %2$s schreiben…</string>
-    <string name="room_many_users_are_typing">%1$s &amp; %2$s &amp; andere schreiben…</string>
+    <string name="room_many_users_are_typing">%1$s, %2$s &amp; andere schreiben…</string>
     <string name="room_message_placeholder_encrypted">Verschlüsselte Nachricht senden…</string>
     <string name="room_message_placeholder_not_encrypted">Nachricht senden (unverschlüsselt)…</string>
     <string name="room_offline_notification">Verbindung zum Server wurde unterbrochen.</string>
@@ -570,8 +570,8 @@ Beachte: Diese Aktion wird die App neu starten und einige Zeit brauchen.</string
     <string name="room_settings_labs_end_to_end">Ende-zu-Ende-Verschlüsselung</string>
     <string name="room_settings_labs_end_to_end_is_active">Ende-zu-Ende-Verschlüsselung ist aktiv</string>
     <string name="room_settings_labs_end_to_end_warnings">Du musst dich abmelden, um die Verschlüsselung aktivieren zu können.</string>
-    <string name="room_settings_never_send_to_unverified_devices_title">Nur für verifizierte Geräte verschlüsseln</string>
-    <string name="room_settings_never_send_to_unverified_devices_summary">Niemals verschlüsselte Nachrichten an unverifizierte Geräte in diesem Raum von diesem Gerät senden.</string>
+    <string name="room_settings_never_send_to_unverified_devices_title">Nur für verifizierte Sitzungen verschlüsseln</string>
+    <string name="room_settings_never_send_to_unverified_devices_summary">Niemals verschlüsselte Nachrichten an unverifizierte Sitzungen in diesem Raum von dieser Sitzung senden.</string>
 
     <!-- Raum settings: advanced addresses -->
     <string name="room_settings_addresses_no_local_addresses">Dieser Raum hat keine lokalen Adressen</string>
@@ -608,11 +608,11 @@ Beachte: Diese Aktion wird die App neu starten und einige Zeit brauchen.</string
     <string name="encryption_information_session_id">Sitzungs-ID</string>
     <string name="encryption_information_decryption_error">Entschlüsselungsfehler</string>
 
-    <string name="encryption_information_sender_device_information">Absendergeräteinformationen</string>
+    <string name="encryption_information_sender_device_information">Informationen der Absendersitzung</string>
     <string name="encryption_information_device_name">Öffentlicher Name</string>
     <string name="encryption_information_name">Öffentlicher Name</string>
     <string name="encryption_information_device_id">ID</string>
-    <string name="encryption_information_device_key">Geräte-Schlüssel</string>
+    <string name="encryption_information_device_key">Sitzungsschlüssel</string>
     <string name="encryption_information_verification">Verifizierungsstatus</string>
     <string name="encryption_information_ed25519_fingerprint">Ed25519-Fingerabdruck</string>
 
@@ -630,43 +630,39 @@ Achtung: Diese Datei wird vielleicht gelöscht, wenn die App deinstalliert wird.
     <string name="encryption_import_room_keys">Raumschlüssel importieren</string>
     <string name="encryption_import_room_keys_summary">Schlüssel aus lokaler Datei importieren</string>
     <string name="encryption_import_import">Importieren</string>
-    <string name="encryption_never_send_to_unverified_devices_title">Nur zu verifizierten Geräten verschlüsseln</string>
-    <string name="encryption_never_send_to_unverified_devices_summary">Von diesem Gerät aus keine verschlüsselten Nachrichten an nicht verifizierte Geräte senden.</string>
+    <string name="encryption_never_send_to_unverified_devices_title">Nur zu verifizierten Sitzungen verschlüsseln</string>
+    <string name="encryption_never_send_to_unverified_devices_summary">Von dieser Sitzung aus keine verschlüsselten Nachrichten an nicht-verifizierte Sitzungen senden.</string>
 
     <string name="encryption_information_not_verified">NICHT verifiziert</string>
     <string name="encryption_information_verified">Verifiziert</string>
     <string name="encryption_information_blocked">Auf der Blockierliste</string>
 
-    <string name="encryption_information_unknown_device">Unbekanntes Gerät</string>
+    <string name="encryption_information_unknown_device">unbekannte Sitzung</string>
     <string name="encryption_information_none">Nichts</string>
 
     <string name="encryption_information_verify">Bestätigen</string>
     <string name="encryption_information_unverify">Verifiz. widerrufen</string>
-    <string name="encryption_information_block">Blockieren</string>
+    <string name="encryption_information_block">Sperren</string>
     <string name="encryption_information_unblock">Zulassen</string>
 
-    <string name="encryption_information_verify_device">Gerät verifizieren</string>
-    <string name="encryption_information_verify_device_warning">Um zu verifizieren, dass diesem Gerät vertraut werden kann, kontaktiere bitte den Besitzer des Gerätes über andere Kommunikationsmittel (z. B. persönlich oder telefonisch) und vergewissere dich, ob der Schüssel, den er in seinen Benutzereinstellungen für dieses Gerät sieht, mit folgendem übereinstimmt:</string>
-    <string name="encryption_information_verify_device_warning2">Wenn er übereinstimmt, drücke unten den Bestätigen-Button. Stimmt er nicht überein, überwacht jemand anderes dieses Gerät und du solltest ggf. den Blockieren-Button drücken. In Zukunft wird dieser Bestätigungsprozess noch komfortabler gestaltet.</string>
-    <string name="encryption_information_verify_key_match">Ja, die Schlüssel stimmen überein</string>
+    <string name="encryption_information_verify_device">Sitzung verifizieren</string>
+    <string name="encryption_information_verify_device_warning">Um zu verifizieren, dass dieser Sitzung vertraut werden kann, kontaktiere bitte den/die Eigentümer!n der Sitzung über andere Kommunikationsmittel (z. B. persönlich oder telefonisch) und vergewissere dich, ob der Schüssel, den er/sie in den Benutzereinstellungen für diese Sitzung sieht, mit folgendem übereinstimmt:</string>
+    <string name="encryption_information_verify_device_warning2">Wenn er übereinstimmt, drücke unten den Bestätigen-Button. Stimmt er nicht überein, überwacht jemand anderes diese Sitzung und du solltest ggf. den Blockieren-Button drücken. In Zukunft wird dieser Bestätigungsprozess noch komfortabler gestaltet.</string>
+    <string name="encryption_information_verify_key_match">Ich bestätige, dass die Schlüssel übereinstimmen</string>
 
     <string name="e2e_enabling_on_app_update">Riot unterstützt jetzt Ende-zu-Ende-Verschlüsselung, du musst dich jedoch erneut anmelden, um sie zu aktivieren.
 
 Du kannst sie jetzt aktivieren oder später über das Einstellungsmenü.</string>
 
     <!-- unknown devices management -->
-    <string name="unknown_devices_alert_title">Raum enthält unbekannte Geräte</string>
-    <string name="unknown_devices_alert_message">Dieser Raum enthält unbekannte Geräte, die noch nicht verifiziert wurden.
-Es gibt also keine Garantie, dass diese Geräte wirklich dem angegebenen Benutzer gehören.
-Wir empfehlen, den Verifizierungsprozess für jedes Gerät zu durchlaufen, bevor du fortfährst. Du kannst die Nachricht aber auch ohne Verifizierung senden, wenn du das vorziehst.
-
-Unbekannte Geräte:</string>
+    <string name="unknown_devices_alert_title">Raum enthält unbekannte Sitzungen</string>
+    <string name="unknown_devices_alert_message">Dieser Raum enthält unbekannte Sitzungen, die noch nicht verifiziert wurden. Es gibt also keine Garantie, dass diese Sitzung wirklich der angegebenen Person gehören. Wir empfehlen, den Verifizierungsprozess für jedes Gerät zu durchlaufen, bevor du fortfährst. Du kannst die Nachricht aber auch ohne Verifizierung senden, wenn du das vorziehst. Unbekannte Sitzungen:</string>
 
     <!-- directory activity  -->
     <string name="select_room_directory">Raum-Verzeichnis auswählen</string>
     <string name="directory_server_fail_to_retrieve_server">Der Server kann nicht verfügbar oder überlastet sein</string>
     <string name="directory_server_type_homeserver">Gib einen Heimserver ein, um seine öffentlichen Räume aufzulisten</string>
-    <string name="directory_server_placeholder">Home-Server-URL</string>
+    <string name="directory_server_placeholder">Heimserver-URL</string>
     <string name="directory_server_all_rooms_on_server">Alle Räume auf dem %s-Server</string>
     <string name="directory_server_native_rooms">Alle nativen %s-Räume</string>
 
@@ -686,7 +682,7 @@ Unbekannte Geräte:</string>
     <string name="media_saving_period_3_days">3 Tage</string>
     <string name="media_saving_period_1_week">1 Woche</string>
     <string name="media_saving_period_1_month">1 Monat</string>
-    <string name="media_saving_period_forever">Für immer</string>
+    <string name="media_saving_period_forever">Unbegrenzt</string>
 
     <string name="offline">Offline</string>
 
@@ -702,11 +698,11 @@ Unbekannte Geräte:</string>
     <string name="larger">Größer</string>
     <string name="tiny">Sehr klein</string>
     <string name="huge">Riesig</string>
-    <string name="settings_theme">Thema</string>
+    <string name="settings_theme">Design</string>
 
     <string name="settings_12_24_timestamps">Zeige Zeitstempel im 12-Stunden-Format</string>
 
-    <string name="widget_no_power_to_manage">Für das Verwalten von Widgets in diesem Raum ist eine Berechtigung erforderlich</string>
+    <string name="widget_no_power_to_manage">Um Widgets in diesem Raum zu verwalten, ist eine Berechtigung erforderlich</string>
     <string name="widget_creation_failure">Widget konnte nicht erstellt werden</string>
     <string name="event_formatter_widget_added">%1$s hinzugefügt von %2$s</string>
     <string name="event_formatter_widget_removed">%1$s entfernt von %2$s</string>
@@ -724,9 +720,9 @@ Unbekannte Geräte:</string>
     <string name="settings_notification_ringtone">Benachrichtigungston</string>
     <string name="widget_integration_failed_to_send_request">Anfrage konnte nicht gesendet werden.</string>
     <string name="widget_integration_missing_user_id">Anfrage enthält keine user_id.</string>
-    <string name="light_theme">Helles Thema</string>
-    <string name="dark_theme">Dunkles Thema</string>
-    <string name="black_them">Schwarzes Thema</string>
+    <string name="light_theme">Helles Design</string>
+    <string name="dark_theme">Dunkles Design</string>
+    <string name="black_them">Schwarzes Design</string>
 
     <string name="login_mobile_device">Mobilgerät</string>
 
@@ -735,9 +731,9 @@ Unbekannte Geräte:</string>
 
     <string name="settings_containing_my_display_name">Nachrichten, die meinen Anzeigenamen enthalten</string>
     <string name="settings_containing_my_user_name">Nachrichten, die meinen Benutzernamen enthalten</string>
-    <string name="you_added_a_new_device">Du hast das neue Gerät \'%s\' hinzugefügt, das jetzt Verschlüsselungs-Schlüssel anfordert.</string>
-    <string name="your_unverified_device_requesting">Dein bislang nicht verifiziertes Gerät \'%s\' fordert Verschlüsselungs-Schlüssel an.</string>
-    <string name="start_verification">Verifizierung starten</string>
+    <string name="you_added_a_new_device">Du hast die neue Sitzung \'%s\' hinzugefügt, die jetzt Verschlüsselungs-Schlüssel anfordert.</string>
+    <string name="your_unverified_device_requesting">Deine bislang nicht verifiziertes Sitzung \'%s\' fordert Verschlüsselungs-Schlüssel an.</string>
+    <string name="start_verification">Verifizierung beginnen</string>
     <string name="call">Anruf</string>
     <string name="notification_noisy_notifications">Laute Benachrichtigungen</string>
     <string name="notification_silent_notifications">Lautlose Benachrichtigungen</string>
@@ -930,7 +926,7 @@ Willst du welche hinzufügen?</string>
 \n 
 \nDie Sichtbarkeit deiner Nachrichten ist ähnlich wie bei E-Mails: Wenn deine Nachrichten gelöscht werden, bedeutet dies, dass von dir verschickte Nachrichten nicht mit neuen oder unregistrierten Nutzern geteilt werden. Aber registrierte Nutzer, die bereits Zugang zu diesen Nachrichten haben, behalten weiterhin Zugriff auf ihr Exemplar.</string>
     <string name="deactivate_account_delete_checkbox">Bitte alle Nachrichten, die ich gesendet habe, löschen, wenn mein Account deaktiviert wird (Warnung: Unterhaltungen werden für zukünftige Nutzer unvollständig erscheinen)</string>
-    <string name="deactivate_account_prompt_password">Um fortzufahren, bitte Password eingeben:</string>
+    <string name="deactivate_account_prompt_password">Um fortzufahren, bitte Passwort eingeben:</string>
     <string name="deactivate_account_submit">Account deaktivieren</string>
 
     <string name="dialog_title_third_party_licences">Drittanbieter-Lizenzen</string>
@@ -938,7 +934,7 @@ Willst du welche hinzufügen?</string>
     <string name="download">Download</string>
     <string name="speak">Sprechen</string>
     <string name="clear">Leeren</string>
-    <string name="e2e_re_request_encryption_key">Verschlüsselungsschlüssel von deinen anderen Sitzungen <u>erneut anfragen</u>.</string>
+    <string name="e2e_re_request_encryption_key">Verschlüsselungsschlüssel von deinen anderen Sitzungen erneut anfragen.</string>
 
     <string name="e2e_re_request_encryption_key_sent">Schlüsselanfrage gesendet.</string>
 
@@ -1053,7 +1049,7 @@ Beachte: Diese Aktion wird die App neu starten und einige Zeit brauchen.</string
 
     <string name="encryption_export_notice">Bitte eine Passphrase erstellen um exportierte Schlüssel zu verschlüsseln. Du musst dieselbe Passphrase eingeben um die Schlüssel importieren zu können.</string>
     <string name="passphrase_create_passphrase">Erzeuge Passphrase</string>
-    <string name="passphrase_passphrase_does_not_match">Passphrasen müssen übereinstimmen</string>
+    <string name="passphrase_passphrase_does_not_match">Passphrasen stimmen nicht überein</string>
     <string name="merged_events_expand">aufklappen</string>
     <string name="merged_events_collapse">Zusammenklappen</string>
 
@@ -1169,7 +1165,7 @@ Versuche die Anwendung neuzustarten.</string>
     <string name="settings_troubleshoot_test_battery_success">Riot wird nicht von Batterieoptimierungen beeinflusst.</string>
     <string name="settings_notification_troubleshoot">Fehler bei Benachrichtigungen finden</string>
     <string name="settings_troubleshoot_diagnostic">Diagnose von Fehlern</string>
-    <string name="settings_troubleshoot_diagnostic_success_status">Basisdiagnose ist OK. Wenn du immer noch keine Benachrichtigungen bekommst, sende bitte einen Fehlerbericht, damit dies untersucht werden kann.</string>
+    <string name="settings_troubleshoot_diagnostic_success_status">Basisdiagnose ist OK. Wenn du immer noch keine Benachrichtigungen bekommst, sende bitte einen Fehlerbericht, um uns beim nachforschen zu helfen.</string>
     <string name="settings_troubleshoot_test_play_services_title">Prüfung der Play-Dienste</string>
     <string name="settings_troubleshoot_test_play_services_success">Google Play-Dienste-APK ist verfügbar und aktuell.</string>
     <string name="settings_troubleshoot_test_token_registration_title">Token-Registrierung</string>
@@ -1190,21 +1186,21 @@ Versuche die Anwendung neuzustarten.</string>
 
     <string name="store_title">Riot.im - Kommuniziere auf deine Weise</string>
     <string name="store_short_description">Eine universelle, sichere Chat-App - komplett unter deiner Kontrolle.</string>
-    <string name="store_full_description">"Eine Chat-App unter deiner Kontrolle und total flexibel. Riot lässt dich auf die Art kommunizieren wie du willst. Die App wurde gemacht für [matrix] - dem Standard für offene, dezentrale Komunikation.
-
-Hole dir ein kostenloses Konto auf matrix.org, hol dir einen eigenen Server auf https://modular.im oder nutze einen anderen Matrix-Server.
-
-Warum solltest du Riot.im wählen?
-
-• KOMPLETTE KOMMUNIKATION: Baue Räume um deine Teams, deine Freunde, deine Community - wie auch immer du willst! Chatte, teile Dateien, füge Widgets hinzu und führe Sprach- und Videotelefonate - alles kostenlos.
-
-• MÄCHTIGE INTEGRATIONEN: Benutze Riot.im mit den Werkzeugen die du kennst und liebst. Mit Riot.im kannst du sogar mit Personen und Gruppen chatten, die andere Chat-Anwendungen benutzen.
-
-• PRIVAT UND SICHER: Halte deine Konversationen geheim. Aktuellste Ende-zu-Ende-Verschlüsselung sorgt dafür, dass deine private Kommunikation auch privat bleibt.
-
-• OFFEN - NICHT VERSCHLOSSEN: Quelloffen und basierend auf Matrix. Behalte deine Daten indem du deinen eigenen Server betreibst oder einen auswählst dem du vertraust.
-
-• WO AUCH IMMER DU BIST: Bleibe im Kontakt wo auch immer du bist wobei deine Nachrichtenhistorie zwischen all deinen Geräten synchronisiert wird. Das andere \"Gerät\" kann auch ein Browser sein. Schau dir dazu auch riot.im an."</string>
+    <string name="store_full_description">Eine Chat-App unter deiner Kontrolle und total flexibel. Riot lässt dich auf die Art kommunizieren, wie du willst. Die App wurde gemacht für [matrix] - dem Standard für offene, dezentrale Komunikation.
+\n
+\nHole dir ein kostenloses Konto auf matrix.org, hol dir einen eigenen Server auf https://modular.im oder nutze einen anderen Matrix-Server.
+\n
+\nWarum solltest du Riot.im wählen\?
+\n
+\n• KOMPLETTE KOMMUNIKATION: Baue Räume um deine Teams, deine Freunde, deine Community - wie auch immer du willst! Chatte, teile Dateien, füge Widgets hinzu und führe Sprach- und Videotelefonate - alles kostenlos.
+\n
+\n• MÄCHTIGE INTEGRATIONEN: Benutze Riot.im mit den Werkzeugen die du kennst und liebst. Mit Riot.im kannst du sogar mit Personen und Gruppen chatten, die andere Chat-Anwendungen benutzen.
+\n
+\n• PRIVAT UND SICHER: Halte deine Konversationen geheim. Aktuellste Ende-zu-Ende-Verschlüsselung sorgt dafür, dass deine private Kommunikation auch privat bleibt.
+\n
+\n• OFFEN - NICHT VERSCHLOSSEN: Quelloffen und basierend auf Matrix. Behalte deine Daten indem du deinen eigenen Server betreibst oder einen auswählst dem du vertraust.
+\n
+\n• WO AUCH IMMER DU BIST: Bleibe im Kontakt wo auch immer du bist, wobei deine Nachrichtenhistorie zwischen all deinen Geräten und auch deinem Messenger im Browser synchronisiert wird. Schau dir dazu auch riot.im an.</string>
 
     <string name="video_call_in_progress">Videogespräch aktiv…</string>
 
@@ -1243,15 +1239,15 @@ Um sicherzustellen, dass du nichts verpasst, lass deine Updates einfach aktivier
     <string name="keys_backup_setup_step1_title">Verliere nie wieder verschlüsselte Nachrichten</string>
     <string name="keys_backup_setup_step2_button_title">Setze Passphrase</string>
     <string name="keys_backup_setup_step3_button_title">Erledigt</string>
-    <string name="keys_backup_setup_step3_copy_button_title">Speichere Wiederherstellungsschlüsse</string>
+    <string name="keys_backup_setup_step3_copy_button_title">Wiederherstellungsschlüssel speichern</string>
     <string name="keys_backup_setup_step3_save_button_title">Sichere als Datei</string>
     <string name="keys_backup_setup_step3_please_make_copy">Bitte mache eine Kopie</string>
-    <string name="keys_backup_setup_step3_share_intent_chooser_title">Teile den Wiederherstellungsschlüssel mit…</string>
+    <string name="keys_backup_setup_step3_share_intent_chooser_title">Wiederherstellungsschlüssel teilen mit…</string>
     <string name="recovery_key">Wiederherstellungsschlüssel</string>
     <string name="unexpected_error">Unerwarteter Fehler</string>
     <string name="keys_backup_setup_backup_started_title">Sicherung gestartet</string>
     <string name="keys_backup_setup_skip_title">Bist du sicher?</string>
-    <string name="keys_backup_restore_key_enter_hint">Gebe Wiederherstellungsschlüssel ein</string>
+    <string name="keys_backup_restore_key_enter_hint">Wiederherstellungsschlüssel eingeben</string>
 
     <string name="keys_backup_restore_setup_recovery_key">Nachrichtenwiederherstellung</string>
 
@@ -1277,61 +1273,61 @@ Dieser Fehler ist außerhalb von Riot passiert. Es gibt kein Google-Konto auf de
     <string name="settings_cryptography_manage_keys">Verwaltung der Krypto-Schlüssel</string>
     <string name="encryption_settings_manage_message_recovery_summary">Schlüssel-Sicherung verwalten</string>
 
-    <string name="keys_backup_setup_step1_description">Nachrichten in verschlüsselten Räumen sind mit Ende-zu-Ende-Verschlüsselung gesichert. Nur du und der/die Empfänger haben die Schlüssel um diese Nachrichten zu lesen.
+    <string name="keys_backup_setup_step1_description">Nachrichten in verschlüsselten Räumen sind mit Ende-zu-Ende-Verschlüsselung gesichert. Nur du und der/die Empfänger!nnen haben die Schlüssel um diese Nachrichten zu lesen. 
+\n
+\nSichere deine Schlüssel, um sie nicht zu verlieren.</string>
+    <string name="recovery_key_export_saved_as_warning">Der Wiederherstellungsschlüssel wurde nach \'%s\' gespeichert. 
+\n
+\nWarnung: Diese Datei wird gelöscht, wenn die Anwendung deinstalliert wird.</string>
 
-Sichere deine Schlüssel um sie nicht zu verlieren.</string>
-    <string name="recovery_key_export_saved_as_warning">Dieser Wiederherstellungsschlüssel wurde nach \'%s\' gespeichert.
-
-Warnung: Diese Datei wird gelöscht wenn die Anwendung deinstalliert wird.</string>
-
-    <string name="keys_backup_setup_step3_generating_key_status">Generiere Wiederherstellungsschlüssel aus der Passphrase. Dies kann mehrere Sekunden brauchen.</string>
+    <string name="keys_backup_setup_step3_generating_key_status">Wiederherstellungsschlüssel aus Passphrase generieren. Dies kann mehrere Sekunden brauchen.</string>
     <string name="keys_backup_setup_backup_started_message">Deine Verschlüsselungsschlüssel werden nun im Hintergrund auf deinem Heimserver gesichert. Die initiale Sicherung kann mehrere Minuten dauern.</string>
 
 
-    <string name="keys_backup_setup_skip_msg">Du kannst den Zugang zu deinen Nachrichten verlieren wenn du dich abmeldest oder das Gerät verlierst.</string>
+    <string name="keys_backup_setup_skip_msg">Du kannst den Zugang zu deinen Nachrichten verlieren, wenn du dich abmeldest oder das Gerät verlierst.</string>
 
     <string name="keys_backup_restore_is_getting_backup_version">Rufe Backupversion ab…</string>
     <string name="keys_backup_restore_with_passphrase">Nutze deine Wiederherstellungspassphrase um deinen sicheren Chatverlauf zu entschlüsseln</string>
     <string name="keys_backup_restore_use_recovery_key">nutze deinen Wiederherstellungsschlüssel</string>
     <string name="keys_backup_restore_with_passphrase_helper_with_link">Wen du deine Wiederherstellungspassphrase nicht weißt, kannst du %s.</string>
 
-    <string name="keys_backup_restore_with_recovery_key">Nutze deinen Wiederherstellungsschlüssel um deinen sicheren Chatverlauf zu entschlüsseln</string>
-    <string name="keys_backup_restore_with_key_helper">Hast du deinen Wiederherstellungsschlüssel verloren? Du kannst einen neuen in den Einstellungen einrichten.</string>
+    <string name="keys_backup_restore_with_recovery_key">Nutze deinen Wiederherstellungsschlüssel um deinen verschlüsselten Chatverlauf zu entschlüsseln</string>
+    <string name="keys_backup_restore_with_key_helper">Wiederherstellungsschlüssel verloren\? Du kannst einen neuen in den Einstellungen einrichten.</string>
     <string name="keys_backup_passphrase_error_decrypt">Sicherung konnte mit dieser Passphrase nicht entschlüsselt werden. Bitte stelle sicher, dass du die korrekte Wiederherstellungspassphrase eingegeben hast.</string>
     <string name="network_error_please_check_and_retry">Netzwerkfehler: Bitte überprüfe deine Verbindung und versuche es erneut.</string>
 
-    <string name="keys_backup_recovery_code_empty_error_message">Bitte gebe deinen Wiederherstellungsschlüssel ein</string>
+    <string name="keys_backup_recovery_code_empty_error_message">Bitte gib deinen Wiederherstellungsschlüssel ein</string>
     <string name="keys_backup_recovery_code_error_decrypt">Sicherung konnte mit diesem Wiederherstellungsschlüssel nicht entschlüsselt werden. Bitte stelle sicher, dass du den korrekten Wiederherstellungsschlüssel eingegeben hast.</string>
 
     <string name="keys_backup_restore_success_title">Sicherung wiederhergestellt %s !</string>
-    <string name="keys_backup_restore_success_description">%1$d Sitzungsschlüssel wurden wiederhergestellt und %2$d vorher unbekannte Schlüssel wurden hinzugefügt</string>
+    <string name="keys_backup_restore_success_description">%1$d Sitzungsschlüssel wurde(n) wiederhergestellt und %2$d vorher unbekannte(r) Schlüssel wurde(n) hinzugefügt</string>
     <plurals name="keys_backup_restore_success_description_part1">
         <item quantity="one">Backup mit %d Schlüssel wiederhergestellt.</item>
         <item quantity="other">Backup mit %d Schlüssel wiederhergestellt.</item>
     </plurals>
     <plurals name="keys_backup_restore_success_description_part2">
-        <item quantity="one">%d neuer Schlüssel wurde diesem Gerät hinzugefügt.</item>
-        <item quantity="other">%d neue Schlüssel wurde diesem Gerät hinzugefügt.</item>
+        <item quantity="one">%d neuer Schlüssel wurde dieser Sitzung hinzugefügt.</item>
+        <item quantity="other">%d neue Schlüssel wurden dieser Sitzung hinzugefügt.</item>
     </plurals>
 
     <string name="keys_backup_get_version_error">Konnte letzte Version der Wiederherstellungsschlüssel nicht laden (%s).</string>
     <string name="keys_backup_no_keysbackup_sdk_error">Sitzungsverschlüsselung ist nicht aktiviert</string>
 
 
-    <string name="keys_backup_settings_status_ok">Schlüsselsicherung wurde auf diesem Gerät korrekt eingerichtet.</string>
-    <string name="keys_backup_settings_status_ko">Schlüsselsicherung ist auf diesem Gerät nicht aktiv.</string>
-    <string name="keys_backup_settings_status_not_setup">Deine Schlüssel werden nicht von diesem Gerät gesichert.</string>
+    <string name="keys_backup_settings_status_ok">Die Schlüsselsicherung wurde für diese Sitzung korrekt eingerichtet.</string>
+    <string name="keys_backup_settings_status_ko">Die Schlüsselsicherung ist in dieser Sitzung nicht aktiv.</string>
+    <string name="keys_backup_settings_status_not_setup">Ihre Schlüssel werden von dieser Sitzung nicht gesichert.</string>
 
 
-    <string name="keys_backup_settings_signature_from_unknown_device">Sicherung hat eine Signatur von einem unbekannten Gerät mit ID %s.</string>
-    <string name="keys_backup_settings_valid_signature_from_this_device">Sicherung hat eine valide Sicherung von diesem Gerät.</string>
-    <string name="keys_backup_settings_valid_signature_from_verified_device">Sicherung hat eine valide Signatur vom verifiziertem Gerät %s.</string>
-    <string name="keys_backup_settings_valid_signature_from_unverified_device">Sicherung hat eine valide Signatur vom unverifiziertem Gerät %s</string>
-    <string name="keys_backup_settings_invalid_signature_from_verified_device">Sicherung hat eine invalide Signatur vom verifiziertem Gerät %s</string>
-    <string name="keys_backup_settings_invalid_signature_from_unverified_device">Sicherung hat eine invalide Signatur vom unverifiziertem Gerät %s</string>
-    <string name="keys_backup_get_trust_error">Konnte Vertrauensinformationen für die Sicherung nicht abrufen (%s).</string>
+    <string name="keys_backup_settings_signature_from_unknown_device">Sicherung hat eine Signatur von einer unbekannten Sitzung mit der ID %s.</string>
+    <string name="keys_backup_settings_valid_signature_from_this_device">Sicherung hat eine valide Sicherung von dieser Sitzung.</string>
+    <string name="keys_backup_settings_valid_signature_from_verified_device">Die Sicherung hat eine gültige Signatur von der verifizierten Sitzung %s.</string>
+    <string name="keys_backup_settings_valid_signature_from_unverified_device">Die Sicherung hat eine gültige Signatur von der nicht verifizierten Sitzung %s</string>
+    <string name="keys_backup_settings_invalid_signature_from_verified_device">Die Sicherung hat eine ungültige Signatur von der verifizierten Sitzung %s</string>
+    <string name="keys_backup_settings_invalid_signature_from_unverified_device">Die Sicherung hat eine ungültige Signatur von der nicht verifizierten Sitzung %s</string>
+    <string name="keys_backup_get_trust_error">Abfrage der Vertrauensinformationen für die Sicherung fehlgeschlagen (%s).</string>
 
-    <string name="keys_backup_settings_untrusted_backup">Um Sichere Nachrichtenwiederherstellung auf diesem Gerät zu nutzen, gebe jetzt deine Wiederherstellungspassphrase oder -schlüssel ein.</string>
+    <string name="keys_backup_settings_untrusted_backup">Um die Schlüsselsicherung für diese Sitzung zu verwenden, stelle sie jetzt mit deiner Passphrase oder deinem Wiederherstellungsschlüssel wieder her.</string>
     <string name="keys_backup_settings_delete_confirm_message">Deine gesicherten Verschlüsselungsschlüssel vom Server löschen\? Du wirst deinen Wiederherstellungsschlüssel nicht mehr nutzen können, um deinen verschlüsselten Chatverlauf zu lesen.</string>
 
     <string name="sign_out_bottom_sheet_warning_no_backup">Beim Ausloggen gehen ihre verschlüsselten Nachrichten verloren</string>
@@ -1340,17 +1336,17 @@ Warnung: Diese Datei wird gelöscht wenn die Anwendung deinstalliert wird.</stri
     <string name="sign_out_bottom_sheet_dont_want_secure_messages">Ich möchte meine verschlüsselten Nachrichten nicht</string>
     <string name="sign_out_bottom_sheet_backing_up_keys">Sichere Schlüssel…</string>
     <string name="keys_backup_activate">Schlüssel-Sicherung verwenden</string>
-    <string name="are_you_sure">Sind Sie sicher?</string>
+    <string name="are_you_sure">Bist du sicher\?</string>
     <string name="backup">Sicherung</string>
-    <string name="sign_out_bottom_sheet_will_lose_secure_messages">Alle verschlüsselten Nachrichten gehen verloren wenn Sie sich ausloggen ohne diese vorher zu sichern.</string>
+    <string name="sign_out_bottom_sheet_will_lose_secure_messages">Alle verschlüsselten Nachrichten gehen verloren wenn du dich ausloggst ohne diese vorher zu sichern.</string>
 
     <string name="stay">Bleiben</string>
     <string name="abort">Abbrechen</string>
 
-    <string name="action_sign_out_confirmation_simple">Sind Sie sicher, dass sie sich ausloggen möchten?</string>
+    <string name="action_sign_out_confirmation_simple">Bist du sicher, dass du dich ausloggen möchtest\?</string>
 
     <string name="encryption_message_recovery">Wiederherstellung verschlüsselter Nachrichten</string>
-    <string name="error_empty_field_enter_user_name">Bitte geben Sie einen Benutzernamen ein.</string>
+    <string name="error_empty_field_enter_user_name">Bitte gib einen Benutzernamen ein.</string>
     <string name="settings_data_save_mode_summary">Der datensparsame Modus sorgt dafür, dass die Präsenz- und Tipp-Benachrichtigungen ausgefiltert werden.</string>
 
     <string name="keys_backup_setup">Richte Schlüsselsicherung ein</string>
@@ -1363,26 +1359,26 @@ Warnung: Diese Datei wird gelöscht wenn die Anwendung deinstalliert wird.</stri
 Für maximale Sicherheit sollte diese *nicht* dein Konto-Passwort sein.</string>
     <string name="keys_backup_setup_creating_backup">Erstelle Sicherung</string>
     <string name="keys_backup_setup_step1_recovery_key_alternative">Oder schütze deine Sicherung mit einem Wiederherstellungsschlüssel den du sicher verwahrst.</string>
-    <string name="keys_backup_setup_step2_skip_button_title">(Erweitert) Richte Wiederherstellungsschlüssel ein</string>
-    <string name="keys_backup_setup_step3_success_title">Erfolgreich!</string>
+    <string name="keys_backup_setup_step2_skip_button_title">(Erweitert) Wiederherstellungsschlüssel einrichten</string>
+    <string name="keys_backup_setup_step3_success_title">Erfolg!</string>
     <string name="keys_backup_setup_step3_text_line1">Deine Schlüssel wurden gesichert.</string>
     <string name="keys_backup_setup_step3_text_line2">Dein Wiederherstellungsschlüssel ist ein Sicherungsnetz - du kannst es benutzen um den Zugriff auf deine verschlüsselten Nachrichten wiederherzustellen, falls du deine Passphrase vergisst.
 Verwahre deinen Wiederherstellungsschlüssel an einem sehr sicheren Ort wie einem Passwortmanager (oder Safe)</string>
-    <string name="keys_backup_setup_step3_text_line2_no_passphrase">Verwahre deinen Wiederherstellungsschlüssel an einem sehr sicheren Ort wie einem Passwortmanager (oder Safe)</string>
+    <string name="keys_backup_setup_step3_text_line2_no_passphrase">Bewahre deinen Wiederherstellungsschlüssel an einem sehr sicheren Ort wie einem Passwortmanager (oder Safe) auf</string>
     <string name="keys_backup_setup_step3_button_title_no_passphrase">Ich habe eine Kopie angefertigt</string>
-    <string name="keys_backup_setup_step3_share_recovery_file">Teile</string>
+    <string name="keys_backup_setup_step3_share_recovery_file">Teilen</string>
     <string name="new_recovery_method_popup_title">Neue Schlüsselsicherung</string>
     <string name="new_recovery_method_popup_description">Eine neue Schlüsselsicherung wurde entdeckt.
-
-Wenn du diese neue Wiederherstellungsmethode nicht eingerichtet hast, kann ein Angreifer versuchen Zugriff auf dein Konto zu erhalten. Ändere dein Passwort und richte sofort eine neue Wiederherstellungsmethode in den Einstellungen ein.</string>
+\n
+\nWenn du die neue Wiederherstellungsmethode nicht festgelegt hast, kann ein/e Angreifer!n versuchen auf dein Konto zuzugreifen. Ändere dein Passwort und richte sofort eine neue Wiederherstellungsmethode in den Einstellungen ein.</string>
     <string name="new_recovery_method_popup_was_me">Ich war es</string>
     <string name="keys_backup_banner_setup_line1">Verliere nie mehr verschlüsselte Nachrichten</string>
-    <string name="keys_backup_banner_setup_line2">Richte Schlüsselsicherung ein</string>
+    <string name="keys_backup_banner_setup_line2">Richte die Schlüsselsicherung ein</string>
 
     <string name="keys_backup_banner_recover_line1">Verliere nie wieder verschlüsselte Nachrichten</string>
     <string name="keys_backup_banner_recover_line2">Benutze Schlüsselsicherung</string>
 
-    <string name="keys_backup_banner_update_line1">Neue Schlüssel für verschlüsselte Nachrichten</string>
+    <string name="keys_backup_banner_update_line1">Neue sichere Schlüssel für Nachrichten</string>
     <string name="keys_backup_banner_update_line2">Verwalte Schlüsselsicherung</string>
 
     <string name="keys_backup_banner_in_progress">Sichere Schlüssel…</string>
@@ -1444,55 +1440,55 @@ Wenn du diese neue Wiederherstellungsmethode nicht eingerichtet hast, kann ein A
     <string name="notification_sender_me">Ich</string>
     <string name="notification_inline_reply_failed">** Fehler beim Senden - bitte Raum öffnen</string>
 
-    <string name="error_jitsi_not_supported_on_old_device">Entschuldige, doch Konferenzgespräche mittels Jitsi wird auf alten Geräten nicht unterstützt (älter als Android 5.0)</string>
+    <string name="error_jitsi_not_supported_on_old_device">Entschuldigung, Konferenzanrufe mit Jitsi werden auf älteren Geräten (mit älteren Android-Versionen als 5.0) nicht unterstützt</string>
 
     <string name="title_activity_verify_device">Sitzung verifizieren</string>
 
     <string name="encryption_information_unknown_ip">Unbekannte IP-Adresse</string>
-    <string name="you_added_a_new_device_with_info">Ein neues Gerät fordert Verschlüsselungs-Schlüssel an.
-\nGerätename: %1$s
-\nZuletzt gesehen: %2$s
-\nWenn du dich nicht auf einem anderen Gerät angemeldet hast, ignoriere diese Anfrage.</string>
-    <string name="your_unverified_device_requesting_with_info">Ein unverifiziertes Gerät fordert Verschlüsselungs-Schlüssel an.
-\nGerätename: %1$s
-\nZuletzt gesehen: %2$s
-\nWenn du dich nicht auf einem anderen Gerät angemeldet hast, ignoriere diese Anfrage.</string>
+    <string name="you_added_a_new_device_with_info">Eine neue Sitzung fordert Verschlüsselungs-Schlüssel an. 
+\nSitzungsname: %1$s 
+\nZuletzt gesehen: %2$s 
+\nWenn du dich nicht mit einer anderen Sitzung angemeldet hast, ignoriere diese Anfrage.</string>
+    <string name="your_unverified_device_requesting_with_info">Eine unverifizierte Sitzung fordert Verschlüsselungs-Schlüssel an. 
+\nSitzungsname: %1$s 
+\nZuletzt gesehen: %2$s 
+\nWenn du nicht eine andere Sitzung angemeldet hast, ignoriere diese Anfrage.</string>
 
     <string name="start_verification_short_label">Verifizieren</string>
     <string name="share_without_verifying_short_label">Teilen</string>
     <string name="ignore_request_short_label">Ignorieren</string>
 
-    <string name="keys_backup_setup_override_backup_prompt_tile">Auf deinem HomeServer existiert bereits eine Sicherung</string>
+    <string name="keys_backup_setup_override_backup_prompt_tile">Auf deinem Heimserver existiert bereits eine Sicherung</string>
     <string name="keys_backup_setup_override_replace">Ersetzen</string>
     <string name="keys_backup_setup_override_stop">Stopp</string>
 
     <string name="keys_backup_settings_checking_backup_state">Überprüfe Sicherungsstatus</string>
     <string name="invalid_or_expired_credentials">Du wurdest abgemeldet, da deine Anmeldedaten falsch oder abgelaufen sind.</string>
 
-    <string name="sas_verify_title">Verifizieren durch Vergleichen eines kurzen Satzes.</string>
+    <string name="sas_verify_title">Verifizieren durch Vergleichen eines kurzen Textes.</string>
     <string name="sas_verify_start_button_title">Starte Verifizierung</string>
     <string name="sas_incoming_request_title">Eingehende Verifizierungsanfrage</string>
-    <string name="sas_incoming_verification_request_dialog">Du hast eine eingehende Verifikationsanfrage erhalten.</string>
-    <string name="sas_view_request_action">Anfragen ansehen</string>
+    <string name="sas_incoming_verification_request_dialog">Du hast eine eingehende Verifizierungsanfrage erhalten.</string>
+    <string name="sas_view_request_action">Anfrage ansehen</string>
     <string name="sas_waiting_for_partner">Warte auf Bestätigung des Partners…</string>
 
     <string name="sas_verified">Verifiziert!</string>
-    <string name="sas_verified_successful">Du hast dieses Gerät erfolgreich verifiziert.</string>
-    <string name="sas_verified_successful_description">Sichere Nachrichten mit diesem Benutzer sind Ende-zu-Ende-verschlüsselt und können nicht von Dritten mitgelesen werden.</string>
+    <string name="sas_verified_successful">Du hast diese Sitzung erfolgreich verifiziert.</string>
+    <string name="sas_verified_successful_description">Sichere Nachrichten mit diesem Benutzer sind Ende-zu-Ende verschlüsselt und können nicht von Dritten mitgelesen werden.</string>
     <string name="sas_got_it">Verstanden</string>
 
-    <string name="sas_verification_request_notification_channel_title">Schlüsselverifikation</string>
+    <string name="sas_verification_request_notification_channel_title">Schlüssel-Verifizierung</string>
     <string name="sas_cancelled_dialog_title">Anfrage abgebrochen</string>
-    <string name="sas_cancelled_by_me">Die Verifizierung ist abgebrochen.
+    <string name="sas_cancelled_by_me">Die Verifizierung wird abgebrochen.
 \nGrund: %s</string>
 
-    <string name="sas_verification_request_notification_channel">Interaktive Geräteverifizierung</string>
-    <string name="sas_incoming_request_notif_title">Verifikationsanfrage</string>
-    <string name="sas_incoming_request_notif_content">%s möchte dein Gerät verifizieren</string>
+    <string name="sas_verification_request_notification_channel">Interaktive Sitzungs-Verifizierung</string>
+    <string name="sas_incoming_request_notif_title">Verifizierungsanfrage</string>
+    <string name="sas_incoming_request_notif_content">%s möchte deine Sitzung verifizieren</string>
 
     <string name="sas_error_m_user">Der Benutzer hat die Verifizierung abgebrochen</string>
     <string name="sas_error_m_timeout">Der Verifizierungsprozess ist abgelaufen</string>
-    <string name="sas_error_m_unexpected_message">Das Gerät hat eine unerwartete Nachricht erhalten</string>
+    <string name="sas_error_m_unexpected_message">Die Sitzung hat eine unerwartete Nachricht erhalten</string>
     <string name="sas_error_m_invalid_message">Eine ungültige Nachricht wurde empfangen</string>
     <string name="sas_error_unknown">Unbekannter Fehler</string>
 
@@ -1548,25 +1544,25 @@ Wenn du diese neue Wiederherstellungsmethode nicht eingerichtet hast, kann ein A
     <string name="settings_integration_manager">Integrationsmanager</string>
 
     <string name="integration_manager_not_configured">Kein Integrationsmanager konfiguriert.</string>
-    <string name="key_share_request">Schlüsselfreigabe Anfordern</string>
-    <string name="keys_backup_setup_override_backup_prompt_description">Es sieht so aus, als hätten Sie bereits ein Setup-Schlüssel-Backup von einem anderen Gerät. Möchten Sie es durch das ersetzen, das Sie gerade erstellen\?</string>
-    <string name="sas_security_advise">Für maximale Sicherheit empfehlen wir, dies persönlich zu tun oder ein anderes vertrauenswürdiges Kommunikationsmittel zu verwenden.</string>
-    <string name="sas_incoming_request_description">Überprüfen Sie dieses Gerät, um es als vertrauenswürdig zu markieren. Das Vertrauen auf Geräte von Partnern gibt Ihnen zusätzliche Sicherheit, wenn Sie verschlüsselte End-to-End-Nachrichten verwenden.</string>
-    <string name="sas_incoming_request_description_2">Das Verifizieren dieses Benutzers wird seine Geräte als \"vertraut\" markieren und dein Gerät bei ihnen als \"vertraut\" markieren.</string>
+    <string name="key_share_request">Schlüsselaustausch anfragen</string>
+    <string name="keys_backup_setup_override_backup_prompt_description">Es sieht so aus, als hättest du bereits ein Setup-Schlüssel-Backup von einer anderen Sitzung. Möchtest du es durch das, was du gerade erstellt hast, ersetzen\?</string>
+    <string name="sas_security_advise">Für maximale Sicherheit empfehlen wir, dies persönlich zu tun, oder ein anderes vertrautes Kommunikationsmedium zu nutzen.</string>
+    <string name="sas_incoming_request_description">Überprüfe diese Sitzung, um sie als vertrauenswürdig zu markieren. Sitzungen von Partner!nnen zu vertrauen gibt dir zusätzliche Sicherheit bei der Verwendung von Ende-zu-Ende verschlüsselten Nachrichten.</string>
+    <string name="sas_incoming_request_description_2">Durch Verifizieren dieser Sitzung wird sie bei dir und deinem Gegenüber als vertrauenswürdig markiert.</string>
 
-    <string name="sas_emoji_description">Überprüfen Sie dieses Gerät, indem Sie bestätigen, dass das folgende Emoji auf dem Bildschirm des Partners angezeigt wird</string>
-    <string name="sas_decimal_description">Überprüfen Sie dieses Gerät, indem Sie bestätigen, dass die folgenden Zahlen auf dem Bildschirm des Partners angezeigt werden</string>
+    <string name="sas_emoji_description">Verifiziere diese Sitzung, indem du bestätigst, dass das folgende Emoji auf dem Bildschirm deines Gegenübers angezeigt wird</string>
+    <string name="sas_decimal_description">Verifiziere diese Sitzung, indem du bestätigst, dass die folgenden Zahlen auf dem Bildschirm deines Gegenübers angezeigt werden</string>
 
-    <string name="sas_verifying_keys">Es ist nichts aufgetaucht\? Noch nicht alle Clients unterstützen die interaktive Verifikation. <button>Nutze alte Verifikation</button>.</string>
-    <string name="sas_legacy_verification_button_title">Verwenden Sie die alte Überprüfung.</string>
+    <string name="sas_verifying_keys">Es ist nichts aufgetaucht\? Noch nicht alle Clients unterstützen die interaktive Verifikation. Nutze die alte Verifikation.<button>Nutze alte Verifikation</button>.</string>
+    <string name="sas_legacy_verification_button_title">Verwende die alte Verifizierungsmethode.</string>
 
-    <string name="sas_error_m_unknown_transaction">Das Gerät kennt diese Transaktion nicht</string>
+    <string name="sas_error_m_unknown_transaction">Die Sitzung kennt diese Transaktion nicht</string>
     <string name="sas_error_m_mismatched_commitment">Die Hash-Verpflichtung stimmte nicht überein</string>
     <string name="sas_error_m_mismatched_sas">Die SAS stimmte nicht überein</string>
-    <string name="sas_error_m_key_mismatch">Wiederherstellungsschlüssel passt nicht</string>
-    <string name="sas_error_m_user_error">Der Benutzer Wiederherstellungsschlüssel passt nicht</string>
-    <string name="room_list_catchup_welcome_body">Informieren Sie sich hier über ungelesene Nachrichten</string>
-    <string name="room_list_people_empty_body">Ihre direkte Konversation wird hier angezeigt</string>
+    <string name="sas_error_m_key_mismatch">Schlüssel-Ungleichheit</string>
+    <string name="sas_error_m_user_error">Benutzer-Ungleichheit</string>
+    <string name="room_list_catchup_welcome_body">Informiere dich hier über ungelesene Nachrichten</string>
+    <string name="room_list_people_empty_body">Deine direkten Konversationen werden hier angezeigt</string>
     <string name="malformed_message">Fehlerhaftes Ereignis, kann nicht angezeigt werden</string>
     <string name="keys_backup_unable_to_get_trust_info">Beim Abrufen der Vertrauensinformationen ist ein Fehler aufgetreten</string>
     <string name="keys_backup_unable_to_get_keys_backup_data">Beim Abrufen der Schlüsselsicherungsdaten ist ein Fehler aufgetreten</string>
@@ -1576,7 +1572,7 @@ Wenn du diese neue Wiederherstellungsmethode nicht eingerichtet hast, kann ein A
     <string name="alpha_disclaimer_content_line_2_gplay_colored_part">Play Store Beschreibung</string>
     <string name="settings_sdk_version">Matrix SDK Version</string>
     <string name="settings_other_third_party_notices">Sonstige Hinweise Dritter</string>
-    <string name="navigate_to_room_when_already_in_the_room">Sie sehen diesen Raum bereits!</string>
+    <string name="navigate_to_room_when_already_in_the_room">Du siehst diesen Raum bereits!</string>
 
     <string name="quick_reactions">Schnelle Reaktionen</string>
 
@@ -1595,8 +1591,8 @@ Wenn du diese neue Wiederherstellungsmethode nicht eingerichtet hast, kann ein A
     <string name="settings_troubleshoot_test_token_registration_quick_fix">Token registrieren</string>
 
     <string name="send_suggestion">Mache einen Vorschlag</string>
-    <string name="send_suggestion_content">Bitte schreiben Sie Ihren Vorschlag unten.</string>
-    <string name="send_suggestion_report_placeholder">Beschreiben Sie hier Ihren Vorschlag</string>
+    <string name="send_suggestion_content">Bitte schreibe unten deine Anmerkungen.</string>
+    <string name="send_suggestion_report_placeholder">Beschreibe hier deine Anmerkung</string>
     <string name="settings_labs_show_hidden_events_in_timeline">Versteckte Ereignisse in der Zeitleiste anzeigen</string>
 
     <string name="bottom_action_people_x">Direkte Nachrichten</string>
@@ -1610,22 +1606,22 @@ Wenn du diese neue Wiederherstellungsmethode nicht eingerichtet hast, kann ein A
     <string name="no_message_edits_found">Keine Änderungen gefunden</string>
 
     <string name="room_filtering_filter_hint">Gespräche filtern…</string>
-    <string name="room_filtering_footer_create_new_direct_message">Senden Sie eine neue Direktnachricht</string>
+    <string name="room_filtering_footer_create_new_direct_message">Sende eine neue Direktnachricht</string>
     <string name="room_filtering_footer_open_room_directory">Das Raumverzeichnis anzeigen</string>
 
     <string name="link_copied_to_clipboard">Link in die Zwischenablage kopiert</string>
 
-    <string name="add_by_matrix_id">Nach Matrix-ID hinzufügen</string>
+    <string name="add_by_matrix_id">Mit Matrix-ID hinzufügen</string>
     <string name="creating_direct_room">Raum erstellen…</string>
     <string name="message_view_edit_history">Bearbeitungsverlauf anzeigen</string>
 
     <string name="sas_cancelled_by_other">Die andere Partei hat die Überprüfung abgebrochen.
 \n%s</string>
-    <string name="sas_error_m_unknown_method">Das Gerät kann sich nicht auf eine Schlüsselvereinbarung, eine Hash-, eine MAC- oder eine SAS-Methode einigen</string>
-    <string name="alpha_disclaimer_content_line_2_gplay">Die neueste Featureliste befindet sich immer in %1$s. Wenn Sie Fehler finden, senden Sie uns bitte einen Bericht im Menü oben links von \"Startseite\". Wir werden den Fehler so schnell wie möglich beheben.</string>
-    <string name="alpha_disclaimer_content_line_2_fdroid">Wenn Sie Fehler finden, senden Sie uns bitte einen Bericht im Menü oben links von \"Startseite\". Wir werden diese so schnell wie möglich beheben.</string>
+    <string name="sas_error_m_unknown_method">Die Sitzung kann sich nicht auf eine Schlüsselvereinbarung, eine Hash-, eine MAC- oder eine SAS-Methode einigen</string>
+    <string name="alpha_disclaimer_content_line_2_gplay">Die neueste Feature-Liste befindet sich immer in %1$s. Wenn du Fehler findest, sende uns bitte einen Bericht im Menü oben links von \"Startseite\". Wir werden den Fehler so schnell wie möglich beheben.</string>
+    <string name="alpha_disclaimer_content_line_2_fdroid">Wenn du Fehler findest, sende uns bitte einen Bericht im Menü oben links von der \"Startseite\". Wir werden diese so schnell wie möglich beheben.</string>
 
-    <string name="import_e2e_keys_from_file">Importieren Sie e2e-Schlüssel aus der Datei \"%1$s\".</string>
+    <string name="import_e2e_keys_from_file">E2E-Schlüssel aus der Datei \"%1$s\" importieren.</string>
 
     <string name="send_suggestion_sent">Vielen Dank, der Vorschlag wurde erfolgreich gesendet</string>
     <string name="send_suggestion_failed">Der Vorschlag konnte nicht gesendet werden (%s)</string>
@@ -1642,14 +1638,14 @@ Wenn du diese neue Wiederherstellungsmethode nicht eingerichtet hast, kann ein A
     <string name="riotx_no_registration_notice_colored_part">Benutze die alte App</string>
 
 
-    <string name="room_filtering_footer_title">Können Sie nicht finden, wonach Sie suchen\?</string>
+    <string name="room_filtering_footer_title">Kannst du nicht finden, wonach du suchst\?</string>
     <string name="room_filtering_footer_create_new_room">Erstelle einen neuen Raum</string>
     <string name="room_directory_search_hint">Name oder ID (#beispiel:matrix.org)</string>
 
-    <string name="labs_swipe_to_reply_in_timeline">Aktivieren Sie das Streichen, um in der Zeitleiste zu antworten</string>
+    <string name="labs_swipe_to_reply_in_timeline">Aktiviere Wischen, um in der Zeitleiste zu antworten</string>
 
-    <string name="direct_room_no_known_users">Kein Ergebnis gefunden. Verwenden Sie Nach Matrix-ID hinzufügen, um auf dem Server zu suchen.</string>
-    <string name="direct_room_start_search">Beginnen Sie mit der Eingabe, um Ergebnisse zu erhalten</string>
+    <string name="direct_room_no_known_users">Kein Ergebnis gefunden. Verwende \'Mit Matrix-ID hinzufügen\', um auf dem Server zu suchen.</string>
+    <string name="direct_room_start_search">Beginne mit der Eingabe, um Ergebnisse zu erhalten</string>
     <string name="direct_room_filter_hint">Filtern nach Benutzername oder ID…</string>
 
     <string name="joining_room">Raum betreten…</string>
@@ -1664,13 +1660,13 @@ Wenn du diese neue Wiederherstellungsmethode nicht eingerichtet hast, kann ein A
     <string name="people_no_identity_server">Kein Integrationsserver konfiguriert.</string>
 
     <string name="call_failed_no_ice_title">Anruf aufgrund eines falsch konfigurierten Servers fehlgeschlagen</string>
-    <string name="call_failed_no_ice_use_alt">Versuchen Sie es mit %s</string>
+    <string name="call_failed_no_ice_use_alt">Versuche es mit %s</string>
     <string name="call_failed_dont_ask_again">Nicht erneut fragen</string>
 
-    <string name="auth_add_email_message_2">Richten Sie eine E-Mail für die Kontowiederherstellung ein, die später von Personen, die Sie kennen, optional gefunden werden kann.</string>
-    <string name="auth_add_phone_message_2">Richten Sie ein Telefon ein und lassen Sie es später optional von Personen erkennen, die Sie kennen.</string>
-    <string name="auth_add_email_phone_message_2">Legen Sie eine E-Mail für die Kontowiederherstellung fest. Verwenden Sie eine spätere E-Mail oder ein späteres Telefon, um von Personen, die Sie kennen, optional gefunden zu werden.</string>
-    <string name="auth_add_email_and_phone_message_2">Legen Sie eine E-Mail für die Kontowiederherstellung fest. Verwenden Sie eine spätere E-Mail oder ein späteres Telefon, um von Personen, die Sie kennen, optional gefunden zu werden.</string>
+    <string name="auth_add_email_message_2">Richte eine E-Mail für die Kontowiederherstellung ein. Optional, kannst du später einrichten, dass Personen dich über diese Adresse finden.</string>
+    <string name="auth_add_phone_message_2">Richte eine Telefonnummer ein. Später kannst du einrichten, dass Personen dich über diese finden.</string>
+    <string name="auth_add_email_phone_message_2">Lege eine E-Mail-Adresse für die Kontowiederherstellung fest. Später kann optional eine E-Mail-Adresse oder eine Telefonnummer dazu verwendet werden, um von anderen Personen gefunden zu werden.</string>
+    <string name="auth_add_email_and_phone_message_2">Lege eine E-Mail-Adresse für die Kontowiederherstellung fest. Später kann optional eine E-Mail-Adresse oder eine Telefonnummer dazu verwendet werden, um von anderen Personen gefunden zu werden.</string>
     <string name="settings_call_ringtone_use_default_stun">Fallback-Call-Assist-Server zulassen</string>
     <string name="settings_background_fdroid_sync_mode_battery">Optimiert für die Batterie</string>
     <string name="settings_background_fdroid_sync_mode_real_time">Optimiert für die Echtzeit</string>
@@ -1680,14 +1676,14 @@ Wenn du diese neue Wiederherstellungsmethode nicht eingerichtet hast, kann ein A
 
     <string name="settings_set_workmanager_delay">Bevorzugtes Synchronisationsintervall</string>
     <string name="settings_discovery_category">Fund</string>
-    <string name="encryption_information_device_name_with_warning">Öffentlicher Name (sichtbar für Personen, mit denen Sie kommunizieren)</string>
-    <string name="device_name_warning">Der öffentliche Name eines Geräts ist für Personen sichtbar, mit denen Sie kommunizieren</string>
-    <string name="widget_integration_review_terms">Um fortzufahren, müssen Sie die Bedingungen dieses Dienstes akzeptieren.</string>
+    <string name="encryption_information_device_name_with_warning">Öffentlicher Name (sichtbar für Personen, mit denen du kommunizierst)</string>
+    <string name="device_name_warning">Der öffentliche Name der Sitzung ist für Personen sichtbar, mit denen du kommunizierst</string>
+    <string name="widget_integration_review_terms">Um fortzufahren, musst du die Nutzungsbedingungen akzeptieren.</string>
 
-    <string name="identity_server_not_defined">Sie verwenden keinen Identity Server</string>
-    <string name="identity_server_not_defined_for_password_reset">Es ist kein Identitätsserver konfiguriert. Sie müssen Ihr Kennwort zurücksetzen.</string>
+    <string name="identity_server_not_defined">Du verwendest keinen Identitätsserver</string>
+    <string name="identity_server_not_defined_for_password_reset">Es ist kein Identitätsserver konfiguriert. Du musst dein Kennwort zurücksetzen.</string>
 
-    <string name="error_user_already_logged_in">Sie versuchen anscheinend, eine Verbindung zu einem anderen Homeserver herzustellen. Möchten Sie sich abmelden\?</string>
+    <string name="error_user_already_logged_in">Du versuchst anscheinend, eine Verbindung zu einem anderen Heimserver herzustellen. Möchtest du dich abmelden\?</string>
 
     <string name="push_gateway_item_push_key">Push-Key:</string>
     <string name="push_gateway_item_app_display_name">App-Anzeigename:</string>
@@ -1695,26 +1691,26 @@ Wenn du diese neue Wiederherstellungsmethode nicht eingerichtet hast, kann ein A
     <string name="terms_of_service">Nutzungsbedingungen</string>
     <string name="review_terms">Nutzungsbedingungen überprüfen</string>
     <string name="terms_description_for_identity_server">Für andere auffindbar sein</string>
-    <string name="terms_description_for_integration_manager">Verwenden Sie Bots, Bridges, Widgets und Sticker-Packs</string>
+    <string name="terms_description_for_integration_manager">Verwende Bots, Bridges, Widgets und Sticker-Pakete</string>
 
     <string name="read_at">Gelesen von</string>
 
 
     <string name="identity_server">Identitätsserver</string>
-    <string name="disconnect_identity_server">Trennen Sie den Identitätsserver</string>
-    <string name="add_identity_server">Konfigurieren Sie den Identitätsserver</string>
+    <string name="disconnect_identity_server">Verbindung zum Identitätsserver trennen</string>
+    <string name="add_identity_server">Identitätsserver konfigurieren</string>
     <string name="change_identity_server">Identitätsserver ändern</string>
     <string name="settings_discovery_emails_title">Erkennbare E-Mail-Adressen</string>
-    <string name="settings_discovery_no_mails">Erkennungsoptionen werden angezeigt, sobald Sie eine E-Mail hinzugefügt haben.</string>
+    <string name="settings_discovery_no_mails">Erkennungsoptionen werden angezeigt, sobald du eine E-Mail hinzugefügt hast.</string>
     <string name="settings_discovery_mail_pending">ausstehend</string>
 
     <string name="settings_discovery_enter_identity_server">Gib einen neuen Identitätsserver ein</string>
     <string name="settings_discovery_bad_identity_server">Konnte keine Verbindung zum Heimserver herstellen</string>
     <string name="resources_script">Latn</string>
 
-    <string name="call_failed_no_ice_description">Bitte frage den Administrator deines Home-Servers (%1$s) um einen TURN server einzurichten, damit Anrufe zuverlässig funktionieren.
-\n
-\nAlternativ kannst du einen öffentlichen Server auf %2$s nutzen doch wird das nicht zu zuverlässig sein und es wird deine IP-Adresse mit dem Server teilen. Du kannst dies auch in den Einstellungen konfigurieren.</string>
+    <string name="call_failed_no_ice_description">Bitte frage die Administration deines Heimservers (%1$s) um einen TURN-Server einzurichten, damit Anrufe zuverlässig funktionieren. 
+\n 
+\nAlternativ kannst du einen öffentlichen Server auf %2$s nutzen, doch wird das nicht zu zuverlässig sein und es wird deine IP-Adresse mit dem Server geteilt. Du kannst dies auch in den Einstellungen konfigurieren.</string>
     <string name="login_error_no_homeserver_found">Dies ist keine Adresse eines Matrixservers</string>
     <string name="login_error_homeserver_not_found">Kann Home-Server nicht bei dieser URL erreichen. Bitte überprüfen</string>
     <string name="settings_call_ringtone_use_default_stun_sum">Wir nutzen %s als Assistenten wenn dein Home-Server keinen anbietet (Deine IP-Adresse wird während des Anrufs geteilt)</string>
@@ -1725,14 +1721,14 @@ Wenn du diese neue Wiederherstellungsmethode nicht eingerichtet hast, kann ein A
 
 
     <string name="settings_background_fdroid_sync_mode">Hintergrundsynchronisierungsmodus (experimentell)</string>
-    <string name="settings_background_fdroid_sync_mode_battery_description">Riot wird sich im Hintergrund auf eine Art synchronisieren die die Ressourcen des Geräts schont (Akku).
+    <string name="settings_background_fdroid_sync_mode_battery_description">Riot wird sich im Hintergrund auf eine Art synchronisieren die Ressourcen des Geräts schont (Akku). 
 \nAbhängig von dem Ressourcen-Statuses deines Geräts kann dein System die Synchronisierung verschieben.</string>
-    <string name="settings_background_fdroid_sync_mode_real_time_description">Riot wird sich im Hintergrund periodisch zu einem bestimmten Zeitpunkt synchronisieren (konfigurierbar).
-\nDies wird Funk- und Akkunutzung beeinflussen. Es wird wird eine permanente Benachrichtigung geben, die sagt, dass Riot auf Ereignisse lauscht.</string>
+    <string name="settings_background_fdroid_sync_mode_real_time_description">Riot wird sich im Hintergrund periodisch zu einem bestimmten Zeitpunkt synchronisieren (konfigurierbar). 
+\nDies wird Funk- und Akkunutzung beeinflussen. Es wird eine permanente Benachrichtigung geben, die sagt, dass Riot auf Ereignisse lauscht.</string>
     <string name="settings_set_workmanager_delay_summary">%s
 \nDie Synchronisierung kann aufgrund deiner Ressourcen (Akku) oder Gerätezustands (schlafend) verschoben werden.</string>
     <string name="settings_integrations">Integrationen</string>
-    <string name="settings_integrations_summary">Benutze einen Integrations-Manager um Bots, Brpcken, Widgets und Sticker-Pakete zu verwalten.
+    <string name="settings_integrations_summary">Benutze einen Integrations-Manager um Bots, Brücken, Widgets und Sticker-Pakete zu verwalten. 
 \nIntegrations-Manager erhalten Konfigurationsdaten und können Widgets verändern, Raum-Einladungen senden und in deinem Namen Berechtigungslevel setzen.</string>
     <string name="settings_integration_allow">Erlaube Integrationen</string>
     <string name="room_widget_activity_title">Widget</string>
@@ -1757,7 +1753,7 @@ Wenn du diese neue Wiederherstellungsmethode nicht eingerichtet hast, kann ein A
     <string name="room_widget_webview_access_microphone">Mikrofon benutzen</string>
     <string name="room_widget_webview_read_protected_media">Lese DRM-geschützte Medien</string>
 
-    <string name="security_warning_identity_server">Frühere Versionen von Riot hatten einen Sicherheitsproblem, welches dem Identitätsserver (%1$s) Zugriff auf deinen Account geben konnte. Wenn du %2$s vertraust, kannst du dies ignorieren – ansonsten logge dich bitte aus und wieder ein.
+    <string name="security_warning_identity_server">Frühere Versionen von Riot hatten ein Sicherheitsproblem, welches dem Identitätsserver (%1$s) Zugriff auf deinen Account geben konnte. Wenn du %2$s vertraust, kannst du dies ignorieren – ansonsten logge dich bitte aus und wieder ein.
 \n
 \nWeitere Details gibt es hier (Englisch):
 \nhttps://medium.com/@RiotChat/36b4792ea0d6</string>
@@ -1766,7 +1762,7 @@ Wenn du diese neue Wiederherstellungsmethode nicht eingerichtet hast, kann ein A
     <string name="settings_discovery_manage">Verwalte deine Erkennungseinstellungen.</string>
     <string name="room_widget_revoke_access">Zugriff für mich zurückziehen</string>
 
-    <string name="push_gateway_item_device_name">Gerätename:</string>
+    <string name="push_gateway_item_device_name">Sitzungsname:</string>
     <string name="push_gateway_item_format">Format:</string>
 
     <string name="store_riotx_full_description">RiotX ist ein neuer Client für das Matrix-Protokoll (matrix.org): Ein offenes Netzwerk für sichere, dezentrale Kommunikation.
@@ -1778,19 +1774,19 @@ Wenn du diese neue Wiederherstellungsmethode nicht eingerichtet hast, kann ein A
 \n
 \nNicht alle Features in Riot sind bisher in RiotX implementiert. Hauptfunktionen, die noch fehlen (und bald kommen!): • Raum-Einstellungen (Raum-Mitglieder auflisten, etc.) • Anrufe • Widgets • …</string>
 
-    <string name="settings_discovery_identity_server_info">Du nutzt aktuell %1$s um zu entdecken und von dir bekannten Kontakten entdeckt zu werden.</string>
+    <string name="settings_discovery_identity_server_info">Du nutzt aktuell %1$s um vorhandene Kontakte zu finden und um von dir bekannten Kontakten gefunden zu werden.</string>
     <string name="settings_discovery_identity_server_info_none">Du benutzt aktuell keinen Identitätsserver. Um zu entdecken und um von dir bekannten Kontakten entdeckt zu werden, richte unten einen ein.</string>
     <string name="settings_discovery_msisdn_title">Entdeckbare Telefonnummern</string>
     <string name="settings_discovery_please_enter_server">Bitte gebe Adresse des Identitätsserver ein</string>
     <string name="settings_discovery_no_terms_title">Identitätsserver hat keine Nutzungsbedingungen</string>
-    <string name="settings_discovery_no_terms">Der Identitätsserver den du ausgewählt hast, hat keine Nutzungsbedingungen. Fahre nur fort, wenn du dem Besitzer des Dienstes vertraust</string>
+    <string name="settings_discovery_no_terms">Der Identitätsserver den du ausgewählt hast, hat keine Nutzungsbedingungen. Fahre nur fort, wenn du dem/r Besitzer!n des Dienstes vertraust</string>
     <string name="settings_text_message_sent">Eine Textnachricht wurde an %s gesendet. Bitte gebe den Verifizierungscode ein, den sie enthält.</string>
 
     <string name="labs_allow_extended_logging">Aktiviere ausführliche Logs.</string>
-    <string name="labs_allow_extended_logging_summary">Gesprächige Logs wird den Entwicklern helfen indem sie mehr Informationen enthalten, wenn du einen Fehlerbericht sendest. Auch wenn dies aktiviert ist, werden keine Nachrichteninhalte oder andere privaten Daten aufgezeichnet.</string>
+    <string name="labs_allow_extended_logging_summary">Ausführliche Logs werden den Entwicklern helfen, indem sie mehr Informationen enthalten, wenn du einen Fehlerbericht sendest. Auch wenn dies aktiviert ist, werden keine Nachrichteninhalte oder andere privaten Daten aufgezeichnet.</string>
 
 
-    <string name="error_terms_not_accepted">Bitte erneut versuchen, nachdem du die Nutzungsbedingungendeines Home-Servers akzeptiert hast.</string>
+    <string name="error_terms_not_accepted">Bitte erneut versuchen, nachdem du die Nutzungsbedingungen deines Home-Servers akzeptiert hast.</string>
 
     <string name="room_widget_permission_webview_shared_info_title">Bei Benutzung könnten Cookies gesetzt werden und es könnten Daten mit %s geteilt werden:</string>
     <string name="room_widget_permission_shared_info_title">Bei Benutzung könnten Daten mit %s geteilt werden:</string>
@@ -1825,7 +1821,7 @@ Wenn du diese neue Wiederherstellungsmethode nicht eingerichtet hast, kann ein A
     <string name="attachment_type_contact">Kontakt</string>
     <string name="attachment_type_camera">Kamera</string>
     <string name="attachment_type_audio">Audio</string>
-    <string name="attachment_type_gallery">Gallerie</string>
+    <string name="attachment_type_gallery">Galerie</string>
     <string name="attachment_type_sticker">Sticker</string>
     <string name="report_content_spam">Es ist Spam</string>
     <string name="report_content_inappropriate">Es ist unangebracht</string>
@@ -1886,8 +1882,8 @@ Wenn du diese neue Wiederherstellungsmethode nicht eingerichtet hast, kann ein A
 
     <string name="login_continue">Fortfahren</string>
     <string name="settings_discovery_disconnect_identity_server_info">Eine Trennung von deinem Identitätsserver würde bedeuten, dass du weder von anderen Nutzern gefunden werden, noch diese per E-Mail oder Telefonnummer einladen kannst.</string>
-    <string name="settings_discovery_disconnect_with_bound_pid">Derzeitig teilst du deine E-Mail-Adresse oder Telefonnummer über den Identitätsserver %1$s. Du müsstest dich erneut zu %2$s verbinden um dies zu unterbinden.</string>
-    <string name="settings_agree_to_terms">Stimme den Nutzungsbedingungen des Identitätsservers (%s) zu, um zu erlauben per E-Mail oder Telefonnummer gefunden werden zu können.</string>
+    <string name="settings_discovery_disconnect_with_bound_pid">Du teilst deine Email Adressen oder Telefonnummern momentan auf dem Identitätsserver %1$s. Du wirst dich erneut mit %2$s verbinden müssen, um mit dem Teilen aufzuhören.</string>
+    <string name="settings_agree_to_terms">Stimme den Nutzungsbedingungen des Identitätsservers (%s) zu, um zu erlauben per E-Mail oder Telefonnummer gefunden zu werden.</string>
 
     <string name="two_and_some_others_read">gelesen von %1$s, %2$s und %3$d anderen</string>
     <string name="error_handling_incoming_share">Zu teilende Daten nicht verarbeitbar</string>
@@ -1916,7 +1912,7 @@ Wenn du diese neue Wiederherstellungsmethode nicht eingerichtet hast, kann ein A
     <string name="login_reset_password_password_hint">Neues Passwort</string>
 
     <string name="login_reset_password_warning_title">Achtung!</string>
-    <string name="login_reset_password_warning_content">Eine Änderung deines Passworts wird alle Ende-zu-Ende-Verschlüsselungsschlüssel zurücksetzen. Dein verschlüsselter Chatverlauf wird dadurch unlesbar. Richte eine Schlüsselsicherung ein oder exportiere deine Raumschlüssel von einem anderen Gerät bevor du dein Passwort zurücksetzt.</string>
+    <string name="login_reset_password_warning_content">Eine Änderung deines Passworts wird alle Ende-zu-Ende-Verschlüsselungsschlüssel zurücksetzen. Dein verschlüsselter Chatverlauf wird dadurch unlesbar. Richte eine Schlüsselsicherung ein oder exportiere deine Raumschlüssel von einer anderen Sitzung bevor du dein Passwort zurücksetzt.</string>
     <string name="login_reset_password_warning_submit">Fortfahren</string>
 
     <string name="login_reset_password_error_not_found">Diese E-Mail-Adresse ist mit keinem Benutzerkonto verknüpft</string>
@@ -1959,4 +1955,403 @@ Wenn du diese neue Wiederherstellungsmethode nicht eingerichtet hast, kann ein A
     <string name="login_wait_for_email_notice">Wir haben dir eine E-Mail an %1$s gesendet.
 \nBitte öffne den darin enthaltenen Link, um mit der Benutzerkontoerstellung fortzufahren.</string>
     <string name="login_validation_code_is_not_correct">Der eingegebene Code ist nicht korrekt. Bitte überprüfe deine Eingabe.</string>
+    <string name="reaction_search_type_hint">Beginne zu Tippen um eine Reaktion zu finden.</string>
+
+    <string name="room_join_rules_invite">%1$s hat den Raum auf \"nur-einladen\" gestellt.</string>
+    <string name="login_splash_title">Befreie deine Kommunikation</string>
+    <string name="login_server_url_form_modular_text">Premium-Hosting für Organisationen</string>
+    <string name="login_server_url_form_modular_notice">Gib die Adresse des Modular Riot oder Servers ein, den du verwenden möchtest</string>
+    <string name="login_server_url_form_other_notice">Gibt die Adresse eines Servers oder eines Riot ein, zu dem du dich verbinden möchtest</string>
+
+    <string name="login_mode_not_supported">Die Anwendung kann sich nicht bei diesem Heimserver anmelden. Der Heimserver unterstützt die folgenden Anmeldetypen:%1$s.
+\n
+\nMöchtest du dich mit einem Webclient anmelden\?</string>
+    <string name="login_reset_password_notice">Eine Bestätigungs-E-Mail wird an dich gesendet, um dein neues Passwort zu bestätigen.</string>
+    <string name="login_reset_password_submit">Weiter</string>
+    <string name="login_reset_password_success_notice_2">Du wurdest von allen Sitzungen abgemeldet und erhälst keine Push-Benachrichtigungen mehr. Um Benachrichtigungen wieder zu aktivieren, melde dich auf jedem Gerät erneut an.</string>
+    <string name="login_reset_password_cancel_confirmation_title">Warnung</string>
+    <string name="login_set_email_notice">Lege eine E-Mail-Adresse fest, um dein Konto wiederherzustellen. Später kannst du optional zulassen, dass Personen dich anhand dieser E-Mail-Adresse entdecken.</string>
+    <string name="login_set_email_submit">Weiter</string>
+
+    <string name="login_set_msisdn_title">Lege Telefonnummer fest</string>
+    <string name="login_set_msisdn_notice">Lege eine Telefonnummer fest, damit Personen dich anhand dieser entdecken können.</string>
+    <string name="login_set_msisdn_notice2">Bitte verwende das internationale Format.</string>
+    <string name="login_set_msisdn_submit">Weiter</string>
+
+    <string name="login_msisdn_confirm_submit">Weiter</string>
+
+    <string name="login_msisdn_error_not_international">Internationale Telefonnummern müssen mit \'+\' beginnen</string>
+    <string name="login_msisdn_error_other">Die Telefonnummer scheint ungültig zu sein. Bitte prüfen</string>
+
+    <string name="login_signup_to">Anmelden bei %1$s</string>
+    <string name="login_signup_username_hint">Benutzername</string>
+    <string name="login_signup_submit">Weiter</string>
+    <string name="login_signup_cancel_confirmation_title">Warnung</string>
+    <string name="login_a11y_captcha_container">Bitte löse das Captcha</string>
+    <string name="login_error_outdated_homeserver_title">Veralteter Heimserver</string>
+    <string name="login_error_outdated_homeserver_content">Auf diesem Heimserver läuft eine zu alte Version, um eine Verbindung herzustellen. Bitten die Heimserver-Administration um ein Upgrade.</string>
+
+    <plurals name="login_error_limit_exceeded_retry_after">
+        <item quantity="one">Es wurden zu viele Anfragen gesendet. Versuche es erneut in %1$d Sekunde…</item>
+        <item quantity="other">Es wurden zu viele Anfragen gesendet. Versuche es erneut in %1$d Sekunden…</item>
+    </plurals>
+
+    <string name="seen_by">Gesehen von</string>
+
+    <string name="signed_out_title">Du bist abgemeldet</string>
+    <string name="signed_out_notice">Dies kann verschiedene Gründe haben:
+\n
+\n• Du hast dein Passwort in einer anderen Sitzung geändert.
+\n
+\n• Du hast diese Sitzung aus einer anderen Sitzung heraus gelöscht.
+\n
+\n• Die Administration deines Servers hat deinen Zugriff aus Sicherheitsgründen ungültig gemacht.</string>
+    <string name="signed_out_submit">Melde dich erneut an</string>
+
+    <string name="soft_logout_title">Du bist abgemeldet</string>
+    <string name="soft_logout_signin_title">Anmelden</string>
+    <string name="soft_logout_signin_notice">Deine Heimserver-Administration (%1$s) hat dich von deinem Konto %2$s (%3$s) abgemeldet.</string>
+    <string name="soft_logout_signin_e2e_warning_notice">Melden dich an, um ausschließlich auf diesem Gerät gespeicherte Verschlüsselungsschlüssel wiederherzustellen. Du benötigst sie, um deine verschlüsselten Nachrichten auf jedem Gerät zu lesen.</string>
+    <string name="soft_logout_signin_submit">Anmelden</string>
+    <string name="soft_logout_signin_password_hint">Passwort</string>
+    <string name="soft_logout_clear_data_title">Persönliche Daten löschen</string>
+    <string name="soft_logout_clear_data_notice">Warnung: Persönliche Daten (einschließlich Verschlüsselungsschlüssel) werden weiterhin auf diesem Gerät gespeichert.
+\n
+\nDeaktiviere diese Option, wenn dieses Gerät nicht mehr verwenden wird oder sich bei einem anderen Konto angemeldet werden soll.</string>
+    <string name="soft_logout_clear_data_submit">Alle Daten löschen</string>
+
+    <string name="soft_logout_clear_data_dialog_title">Daten löschen</string>
+    <string name="soft_logout_clear_data_dialog_content">Alle aktuell auf diesem Gerät gespeicherten Daten löschen\?
+\nMelde dich erneut an, um auf deine Kontodaten und Nachrichten zuzugreifen.</string>
+    <string name="soft_logout_clear_data_dialog_e2e_warning_content">Du verlierst den Zugriff auf verschlüsselte Nachrichten, außer, du meldest dich an, um den Verschlüsselungsschlüssel wiederherzustellen.</string>
+    <string name="soft_logout_clear_data_dialog_submit">Daten löschen</string>
+    <string name="soft_logout_sso_not_same_user_error">Die aktuelle Sitzung gehört dem/der Benutzer!n%1$s. Die angegebenen Anmeldeinformationen sind von Benutzer!n %2$s. Dies wird nicht von RiotX unterstützt.
+\nBitte zuerst die Daten löschen und dann erneut anmelden.</string>
+
+    <string name="permalink_malformed">matrix.to-Link fehlerhaft</string>
+    <string name="bug_report_error_too_short">Die Beschreibung ist zu kurz</string>
+
+    <string name="notification_initial_sync">Initiale Synchronisierung…</string>
+
+    <string name="settings_show_devices_list">Alle meine Sitzungen anzeigen</string>
+    <string name="settings_advanced_settings">Erweiterte Einstellungen</string>
+    <string name="settings_developer_mode">Entwicklungsmodus</string>
+    <string name="settings_developer_mode_summary">Der Entwicklungsmodus aktiviert versteckte Funktionen und kann die Anwendung weniger stabil machen. Nur für Entwickler!nnen!</string>
+    <string name="settings_rageshake">Wutschütteln</string>
+    <string name="settings_rageshake_detection_threshold">Erkennungsschwelle</string>
+    <string name="settings_rageshake_detection_threshold_summary">Schüttel dein Telefon, um die Erkennungsschwelle zu testen</string>
+    <string name="rageshake_detected">Schütteln erkannt!</string>
+    <string name="settings">Einstellungen</string>
+    <string name="devices_current_device">Aktuelle Sitzung</string>
+    <string name="devices_other_devices">Andere Sitzungen</string>
+
+    <string name="autocomplete_limited_results">Zeigt nur die ersten Ergebnisse, gib mehr Buchstaben ein…</string>
+
+    <string name="settings_developer_mode_fail_fast_title">Ausfallsicher</string>
+    <string name="settings_developer_mode_fail_fast_summary">RiotX kann häufiger abstürzen, wenn ein unerwarteter Fehler auftritt</string>
+
+    <string name="command_description_verify">Überprüfe die angegebenen Benutzer-ID</string>
+    <string name="command_description_shrug">Stellt einer Klartextnachricht ¯\\_(ツ)_/¯ voran</string>
+
+    <string name="create_room_encryption_title">Aktiviere Verschlüsselung</string>
+    <string name="create_room_encryption_description">Nach der Aktivierung kann die Verschlüsselung nicht deaktiviert werden.</string>
+
+    <string name="login_error_threepid_denied">Deine E-Mail-Domain ist nicht berechtigt, sich auf diesem Server zu registrieren</string>
+
+    <string name="verification_conclusion_warning">Nicht vertrauenswürdige Anmeldung</string>
+    <string name="verification_sas_match">Sie passen</string>
+    <string name="verification_sas_do_not_match">Sie passen nicht</string>
+    <string name="verify_user_sas_emoji_help_text">Verifiziere diese/n Benutzer!n, indem du bestätigst, dass diese einzigartigen Emoji in der selben Reihenfolge auf dem Bildschirm deines Gegenübers angezeigt werden.</string>
+    <string name="verify_user_sas_emoji_security_tip">Für ultimative Sicherheit verwende ein anderes vertrauenswürdiges Kommunikationsmittel oder mache es persönlich.</string>
+    <string name="verification_green_shield">Suche nach dem grünen Schild, um sicherzustellen, dass ein/e Benutzer!n vertrauenswürdig ist. Vertraue allen Benutzer!nnen in einem Raum, um sicherzustellen, dass der Raum sicher ist.</string>
+
+    <string name="verification_conclusion_not_secure">Nicht sicher</string>
+    <string name="verification_conclusion_compromised">Eine der folgenden Möglichkeiten kann beeinträchtigt sein:
+\n
+\n - Dein Heimserver
+\n - Der Heimserver mit dem dein Gegenüber verbunden ist
+\n - Deine oder die Internetverbindung des Gegenüber
+\n - Dein Gerät oder das Gerät des Gegenüber</string>
+
+    <string name="sent_a_video">Video.</string>
+    <string name="sent_an_image">Bild.</string>
+    <string name="sent_an_audio_file">Audio</string>
+    <string name="sent_a_file">Datei</string>
+
+    <string name="verification_request_waiting">Warten…</string>
+    <string name="verification_request_other_cancelled">%s brach ab</string>
+    <string name="verification_request_you_cancelled">Du hast abgebrochen</string>
+    <string name="verification_request_other_accepted">%s hat akzeptiert</string>
+    <string name="verification_request_you_accepted">Du hast akzeptiert</string>
+    <string name="verification_sent">Verifizierung gesendet</string>
+    <string name="verification_request">Verifizierung angefragt</string>
+
+
+    <string name="verification_verify_device">Verifiziere diese Sitzung</string>
+    <string name="verification_verify_device_manually">Manuelle Verifizierung</string>
+
+    <string name="you">Ich</string>
+
+    <string name="verification_scan_notice">Scanne den Code mit dem Gerät des Gegenüber, um sich gegenseitig zu überprüfen</string>
+    <string name="verification_scan_their_code">Scanne ihren/seinen Code</string>
+    <string name="verification_scan_emoji_title">Kann nicht scannen</string>
+    <string name="verification_scan_emoji_subtitle">Wenn ihr nicht am selben Ort seid, vergleicht Emoji stattdessen</string>
+
+    <string name="verification_no_scan_emoji_title">Verifizieren via Emoji-Vergleich</string>
+
+    <string name="verify_by_emoji_title">Mit Emoji verifizieren</string>
+    <string name="verify_by_emoji_description">Wenn du den obigen Code nicht scannen kannst, verifiziert, indem ihr eine kurze, eindeutige Auswahl an Emoji vergleicht.</string>
+
+    <string name="a13n_qr_code_description">QR-Code-Bild</string>
+
+    <string name="verification_verify_user">%s verifizieren</string>
+    <string name="verification_verified_user">%s verifiziert</string>
+    <string name="verification_request_waiting_for">Warte auf %s…</string>
+    <string name="verification_request_alert_description">Für zusätzliche Sicherheit überprüfe %s, indem ihr auf beiden Geräten einen einzigartigen Code überprüft.
+\n
+\nFür maximale Sicherheit macht dies persönlich.</string>
+    <string name="room_profile_not_encrypted_subtitle">Nachrichten in diesem Raum sind nicht Ende-zu-Ende verschlüsselt.</string>
+    <string name="room_profile_encrypted_subtitle">Nachrichten in diesem Raum sind Ende-zu-Ende verschlüsselt.
+\n
+\nDeine Nachrichten sind gesichert und nur du und dein Gegenüber haben die eindeutigen Schlüssel, um sie zu entsperren.</string>
+    <string name="room_profile_section_security">Sicherheit</string>
+    <string name="room_profile_section_security_learn_more">Mehr erfahren</string>
+    <string name="room_profile_section_more">Mehr</string>
+    <string name="room_profile_section_more_settings">Raum Einstellungen</string>
+    <string name="room_profile_section_more_notifications">Benachrichtigungen</string>
+    <plurals name="room_profile_section_more_member_list">
+        <item quantity="one">Eine Person</item>
+        <item quantity="other">%1$d Personen</item>
+    </plurals>
+    <string name="room_profile_section_more_uploads">Uploads</string>
+    <string name="room_profile_section_more_leave">Raum verlassen</string>
+    <string name="room_profile_leaving_room">Verlasse den Raum…</string>
+
+    <string name="room_member_power_level_admins">Admins</string>
+    <string name="room_member_power_level_moderators">Moderierende</string>
+    <string name="room_member_power_level_custom">benutzerdefiniert</string>
+    <string name="room_member_power_level_invites">Eingeladen</string>
+    <string name="room_member_power_level_users">Nutzer!n</string>
+
+    <string name="room_member_power_level_admin_in">Admin in %1$s</string>
+    <string name="room_member_power_level_moderator_in">Moderation in %1$s</string>
+    <string name="room_member_jump_to_read_receipt">Springen &amp; als gelesen markieren</string>
+
+    <string name="rendering_event_error_type_of_event_not_handled">RiotX kann keine Ereignisse vom Typ \'%1$s\'</string>
+    <string name="rendering_event_error_type_of_message_not_handled">RiotX beherrscht keine Nachrichten vom Typ \'%1$s\'</string>
+    <string name="rendering_event_error_exception">RiotX ist beim verarbeiten des Ereignisinhalts mit der ID \'%1$s\' auf ein Problem gestoßen</string>
+
+    <string name="unignore">Nicht ignorieren</string>
+
+    <string name="verify_cannot_cross_sign">Diese Sitzung kann diese Verifizierung nicht mit deinen anderen Sitzungen teilen.
+\nDie Überprüfung wird lokal gespeichert und in einer zukünftigen Version der App freigegeben.</string>
+
+    <string name="room_list_sharing_header_recent_rooms">Neueste Räume</string>
+    <string name="room_list_sharing_header_other_rooms">Andere Räume</string>
+
+    <string name="command_description_rainbow">Sendet die angegebene Nachricht in Regenbogenfarben</string>
+    <string name="command_description_rainbow_emote">Sendet das angegebene Emote in Regenbogenfarben</string>
+
+    <string name="settings_category_timeline">Zeitleiste</string>
+
+    <string name="settings_category_composer">Nachrichteneditor</string>
+
+    <string name="room_settings_enable_encryption">Aktivieren Ende-zu-Ende-Verschlüsselung</string>
+    <string name="room_settings_enable_encryption_warning">Einmal aktiviert kann die Verschlüsselung nicht rückgängig gemacht werden.</string>
+
+    <string name="room_settings_enable_encryption_dialog_title">Verschlüsselung aktivieren\?</string>
+    <string name="room_settings_enable_encryption_dialog_content">Nach der Aktivierung kann die Verschlüsselung für einen Raum nicht deaktiviert werden. In einem verschlüsselten Raum gesendete Nachrichten können vom Server nicht gesehen werden, nur von den Teilnehmenden des Raums. Durch die Verschlüsselung funktionieren viele Bots und Bridges möglicherweise nicht ordnungsgemäß.</string>
+    <string name="room_settings_enable_encryption_dialog_submit">Verschlüsselung aktivieren</string>
+
+    <string name="verification_request_notice">Um sicher zu gehen, verifiziere %s, indem ein einmaligen Code überprüft wird.</string>
+    <string name="verification_request_start_notice">Um sicher zu sein, tut dies persönlich oder verwendet einen anderen Kommunikationsweg.</string>
+
+    <string name="verification_emoji_notice">Vergleiche die einzigartigen Emoji und stell sicher, dass sie in derselben Reihenfolge angezeigt werden.</string>
+    <string name="verification_code_notice">Vergleiche den Code mit dem Code auf dem Bildschirm deines Gegenübers.</string>
+    <string name="verification_conclusion_ok_notice">Nachrichten mit diesem Gegenüber sind Ende-zu-Ende verschlüsselt und können nicht von Dritten gelesen werden.</string>
+    <string name="verification_conclusion_ok_self_notice">Deine neue Sitzung ist jetzt verifiziert. Sie hat Zugriff auf deine verschlüsselten Nachrichten, und andere Benutzer!nnen sehen sie als vertrauenswürdig an.</string>
+
+
+    <string name="encryption_information_cross_signing_state">Cross-Signing</string>
+    <string name="encryption_information_dg_xsigning_complete">Cross-Signing ist aktiviert
+\nPrivate Schlüssel auf dem Gerät.</string>
+    <string name="encryption_information_dg_xsigning_trusted">Cross-Signing ist aktiviert
+\nSchlüssel sind vertrauenswürdig.
+\nPrivate Schlüssel sind nicht bekannt</string>
+    <string name="encryption_information_dg_xsigning_not_trusted">Cross-Signing ist aktiviert
+\nSchlüssel sind nicht vertrauenswürdig</string>
+    <string name="encryption_information_dg_xsigning_disabled">Cross-Signing ist nicht aktiviert</string>
+
+
+    <string name="settings_active_sessions_list">Aktive Sitzungen</string>
+    <string name="settings_active_sessions_show_all">Zeige alle Sitzungen</string>
+    <string name="settings_active_sessions_manage">Verwalte Sitzungen</string>
+    <string name="settings_active_sessions_signout_device">Diese Sitzung abmelden</string>
+
+    <string name="settings_failed_to_get_crypto_device_info">Keine kryptografischen Informationen verfügbar</string>
+
+    <string name="settings_active_sessions_verified_device_desc">Diese Sitzung ist für sichere Nachrichtenübertragung vertrauenswürdig, da du sie überprüft hast:</string>
+    <string name="settings_active_sessions_unverified_device_desc">Verifiziere diese Sitzung, um sie als vertrauenswürdig zu markieren, und gewähren ihr Zugriff auf verschlüsselte Nachrichten. Wenn du dich nicht bei dieser Sitzung angemeldet hast, ist dein Konto möglicherweise gefährdet:</string>
+
+    <plurals name="settings_active_sessions_count">
+        <item quantity="one">Eine aktive Sitzung</item>
+        <item quantity="other">%d aktive Sitzungen</item>
+    </plurals>
+
+    <string name="crosssigning_verify_this_session">Verifiziere diese Sitzung</string>
+    <string name="crosssigning_other_user_not_trust">Andere Benutzer!nnen vertrauen ihr möglicherweise nicht</string>
+    <string name="complete_security">Vollständige Sicherheit</string>
+
+    <string name="verification_open_other_to_verify">Nutze eine vorhandene Sitzung um diese Sitzung zu verifizieren und ihr Zugriff auf verschlüsselte Nachrichten zu gewähren.</string>
+
+
+    <string name="verification_profile_verify">Verifizieren</string>
+    <string name="verification_profile_verified">Verifiziert</string>
+    <string name="verification_profile_warning">Warnung</string>
+
+    <string name="room_member_profile_failed_to_get_devices">Sitzungen konnten nicht abgerufen werden</string>
+    <string name="room_member_profile_sessions_section_title">Sitzungen</string>
+    <string name="trusted">Vertraut</string>
+    <string name="not_trusted">Nicht vertraut</string>
+
+    <string name="verification_profile_device_verified_because">Diese Sitzung ist für sichere Nachrichtenübertragung vertrauenswürdig, weil %1$s (%2$s) sie verifiziert hat:</string>
+    <string name="verification_profile_device_new_signing">%1$s (%2$s) hat sich in einer neuen Sitzung angemeldet:</string>
+    <string name="verification_profile_device_untrust_info">Bis diese/r Benutzer!n dieser Sitzung vertraut, werden an und von ihr/ihm gesendete Nachrichten mit Warnungen gekennzeichnet. Alternativ kannst du dies manuell überprüfen.</string>
+
+
+    <string name="initialize_cross_signing">Initialisiere Cross-Signing</string>
+    <string name="reset_cross_signing">Schlüssel zurücksetzen</string>
+
+    <string name="a11y_qr_code_for_verification">QR-Code</string>
+
+    <string name="qr_code_scanned_by_other_notice">Fast geschaft! Zeigt %s dasselbe Schild an\?</string>
+    <string name="qr_code_scanned_by_other_yes">Ja</string>
+    <string name="qr_code_scanned_by_other_no">Nein</string>
+
+    <string name="no_connectivity_to_the_server_indicator">Verbindung zum Server wurde unterbrochen</string>
+
+    <string name="settings_dev_tools">Entwicklungswerkzeuge</string>
+    <string name="settings_account_data">Kontodaten</string>
+    <plurals name="poll_info">
+        <item quantity="one">%d Stimme</item>
+        <item quantity="other">%d Stimmen</item>
+    </plurals>
+    <plurals name="poll_info_final">
+        <item quantity="one">%d Stimme - Endergebnis</item>
+        <item quantity="other">%d Stimmen - Endergebnis</item>
+    </plurals>
+    <string name="poll_item_selected_aria">Ausgewählte Option</string>
+    <string name="command_description_poll">Erstellt eine einfache Umfrage</string>
+    <string name="verification_cannot_access_other_session">Nutze eine Wiederherstellungsmethode</string>
+    <string name="verification_use_passphrase">Wenn du auf keine existierende Sitzung zugreifen kannst</string>
+
+    <string name="new_signin">Neue Anmeldung</string>
+
+    <string name="enter_secret_storage_invalid">Kann keine Geheimnisse im Speicher finden</string>
+    <string name="enter_secret_storage_passphrase">Gib die geheime Speicherpassphrase ein</string>
+    <string name="enter_secret_storage_passphrase_warning">Warnung:</string>
+    <string name="enter_secret_storage_passphrase_warning_text">Du solltest nur von einem vertrauenswürdigen Gerät auf den geheimen Speicher zugreifen</string>
+
+    <string name="message_action_item_redact">Entfernen…</string>
+    <string name="share_confirm_room">Möchtest du diesen Anhang an %1$s senden\?</string>
+    <plurals name="send_images_with_original_size">
+        <item quantity="one">Sende Bild in Originalgröße</item>
+        <item quantity="other">Sende Bilder in Originalgröße</item>
+    </plurals>
+
+    <string name="delete_event_dialog_title">Entfernen bestätigen</string>
+    <string name="delete_event_dialog_content">Möchtest du dieses Ereignis wirklich entfernen (löschen)\? Beachte, dass beim Löschen eines Raumnamens oder einer Themenänderung die Änderung rückgängig gemacht werden kann.</string>
+    <string name="delete_event_dialog_reason_checkbox">Grund hinzufügen</string>
+    <string name="delete_event_dialog_reason_hint">Grund für das Editieren</string>
+
+    <string name="event_redacted_by_user_reason_with_reason">Ereignis gelöscht von Benutzer!n, Grund: %1$s</string>
+    <string name="event_redacted_by_admin_reason_with_reason">Ereignis vom Raumadministration moderiert, Grund: %1$s</string>
+
+    <string name="keys_backup_restore_success_title_already_up_to_date">Schlüssel sind bereits aktuell!</string>
+
+    <string name="spoiler">Spoiler</string>
+    <string name="room_member_power_level_custom_in">Benutzerdefiniert (%1$d) in %2$s</string>
+
+    <string name="login_mobile_device_riotx">RiotX Android</string>
+
+    <string name="settings_key_requests">Schlüsselanforderungen</string>
+
+    <string name="e2e_use_keybackup">Schalte den verschlüsselten Nachrichtenverlauf frei</string>
+
+    <string name="refresh">Neu laden</string>
+
+    <string name="new_session">Neue Anmeldung. Warst du das\?</string>
+    <string name="new_session_review">Tippe für eine Überprüfung &amp; Verifikation</string>
+    <string name="verify_new_session_notice">Benutze diese Sitzung um deine neue zu verfizieren, damit sie auf verschlüsselte Nachrichten zugreifen kann.</string>
+    <string name="verify_new_session_was_not_me">Das war ich nicht</string>
+    <string name="verify_new_session_compromized">Dein Account ist möglicherweise komprimittiert</string>
+
+    <string name="verify_cancel_self_verification_from_untrusted">Wenn du abbrichst, wirst du auf diesem Gerät keine verschlüsselten Nachrichten lesen können, und andere Benutzer werden ihm nicht vertrauen</string>
+    <string name="verify_cancel_self_verification_from_trusted">Wenn du abbrichst, wirst du auf deinem neuen Gerät keine verschlüsselten Nachrichten lesen können, und andere Benutzer werden ihm nicht vertrauen</string>
+    <string name="verify_cancel_other">Du wirst %1$s (%2$s) nicht verifizieren, wenn du jetzt abbrichst. Beginne in deren Nutzerprofil erneut.</string>
+
+    <string name="verify_not_me_self_verification">Eines der folgenden könnte kom­pro­mit­tie­rt sein:
+\n
+\n- Dein Passwort
+\n- Dein Home-Server
+\n- Dieses Gerät, oder das andere Gerät
+\n- Die Internetverbindung, die von den Geräten genutzt wird
+\n
+\nWir empfehlen dir dein Passwort &amp; Wiederherstellungsschlüssel in den Einstellungen sofort zu ändern.</string>
+
+    <string name="verify_cancelled_notice">Verifiziere deine Geräte in den Einstellungen.</string>
+    <string name="verification_cancelled">Verifizierung abgebrochen</string>
+
+    <string name="generate_message_key">Generiere einen Nachrichtenschlüssel</string>
+
+    <string name="confirm_recovery_passphrase">Bestätige %s</string>
+
+    <string name="enter_account_password">Gibe dein %s ein um fortzufahren.</string>
+
+    <string name="bootstrap_info_confirm_text">Gebe deine %s für eine Bestätigung erneut ein.</string>
+    <string name="bootstrap_dont_reuse_pwd">Benutze dein Accountpasswort nicht mehrfach.</string>
+
+
+    <string name="bootstrap_loading_text">Dies könnte einige Sekunden dauern, gedulde dich bitte.</string>
+    <string name="bootstrap_loading_title">Wiederherstellung einrichten.</string>
+    <string name="your_recovery_key">Dein Wiederherstellungsschlüssel</string>
+    <string name="bootstrap_finish_title">Du bist fertig!</string>
+    <string name="keep_it_safe">Bewahre es sicher auf</string>
+    <string name="finish">Abschließen</string>
+
+    <string name="bootstrap_save_key_description">Benutze diesen %1$s als Sicherheit für den Fall, dass du deine %2$s vergisst.</string>
+
+    <string name="bootstrap_crosssigning_progress_initializing">Veröffentliche erstellte Identitätsschlüssel</string>
+    <string name="bootstrap_crosssigning_progress_pbkdf2">Generiere sicheren Schlüssel von der Passphrase</string>
+    <string name="bootstrap_crosssigning_progress_default_key">Definiere SSSS Standardschlüssel</string>
+    <string name="bootstrap_crosssigning_progress_save_msk">Synchronisiere Hauptschlüssel</string>
+    <string name="bootstrap_crosssigning_progress_save_usk">Synchronisiere Benutzerschlüssel</string>
+    <string name="bootstrap_crosssigning_progress_save_ssk">Synchronisiere selbstsignierenden Schlüssel</string>
+    <string name="bootstrap_crosssigning_progress_key_backup">Richte Schlüsselbackup ein</string>
+
+
+    <string name="bootstrap_cross_signing_success">Deine %2$s &amp; %1$s sind nun eingerichtet.
+\n
+\nBewahre sie sicher auf! Du wirst sie benötigen, um verschlüsselte Nachrichten und sichere Informationen freizuschalten, wenn du alle deine aktive Sitzungen verlierst.</string>
+
+    <string name="bootstrap_crosssigning_save_usb">Speichere ihn auf einem USB-Stick oder auf einem Sicherungslaufwerk</string>
+    <string name="error_failed_to_import_keys">Import der Schlüssel fehlgeschlagen</string>
+
+    <string name="settings_notification_configuration">Benachrichtigungskonfiguration</string>
+    <string name="settings_messages_at_room">\@raum enthaltende Nachrichten</string>
+    <string name="settings_messages_in_e2e_group_chat">Verschlüsselte Nachrichten in Gruppenchats</string>
+    <string name="settings_notification_advanced_summary_riotx">Setze die Benachrichtigungswichtigkeit abhängig vom Ereignistyp</string>
+
+    <string name="command_description_plain">Sendet eine Nachricht als einfachen Text, ohne sie als Markdown zu interpretieren</string>
+
+    <string name="auth_invalid_login_param_space_in_password">Inkorrekter Benutzername und/oder Passwort. Das eingegebene Passwort beginnt oder endet mit Leerzeichen, bitte kontrolliere es.</string>
+
+    <string name="message_key">Nachrichtenschlüssel</string>
+    <string name="account_password">Kontopasswort</string>
+
+    <string name="recovery_passphrase">Wiederherstellungs-Passphrase</string>
+    <string name="bootstrap_crosssigning_print_it">Druck es aus und speichere es an einem sicheren Ort</string>
+    <string name="bootstrap_crosssigning_save_cloud">Kopier es in deinen persönlichen Cloud-Speicher</string>
+
+    <string name="encryption_not_enabled">Verschlüsselung ist nicht aktiviert</string>
 </resources>
diff --git a/vector/src/main/res/values-es/strings.xml b/vector/src/main/res/values-es/strings.xml
index 9ae69b7e52..ec37ea2825 100644
--- a/vector/src/main/res/values-es/strings.xml
+++ b/vector/src/main/res/values-es/strings.xml
@@ -1482,7 +1482,7 @@ Ten en cuenta que esta acción reiniciará la aplicación y puede tardar algo de
     <string name="sas_got_it">Ok</string>
 
     <string name="sas_verifying_keys">¿No aparece nada\? No todas las aplicaciones cliente soportan verificación interactiva. Usa la verificación clásica.</string>
-    <string name="sas_legacy_verification_button_title">Usar verificación clásica</string>
+    <string name="sas_legacy_verification_button_title">Usar verificación clásica.</string>
 
     <string name="sas_verification_request_notification_channel_title">Verificación de clave</string>
     <string name="sas_cancelled_dialog_title">Solicitud cancelada</string>
@@ -1597,7 +1597,7 @@ Ten en cuenta que esta acción reiniciará la aplicación y puede tardar algo de
     <string name="call_failed_no_ice_description">Por favor, pídele al administrador de tu servidor doméstico (%1$s) que configure un servidor TURN para que las llamadas funcionen de forma fiable.
 \n
 \nAlternativamente, puedes intentar usar el servidor público en %2$s, pero no será tan confiable, y compartirá tu dirección IP con ese servidor. También puedes cambiar esto en Configuración.</string>
-    <string name="auth_add_email_message_2">Configura un correo electrónico para la recuperación de la cuenta, y más tarde configúralo ser descubierto opcionalmente por personas que te conozcan</string>
+    <string name="auth_add_email_message_2">Configura un correo electrónico para la recuperación de la cuenta, y opcionalmente para encontrar personas conocidas</string>
     <string name="auth_add_email_phone_message_2">Configura un correo electrónico para la recuperación de la cuenta. Usa el correo electrónico o el teléfono más tarde para ser descubierto opcionalmente por personas que te conozcan.</string>
     <string name="auth_add_email_and_phone_message_2">Configura un correo electrónico para la recuperación de la cuenta. Usa el correo electrónico o el teléfono más tarde para ser descubierto opcionalmente por personas que te conozcan.</string>
     <string name="login_error_no_homeserver_found">Esta no es una dirección de servidor Matrix válida</string>
@@ -1878,4 +1878,36 @@ Ten en cuenta que esta acción reiniciará la aplicación y puede tardar algo de
     <string name="login_splash_submit">Empieza</string>
 
     <string name="login_server_title">Selecciona un servidor</string>
+    <string name="login_server_text">Como el correo electrónico, las cuantas tienen un hogar, aunque se puede hablar con cualquiera</string>
+    <string name="login_server_modular_text">Alojamiento de pago para organizaciones</string>
+    <string name="login_server_modular_learn_more">Saber más</string>
+    <string name="login_server_other_title">Otro</string>
+    <string name="login_server_other_text">Ajustes avanzados y de personalización</string>
+
+    <string name="login_continue">Continuar</string>
+    <string name="login_connect_to">Conectarse a %1$s</string>
+    <string name="login_connect_to_modular">Conectarse a Modular</string>
+    <string name="login_connect_to_a_custom_server">Conectarse a un servidor externo</string>
+    <string name="login_signin_to">Iniciar sesión en %1$s</string>
+    <string name="login_signup">Registrarse</string>
+    <string name="login_signin">Iniciar sesión</string>
+    <string name="login_server_url_form_other_hint">Dirección</string>
+    <string name="login_server_url_form_modular_text">Alojamiento de pago para organizaciones</string>
+    <string name="login_server_url_form_modular_notice">Introduzca la dirección de Modular Riot o servidor que quieres usar</string>
+    <string name="login_server_url_form_other_notice">Introduzca la dirección del servidor Riot al que quieres conectarte</string>
+
+    <string name="login_sso_error_message">Se produjo un error al cargar la pagina: %1$s (%2$d)</string>
+    <string name="login_mode_not_supported">"La aplicación no es capaz de iniciar sesión en este servidor. Este solo soporta el acceso mediante:  %1$s.
+\n
+\n¿Quieres acceder usando un cliente web\?"</string>
+    <string name="login_registration_disabled">Lo sentimos, este servidor no acepta nuevas cuentas.</string>
+    <string name="login_registration_not_supported">La aplicación no fue capaz de crear una cuenta en este servidor.
+\n
+\n¿Quieres registrarte usando un cliente web\?</string>
+
+    <string name="login_login_with_email_error">La dirección de coreo electrónico no está asociada a ninguna cuenta.</string>
+
+    <string name="login_reset_password_on">Reiniciar contraseña en %1$s</string>
+    <string name="keys_backup_restore_success_title_already_up_to_date">¡Las claves ya están al día!</string>
+
 </resources>
diff --git a/vector/src/main/res/values-eu/strings.xml b/vector/src/main/res/values-eu/strings.xml
index dd8ead5f27..14827878a4 100644
--- a/vector/src/main/res/values-eu/strings.xml
+++ b/vector/src/main/res/values-eu/strings.xml
@@ -285,7 +285,7 @@ Baimendu sarbidea hurrengo laster-leihoan zure telefonotik fitxategiak bidali ah
     <string name="room_participants_action_unban">Debekua kendu</string>
     <string name="room_participants_action_set_default_power_level">Berrezarri erabiltzaile arrunt gisa</string>
     <string name="room_participants_action_set_moderator">Bihurtu moderatzaile</string>
-    <string name="room_participants_action_set_admin">Bihurtu kudeatzaile</string>
+    <string name="room_participants_action_set_admin">Bihurtu administratzaile</string>
     <string name="room_participants_action_ignore">Ezkutatu kide honen mezu guztiak</string>
     <string name="room_participants_action_unignore">Erakutsi kide honen mezu guztiak</string>
     <string name="room_participants_invite_search_another_user">Erabiltzailearen IDa, izena edo e-maila</string>
@@ -635,7 +635,7 @@ Orain egin dezakezu edo gero aplikazioaren ezarpenetatik.</string>
     <string name="people_search_user_directory">ERABILTZAILE DIREKTORIOA (%s)</string>
     <string name="settings_data_save_mode">Datuak gordetzeko modua</string>
 
-    <string name="settings_theme">Itxura</string>
+    <string name="settings_theme">Azala</string>
 
     <string name="font_size">Letra-tamaina</string>
     <string name="tiny">Oso txikia</string>
@@ -645,9 +645,9 @@ Orain egin dezakezu edo gero aplikazioaren ezarpenetatik.</string>
     <string name="larger">Oso handia</string>
     <string name="largest">Handiena</string>
     <string name="huge">Erraldoia</string>
-    <string name="light_theme">Itxura argia</string>
-    <string name="dark_theme">Itxura iluna</string>
-    <string name="black_them">Itxura beltza</string>
+    <string name="light_theme">Azal argia</string>
+    <string name="dark_theme">Azal iluna</string>
+    <string name="black_them">Azal beltza</string>
 
     <string name="notification_sync_in_progress">Sinkronizatzen…</string>
     <string name="notification_listening_for_events">Entzun gertaerak</string>
@@ -881,7 +881,7 @@ Matrix-eko mezuen ikusgaitasuna e-mail sistemaren antekoa da. Guk zure mezuak ah
     <string name="download">Deskargatu</string>
     <string name="speak">Hitz egin</string>
     <string name="clear">Garbitu</string>
-    <string name="e2e_re_request_encryption_key"><u>Berriro eskatu zifratze-gakoak</u> zure beste saioetatik.</string>
+    <string name="e2e_re_request_encryption_key">Eskatu berriro zifratze-gakoak zure beste saioetatik.</string>
 
     <string name="e2e_re_request_encryption_key_sent">Gako eskaria bidalita.</string>
 
@@ -991,7 +991,7 @@ Kontuan izan ekintza honek aplikazioa berrabiaraziko duela eta denbora bat behar
 
     <string name="unknown_error">Errore bat gertatu da</string>
 
-    <string name="status_theme">Status.im itxura</string>
+    <string name="status_theme">Status.im azala</string>
 
     <string name="room_sliding_menu_version_x">%s bertsioa</string>
     <string name="encryption_export_notice">Sortu esportatutako gakoak zifratzeko pasaesaldi bat. Pasaesaldi hori gakoak inportatzeko sartu beharko duzu.</string>
@@ -1291,7 +1291,7 @@ Abisua: Fitxategi hau ezabatu daiteke aplikazioa desinstalatzen bada.</string>
     <string name="ignore">Ezikusi</string>
 
     <string name="action_sign_out_confirmation_simple">Ziur saioa amaitu nahi duzula\?</string>
-    <string name="auth_login_sso">Hasi saioa urrats batean</string>
+    <string name="auth_login_sso">Hasi saioa Single sign-on bidez</string>
     <string name="login_error_unknown_host">URL-a ez dago eskuragarri, egiaztatu mesedez</string>
     <string name="login_error_ssl_handshake">Zure gailuak zaharkitutako TLS segurtasun protokolo bat darabil, erasotu daitekeena, zure segurtasunerako ezin izango zara konektatu</string>
     <string name="settings_send_message_with_enter">Bidali mezua Sartu tekla sakatuta</string>
@@ -1344,7 +1344,7 @@ Abisua: Fitxategi hau ezabatu daiteke aplikazioa desinstalatzen bada.</string>
     <string name="keys_backup_banner_recover_line1">Ez galdu inoiz zifratutako mezuak</string>
     <string name="keys_backup_banner_recover_line2">Erabili gakoen babes-kopia</string>
 
-    <string name="keys_backup_banner_update_line1">Zifratutako mezuen gako berriak</string>
+    <string name="keys_backup_banner_update_line1">Mezu seguruen gako berriak</string>
     <string name="keys_backup_banner_update_line2">Kudeatu gakoen babes-kopian</string>
 
     <string name="keys_backup_banner_in_progress">Gakoen babes-kopia egiten…</string>
@@ -1553,12 +1553,12 @@ Abisua: Fitxategi hau ezabatu daiteke aplikazioa desinstalatzen bada.</string>
 
     <string name="store_riotx_title">RiotX - Hurrengo belaunaldiko Matrix bezeroa</string>
     <string name="store_riotx_short_description">Matrix-erako bezero azkarrago eta arinago bat azken Android tresnak erabiliz eginak</string>
-    <string name="store_riotx_full_description">RiotX bezero berri bat da Matrix protokoloarentzako (Matrix.org): komunikazioa seguru eta deszentralizatuarentzako sare libre bat. RiotX Android plataformarako Riot bezeroaren berridazketa oso bat da, erabat berridatzitako Android SDK-n oinarritua.
-\n
-\nAbisua: hau beta bertsio bat da. RiotX garapen aktiboan dago eta baditu mugak zein akatsak (gehiegi ez espero dugu). Iruzkin guztiak ongi etorriak dira!
-\n
-\nRiotX bezeroak honakoa ahalbidetzen du: • Badagoen kontu batean saioa hasi • Gelak sortu eta gela publikoetara elkartu • Gonbidapenak onartu edo ukatu • Erabiltzailearen gelak zerrendatu • Gelaren xehetasunak ikusi • Testuzko mezuak bidali • Eranskinak bidali • Zifratutako geletan mezuak irakurri eta idatzi • Zifratzea: E2Egakoen babeskopia, gailuaren egiaztaketa aurreratua, gakoa partekatzeko eskaria eta erantzuna • Push jakinarazpena • Gai argia, iluna eta beltza
-\n
+    <string name="store_riotx_full_description">RiotX bezero berri bat da Matrix protokoloarentzako (Matrix.org): komunikazioa seguru eta deszentralizatuarentzako sare libre bat. RiotX Android plataformarako Riot bezeroaren berridazketa oso bat da, erabat berridatzitako Android SDK-n oinarritua. 
+\n 
+\nAbisua: hau beta bertsio bat da. RiotX garapen aktiboan dago eta baditu mugak zein akatsak (gehiegi ez espero dugu). Iruzkin guztiak ongi etorriak dira! 
+\n 
+\nRiotX bezeroak honakoa ahalbidetzen du: • Badagoen kontu batean saioa hasi • Gelak sortu eta gela publikoetara elkartu • Gonbidapenak onartu edo ukatu • Erabiltzailearen gelak zerrendatu • Gelaren xehetasunak ikusi • Testuzko mezuak bidali • Eranskinak bidali • Zifratutako geletan mezuak irakurri eta idatzi • Zifratzea: E2Egakoen babeskopia, gailuaren egiaztaketa aurreratua, gakoa partekatzeko eskaria eta erantzuna • Push jakinarazpena • Azal argia, iluna eta beltza 
+\n 
 \nEz dira oraindik Riot bezeroaren ezaugarri guztiak ezarri RiotX bezeroan. Falta diren (eta laster etorriko direnen) artean nabarmenak dira: • Gelaren ezarpenak (gelako kideak zerrendatzea, eta abar.) • Deiak • Trepetak • …</string>
 
     <string name="push_gateway_item_app_display_name">aplikazio_pantaila_izena:</string>
@@ -1784,7 +1784,7 @@ Abisua: Fitxategi hau ezabatu daiteke aplikazioa desinstalatzen bada.</string>
     <string name="room_widget_permission_display_name">Zure pantaila-izena</string>
     <string name="room_widget_permission_avatar_url">Zure abatarraren URL-a</string>
     <string name="room_widget_permission_user_id">Zure erabiltzaile ID-a</string>
-    <string name="room_widget_permission_theme">Zure gaia</string>
+    <string name="room_widget_permission_theme">Zure azala</string>
     <string name="room_widget_permission_widget_id">Trepetaren ID-a</string>
     <string name="room_widget_permission_room_id">Gelaren ID-a</string>
 
@@ -2079,8 +2079,8 @@ Abisua: Fitxategi hau ezabatu daiteke aplikazioa desinstalatzen bada.</string>
 
     <string name="room_member_jump_to_read_receipt">Saltatu irakurragirira</string>
 
-    <string name="rendering_event_error_type_of_event_not_handled">RiotX aplikazioak oraindik ez ditu \'%1$s\' motako gertaerak kudeatzen</string>
-    <string name="rendering_event_error_type_of_message_not_handled">RiotX aplikazioak oraindik ez ditu \'%1$s\' motako mezuak kudeatzen</string>
+    <string name="rendering_event_error_type_of_event_not_handled">RiotX aplikazioak ez ditu \'%1$s\' motako gertaerak kudeatzen</string>
+    <string name="rendering_event_error_type_of_message_not_handled">RiotX aplikazioak ez ditu \'%1$s\' motako mezuak kudeatzen</string>
     <string name="rendering_event_error_exception">RiotX aplikazioak arazo bat izan du \'%1$s\' id-a duen edukia erakusteko</string>
 
     <string name="unignore">Utzi ezikusteari</string>
@@ -2144,7 +2144,7 @@ Abisua: Fitxategi hau ezabatu daiteke aplikazioa desinstalatzen bada.</string>
     <string name="crosssigning_other_user_not_trust">Beste erabiltzaile batzuk ez fidagarritzat jo lezakete</string>
     <string name="complete_security">Bete segurtasuna</string>
 
-    <string name="verification_open_other_to_verify">Ireki aurreko saio bat eta erabili hori saio hau egiaztatzeko, mezu zifratuetara sarbidea emanez. Ez baduzu bat erabiltzerik, erabili berreskuratze gakoa edo pasa-esaldia.</string>
+    <string name="verification_open_other_to_verify">Erabili aurreko saio bat saio hau egiaztatzeko, mezu zifratuetara sarbidea emanez.</string>
 
 
     <string name="verification_profile_verify">Egiaztatu</string>
@@ -2166,8 +2166,188 @@ Abisua: Fitxategi hau ezabatu daiteke aplikazioa desinstalatzen bada.</string>
 
     <string name="a11y_qr_code_for_verification">QR kodea</string>
 
+    <string name="qr_code_scanned_by_other_notice">Ia bukatu duzu! %s-ek ezkutu bera erakusten du\?</string>
     <string name="qr_code_scanned_by_other_yes">Bai</string>
     <string name="qr_code_scanned_by_other_no">Ez</string>
 
     <string name="no_connectivity_to_the_server_indicator">Zerbitzariarekin konexioa galdu da</string>
+    <string name="login_signup_username_hint">Erabiltzaile-izena</string>
+    <string name="settings_dev_tools">Garapen tresnak</string>
+    <string name="settings_account_data">Kontuaren datuak</string>
+    <plurals name="poll_info">
+        <item quantity="one">boto %d</item>
+        <item quantity="other">%d boto</item>
+    </plurals>
+    <plurals name="poll_info_final">
+        <item quantity="one">boto %d - Azken emaitza</item>
+        <item quantity="other">%d boto - Azken emaitza</item>
+    </plurals>
+    <string name="poll_item_selected_aria">Hautatutako aukera</string>
+    <string name="command_description_poll">Inkesta sinplea sortzen du</string>
+    <string name="verification_cannot_access_other_session">Erabili berreskuratze metodo bat</string>
+    <string name="verification_use_passphrase">Ezin baduzu badagoen saio bat erabili</string>
+
+    <string name="new_signin">Saio berria</string>
+
+    <string name="enter_secret_storage_invalid">Ezin izan da sekreturik aurkitu biltegian</string>
+    <string name="enter_secret_storage_passphrase">Sartu biltegi sekretuko pasa-esaldia</string>
+    <string name="enter_secret_storage_passphrase_warning">Abisua:</string>
+    <string name="enter_secret_storage_passphrase_warning_text">Biltegi sekretura gailu fidagarri batetik konektatu beharko zinateke beti</string>
+
+    <string name="message_action_item_redact">Kendu…</string>
+    <string name="share_confirm_room">Eranskin hau %1$s gelara bidali nahi duzu\?</string>
+    <plurals name="send_images_with_original_size">
+        <item quantity="one">Bidali irudia jatorrizko tamainan</item>
+        <item quantity="other">Bidali irudiak jatorrizko tamainan</item>
+    </plurals>
+
+    <string name="delete_event_dialog_title">Berretsi kentzea</string>
+    <string name="delete_event_dialog_content">Ziur gertaera hau kendu (ezabatu) nahi duzula\? Jakin gelaren izenaren edo mintzagaiaren aldaketa ezabatzen baduzu, aldaketa desegin daitekeela.</string>
+    <string name="delete_event_dialog_reason_checkbox">Eman arrazoi bat</string>
+    <string name="delete_event_dialog_reason_hint">Kentzeko arrazoia</string>
+
+    <string name="event_redacted_by_user_reason_with_reason">Erabiltzaileak kendu du gertaera, arrazoia: %1$s</string>
+    <string name="event_redacted_by_admin_reason_with_reason">Gelako moderatzaile batek kendu du gertaera, arrazoia: %1$s</string>
+
+    <string name="keys_backup_restore_success_title_already_up_to_date">Gakoak egunean daude jada!</string>
+
+    <string name="login_mobile_device_riotx">RiotX Android</string>
+
+    <string name="settings_key_requests">Gako eskaerak</string>
+
+    <string name="e2e_use_keybackup">Desblokeatu zifratutako mezuen historiala</string>
+
+    <string name="refresh">Freskatu</string>
+
+    <string name="new_session">Egiaztatu gabeko saioa. Zu izan zara\?</string>
+    <string name="new_session_review">Sakatu eta berrikusi eta egiaztatu</string>
+    <string name="verify_new_session_notice">Erabili saio hau berria egiaztatzeko, honela mezu zifratuetara sarbidea emanez.</string>
+    <string name="verify_new_session_was_not_me">Ez naiz ni izan</string>
+    <string name="verify_new_session_compromized">Zure kontua konprometituta egon daiteke</string>
+
+    <string name="verify_cancel_self_verification_from_untrusted">Ezeztatzen baduzu, ezin izango dituzu zifratutako mezuak irakurri gailu honetan, eta beste erabiltzaileek ez dute fidagarritzat joko</string>
+    <string name="verify_cancel_self_verification_from_trusted">Ezeztatzen baduzu, ezin izango dituzu zifratutako mezuak irakurri gailu berrian, eta beste erabiltzaileek ez dute fidagarritzat joko</string>
+    <string name="verify_cancel_other">Ez duzu %1$s (%2$s) egiaztatuko orain ezeztatzen baduzu. Hasi berriro bere erabiltzaile profilean.</string>
+
+    <string name="verify_not_me_self_verification">Hauetakoren bat konprometituta egon daiteke:
+\n
+\n- Zure pasahitza
+\n- Zure hasiera-zerbitzaria
+\n- Gailu hau, edo beste gailua
+\n- Gailuren batek darabilen internet konexioa
+\n
+\nPasahitza eta berreskuratze gajoa ezarpenetan berehala aldatzea aholkatzen dugu.</string>
+
+    <string name="verify_cancelled_notice">Egiaztatu gailuak ezarpenetatik.</string>
+    <string name="verification_cancelled">Egiaztaketa ezeztatuta</string>
+
+    <string name="recovery_passphrase">Berreskuratze pasa-esaldia</string>
+    <string name="message_key">Mezu-gakoa</string>
+    <string name="account_password">Kontuaren pasahitza</string>
+
+    <string name="set_recovery_passphrase">Ezarri %s bat</string>
+    <string name="generate_message_key">Sortu mezu-gakoa</string>
+
+    <string name="confirm_recovery_passphrase">Berretsi %s</string>
+
+    <string name="enter_account_password">Sartu zure %s jarraitzeko.</string>
+
+    <string name="bootstrap_info_text">Babestu eta desblokeatu zifratutako mezuak eta jo fidagarritzat %s erabiliz.</string>
+    <string name="bootstrap_info_confirm_text">Sartu zure %s berriro hau berresteko.</string>
+    <string name="bootstrap_dont_reuse_pwd">Ez berrerabili zure kontuaren pasahitza.</string>
+
+
+    <string name="bootstrap_loading_text">Honek segundo batzuk behar litzake, itxaron.</string>
+    <string name="bootstrap_loading_title">Berrekuratzea ezartzen.</string>
+    <string name="your_recovery_key">Zure berreskuratze-gakoa</string>
+    <string name="bootstrap_finish_title">Bukatu duzu!</string>
+    <string name="keep_it_safe">Gorde toki seguruan</string>
+    <string name="finish">Amaitu</string>
+
+    <string name="bootstrap_save_key_description">Erabili %1$s hau babes gehigarri gisa, %2$s ahaztekotan.</string>
+
+    <string name="bootstrap_crosssigning_progress_initializing">Sortutako identitate-gakoak argitaratzen</string>
+    <string name="bootstrap_crosssigning_progress_pbkdf2">Gako segurua pasa-esalditik sortzen</string>
+    <string name="bootstrap_crosssigning_progress_default_key">Lehenetsitako SSSS gakoa definitzen</string>
+    <string name="bootstrap_crosssigning_progress_save_msk">Gako nagusia sinkronizatzen</string>
+    <string name="bootstrap_crosssigning_progress_save_usk">Erabiltzaile-gakoa sinkronizatzen</string>
+    <string name="bootstrap_crosssigning_progress_save_ssk">Norberak sinatzeko gakoa sinkronizatzen</string>
+    <string name="bootstrap_crosssigning_progress_key_backup">Gakoen babeskopia ezartzen</string>
+
+
+    <string name="bootstrap_cross_signing_success">"Zure %2$s eta %1$s ezarrita daude.
+\n
+\nGorde toki seguruan! Zifratutako mezuak eta informazio segurua desblokeatzeko beharko dituzu  zure saio aktibo guztiak galduz gero."</string>
+
+    <string name="bootstrap_crosssigning_print_it">Inprimatu eta gorde toki seguruan</string>
+    <string name="bootstrap_crosssigning_save_usb">Gorde USB memorian edo babes-kopien diskoan</string>
+    <string name="bootstrap_crosssigning_save_cloud">Kopiatu zure hodei pertsonalean</string>
+
+    <string name="auth_flow_not_supported">Ezin duzu hori mugikorretik egin</string>
+
+    <string name="bootstrap_skip_text">Berreskuratze pasa-esaldia ezartzeak zifratutako mezuak babestea zein desblokeatzea eta fidagarritasuna ezartzea ahalbidetzen dizu.
+\n
+\nEz baduzu mezuen pasahitz bat ezarri, sortu mezuen gakoa.</string>
+    <string name="bootstrap_skip_text_no_gen_key">Berreskuratze pasa-esaldia ezartzeak zifratutako mezuak babestea zein desblokeatzea eta fidagarritasuna ezartzea ahalbidetzen dizu.</string>
+
+
+    <string name="encryption_enabled">Zifratzea gaituta</string>
+    <string name="encryption_enabled_tile_description">Gela honetako mezuak muturretik muturrera zifratuta daude. Ikasi gehiago eta egiaztatu erabiltzaileak bere erabiltzaile-profilean.</string>
+    <string name="encryption_not_enabled">Zifratzea gaitu gabe</string>
+    <string name="encryption_unknown_algorithm_tile_description">Gela honetan erabilitako zifratzea ez da onartzen</string>
+
+    <string name="room_created_summary_item">%s erabiltzaileak gela sortu eta konfiguratu du.</string>
+
+    <string name="qr_code_scanned_self_verif_notice">Ia amaitu duzu! Zure beste gailuak ezkutu bera erakusten du\?</string>
+    <string name="qr_code_scanned_verif_waiting_notice">Ia bukatu duzu! Baieztapenaren zain…</string>
+    <string name="qr_code_scanned_verif_waiting">%s itxaroten…</string>
+
+    <string name="error_failed_to_import_keys">Ezin izan dira gakoak inportatu</string>
+
+    <string name="settings_notification_configuration">Jakinarazpenen ezarpena</string>
+    <string name="settings_messages_at_room">\@room duten mezuak</string>
+    <string name="settings_messages_in_e2e_one_to_one">Zifratutako mezuak bi pertsonen arteko txatetan</string>
+    <string name="settings_messages_in_e2e_group_chat">Zifratutako mezuak talde-txatetan</string>
+    <string name="settings_when_rooms_are_upgraded">Gelak eguneratzean</string>
+    <string name="settings_troubleshoot_title">Arazo-ehiza</string>
+    <string name="settings_notification_advanced_summary_riotx">Ezarri jakinarazpenen garrantzia gertaerako</string>
+
+    <string name="command_description_plain">Mezua test arrunt gisa bidaltzen du, markdown den aztertu gabe</string>
+
+    <string name="auth_invalid_login_param_space_in_password">Erabiltzaile-izen edo pasahitz okerra. Sartutako pasahitzak zuriuneak ditu hasiera edo amaieran, egiztatu.</string>
+
+    <string name="room_message_placeholder">Mezua…</string>
+
+    <string name="upgrade_security">Zifratze eguneratzea eskuragarri</string>
+    <string name="security_prompt_text">Egiaztatu zure burua eta besteak txatak seguru mantentzeko</string>
+
+    <string name="bootstrap_enter_recovery">Sartu zure %s jarraitzeko</string>
+    <string name="use_file">Erabili fitxategia</string>
+
+    <string name="enter_backup_passphrase">Sartu %s</string>
+    <string name="backup_recovery_passphrase">Berreskuratze pasa-esaldia</string>
+    <string name="bootstrap_invalid_recovery_key">Ez da baliozko berreskuratze-gakoa</string>
+    <string name="recovery_key_empty_error_message">Sartu berreskuratze-gakoa</string>
+
+    <string name="bootstrap_progress_checking_backup">Babes-kopiaren gakoa egiaztatzen</string>
+    <string name="bootstrap_progress_checking_backup_with_info">Babes-kopiaren gakoa egiaztatzen (%s)</string>
+    <string name="bootstrap_progress_compute_curve_key">Curve gakoa jasotzen</string>
+    <string name="bootstrap_progress_generating_ssss">SSSS gakoa pasa-esalditik sortzen</string>
+    <string name="bootstrap_progress_generating_ssss_with_info">SSSS gakoa pasa-esalditik sortzen (%s)</string>
+    <string name="bootstrap_progress_generating_ssss_recovery">SSSS gakoa berreskuratze pasa-esalditik sortzen</string>
+    <string name="bootstrap_progress_storing_in_sss">Gakoen babes-kopia sekretua SSSS-n gordetzen</string>
+    <string name="new_session_review_with_info">%1$s (%2$s)</string>
+
+    <string name="bootstrap_migration_enter_backup_password">Sartu zure gakoen babes-kopiaren pasa-esaldia jarraitzeko.</string>
+    <string name="bootstrap_migration_use_recovery_key">erabili zure gakoen babes-kopiaren berrekuratze gakoa</string>
+    <string name="bootstrap_migration_with_passphrase_helper_with_link">Ez badakizu zure gakoen babes-koparen pasa-esaldia, %s.</string>
+    <string name="bootstrap_migration_backup_recovery_key">Gakoen babes-kopiaren berrekuratze gakoa</string>
+
+    <string name="settings_security_prevent_screenshots_title">Eragotzi aplikazioaren pantaila-argazkiak</string>
+    <string name="settings_security_prevent_screenshots_summary">Ezarpen hau gaitzeak FLAG_SECURE gehitzen die jarduera guztiei. Berrabiarazi aplikazioa aldaketa aplikatzeko.</string>
+
+    <string name="media_file_added_to_gallery">Multimedia fitxategia galeriara gehituta</string>
+    <string name="error_adding_media_file_to_gallery">Ezin izan da multimedia fitxategia galeriara gehitu</string>
+    <string name="change_password_summary">Ezarri kontuaren pasahitz berria…</string>
+
 </resources>
diff --git a/vector/src/main/res/values-fa/strings.xml b/vector/src/main/res/values-fa/strings.xml
index 7f8a2d0c3a..5ec62b8158 100644
--- a/vector/src/main/res/values-fa/strings.xml
+++ b/vector/src/main/res/values-fa/strings.xml
@@ -3,9 +3,9 @@
     <string name="resources_language">fa</string>
     <string name="resources_country_code">IR</string>
 
-    <string name="light_theme">قالب روشن</string>
-    <string name="dark_theme">قالب تیره</string>
-    <string name="black_them">قالب سیاه</string>
+    <string name="light_theme">زمینهٔ روشن</string>
+    <string name="dark_theme">زمینهٔ تیره</string>
+    <string name="black_them">زمینهٔ سیاه</string>
 
     <string name="notification_listening_for_events">گوش دادن به رویدادها</string>
     <string name="title_activity_home">پیام‌ها</string>
@@ -32,7 +32,7 @@
     <string name="active_call">تماس فعال</string>
     <string name="ongoing_conference_call_voice">صوتی</string>
     <string name="ongoing_conference_call_video">تصویری</string>
-    <string name="device_information">اطلاعات دستگاه</string>
+    <string name="device_information">اطّلاعات نشست</string>
     <string name="send_anyway">به هر حال ارسال کنید</string>
     <string name="or">یا</string>
     <string name="invite">دعوت</string>
@@ -106,7 +106,7 @@
     <string name="auth_invalid_phone">شماره تلفن نامعتبر به نظر می‌رسد</string>
     <string name="auth_password_dont_match">گذرواژه‌ها مطابقت ندارد</string>
     <string name="auth_forgot_password">گذرواژه را فراموش کردید؟</string>
-    <string name="auth_use_server_options">از گزینه‌های کارگزار سفارشی استفاده کنید (پیشرفته)</string>
+    <string name="auth_use_server_options">استفاده از گزینه‌های کارساز سفارشی (پیش‌رفته)</string>
     <string name="auth_email_validation_message">برای ادامه‌ی ثبت‌نام، لطفاً ایمیل خود را بررسی کنید</string>
     <string name="auth_reset_password_next_step_button">من آدرس ایمیلم را تایید کرده‌ام</string>
     <string name="login_error_network_error">امکان ورود به سیستم وجود ندارد: خطای شبکه</string>
@@ -141,13 +141,13 @@
 
     <string name="bottom_action_favourites">پسندیده‌ها</string>
     <string name="bottom_action_people">افراد</string>
-    <string name="bottom_action_groups">جامعه‌ها</string>
+    <string name="bottom_action_groups">اجتماع‌ها</string>
 
-    <string name="home_filter_placeholder_home">جستجوی اتاق‌ها</string>
-    <string name="home_filter_placeholder_favorites">جستجوی پسندها</string>
-    <string name="home_filter_placeholder_people">جستجوی افراد</string>
-    <string name="home_filter_placeholder_rooms">جستجوی اتاق‌ها</string>
-    <string name="home_filter_placeholder_groups">جستجوی جامعه‌ها</string>
+    <string name="home_filter_placeholder_home">پالایش نام‌های اتاق</string>
+    <string name="home_filter_placeholder_favorites">پالایش برگزیده‌ها</string>
+    <string name="home_filter_placeholder_people">پالایش افراد</string>
+    <string name="home_filter_placeholder_rooms">پالایش نام‌های اتاق</string>
+    <string name="home_filter_placeholder_groups">پالایش نام‌های اجتماع</string>
 
     <string name="invitations_header">دعوت‌ها</string>
     <string name="system_alerts_header">هشدارهای سیستمی</string>
@@ -160,8 +160,8 @@
 
     <string name="rooms_directory_header">فهرست اتاق‌ها</string>
     <string name="no_room_placeholder">اتاقی نیست</string>
-    <string name="no_public_room_placeholder">اتاق عمومی در دسترس نیست</string>
-    <string name="groups_header">جامعه‌ها</string>
+    <string name="no_public_room_placeholder">هیچ اتاق عمومی‌ای موجود نیست</string>
+    <string name="groups_header">اجتماع‌ها</string>
     <string name="send_bug_report_include_logs">ارسال رخدادنگارها</string>
     <string name="send_bug_report_include_crash_logs">ارسال رخدادنگارهای خطا</string>
     <string name="send_bug_report_include_screenshot">ارسال تصویر صفحه</string>
@@ -273,8 +273,8 @@
 
     <string name="room_participants_header_admin_tools">ابزارهای مدیر</string>
     <string name="room_participants_header_call">تماس</string>
-    <string name="room_participants_header_direct_chats">پیام‌های شخصی</string>
-    <string name="room_participants_header_devices">دستگاه‌ها</string>
+    <string name="room_participants_header_direct_chats">گپ‌های مستقیم</string>
+    <string name="room_participants_header_devices">نشست‌ها</string>
 
     <string name="room_participants_action_invite">دعوت</string>
     <string name="room_participants_action_leave">ترک این اتاق</string>
@@ -296,21 +296,21 @@
     <string name="action_sign_out_confirmation_simple">آیا می‌خواهید از حساب کاربری خود خارج شوید؟</string>
     <string name="action_mark_room_read">علامت‌گذاری به عنوان خوانده شده</string>
     <string name="auth_login_sso">ورود با سامانه‌های احراز هویت مرکزی</string>
-    <string name="status_theme">قالب Status.im</string>
+    <string name="status_theme">زمینهٔ Status.im</string>
 
     <string name="notification_sync_init">راه‌اندازی سرویس</string>
-    <string name="notification_noisy_notifications">اعلان‌های باصدا</string>
-    <string name="notification_silent_notifications">اعلان‌های بی‌صدا</string>
+    <string name="notification_noisy_notifications">آگاهی‌های پرصدا</string>
+    <string name="notification_silent_notifications">آگاهی‌های صامت</string>
 
     <string name="title_activity_historical">تاریخچه</string>
-    <string name="title_activity_group_details">جزئیات جامعه</string>
+    <string name="title_activity_group_details">جزییات اجتماع</string>
     <string name="title_activity_choose_sticker">ارسال استیکر</string>
     <string name="title_activity_keys_backup_setup">پشتیبان‌گیری کلید</string>
     <string name="title_activity_keys_backup_restore">بازیابی پشتیبان کلید</string>
     <string name="keys_backup_is_not_finished_please_wait">پشتیبان‌گیری از کلید هنوز به پایان نرسیده است، لطفاً صبر کنید…</string>
     <string name="sign_out_bottom_sheet_warning_no_backup">در صورتی که الآن از حساب خود خارج شوید، پیام‌های رمز خود را از دست خواهید داد</string>
     <string name="sign_out_bottom_sheet_warning_backing_up">پشتیبان‌گیری کلید در جریان است. در صورتی که الآن از حساب خود خارج شوید، پیام‌های رمز خود را از دست خواهید داد.</string>
-    <string name="sign_out_bottom_sheet_warning_backup_not_active">برای جلوگیری از گم شدن پیام‌های رمز، پشتیبان امن کلید باید روی تمام دستگاه‌های شما فعال باشد.</string>
+    <string name="sign_out_bottom_sheet_warning_backup_not_active">برای از دست ندادن دسترسی به پیام‌های رمزشده، باید پشتیبان کلید امن روی تمام نشست‌هایتان فعّال باشد.</string>
     <string name="sign_out_bottom_sheet_dont_want_secure_messages">پیام‌های رمز خود را نمی‌خواهم</string>
     <string name="sign_out_bottom_sheet_backing_up_keys">پشتیبان‌گیری از کلیدها…</string>
     <string name="keys_backup_activate">استفاده از پشتیبان کلید</string>
@@ -332,14 +332,326 @@
 \nمی‌توانید در ادامه ایمیل خود را در تنظیمات برنامه به پروفایل خود اضافه کنید.</string>
     <string name="auth_recaptcha_message">کارگزار می‌خواهد اطمینان یابد که شما ربات نیستید</string>
     <string name="auth_username_in_use">نام کاربری قبلاً استفاده شده است</string>
-    <string name="e2e_re_request_encryption_key"><u>دریافت کلیدهای رمزنگاری</u> از سایر دستگاه‌های شما.</string>
+    <string name="e2e_re_request_encryption_key"><u>بازدرخواست کلیدهای رمزنگاری</u> از دیگر نشست‌هایتان.</string>
 
     <string name="e2e_re_request_encryption_key_sent">درخواست کلید ارسال شد.</string>
 
     <string name="e2e_re_request_encryption_key_dialog_title">ارسال درخواست</string>
-    <string name="e2e_re_request_encryption_key_dialog_content">لطفاً برنامه را روی یکی از دستگاه‌های دیگرتان که به این پیام دسترسی داشته است، اجرا کنید تا کلیدها منتقل شوند.</string>
+    <string name="e2e_re_request_encryption_key_dialog_content">لطفاً ریوت را روی افزاره‌ای دیگر که می‌تواند پیام را رمزگشایی کند، اجرا کنید تا بتواند کلیدها را به این نشست بفرستد.</string>
 
-    <string name="read_receipts_list">مشاهده گیرندگان</string>
+    <string name="read_receipts_list">فهرست رسیدهای خواندن</string>
 
     <string name="keys_backup_setup_skip_title">آیا مطمئن هستید؟</string>
+    <string name="disconnect">عدم اتصال</string>
+    <string name="review">بررسی</string>
+    <string name="decline">رد کردن</string>
+
+    <string name="call_failed_dont_ask_again">دوباره از من نپرس</string>
+
+    <string name="auth_add_email_message_2">برای بازیابی یک ایمیل وارد کنید، و بعدا در صورت دلخواه می توانید از آن برای شناسایی دوستان خود استفاده کنید.</string>
+    <string name="auth_add_phone_message_2">ثبت شماره تلفن (بعدا در صورت دلخواه می توانید از آن برای شناسایی دوستان هود استفاده کنید).</string>
+    <string name="auth_reset_password_message">نشانی رایانامهٔ پیوسته به حسابتان را برای بازنشانی گذواژه‌تان وارد کنید:</string>
+    <string name="resources_script">Latn</string>
+
+    <string name="room_participants_invite_search_another_user">شناسهٔ کاربری، نام یا رایانامه</string>
+    <string name="room_message_placeholder_reply_to_encrypted">فرستادن پاسخی رمزشده…</string>
+    <string name="room_message_placeholder_reply_to_not_encrypted">فرستادن یک پاسخ (رمزنشده)…</string>
+    <string name="search_members_hint">پالایش اعضای اتاق</string>
+    <string name="tab_title_search_rooms">اتاق‌ها</string>
+    <string name="room_recents_conversations">اتاق‌ها</string>
+    <plurals name="directory_search_rooms">
+        <item quantity="one">۱ اتاق</item>
+        <item quantity="other">%d اتاق</item>
+    </plurals>
+    <plurals name="directory_search_rooms_for">
+        <item quantity="one">%1$s اتاق برای %2$s پیدا شد</item>
+        <item quantity="other">%1$s اتاق برای %2$s پیدا شد</item>
+    </plurals>
+    <string name="room_settings_direct_chat">گپ مستقیم</string>
+    <string name="room_sliding_menu_version">نگارش</string>
+    <string name="room_sliding_menu_version_x">نگارش %s</string>
+    <string name="room_sliding_menu_term_and_conditions">شرایط و ضوابط</string>
+    <string name="room_sliding_menu_third_party_notices">تذکّرهای سوم‌شخص</string>
+    <string name="room_sliding_menu_copyright">حق رونوشت</string>
+    <string name="room_sliding_menu_privacy_policy">سیاست محرمانگی</string>
+
+    <string name="settings_profile_picture">عکس نمایه</string>
+    <string name="settings_display_name">نام نمایشی</string>
+    <string name="settings_email_address">رایانامه</string>
+    <string name="settings_add_email_address">افزودن نشانی رایانامه</string>
+    <string name="settings_phone_number">تلفن</string>
+    <string name="settings_add_phone_number">افزودن شماره تلفن</string>
+    <string name="settings_app_info_link_title">اطّلاعات برنامه</string>
+    <string name="settings_app_info_link_summary">نمایش اطّلاعات برنامه در تنظیمات سامانه.</string>
+    <string name="settings_add_3pid_confirm_password_title">تأیید گذرواژه‌تان</string>
+    <string name="settings_add_3pid_flow_not_supported">نمی‌توانید این کار را از ریوت همراه انجام دهید</string>
+    <string name="settings_add_3pid_authentication_needed">نیاز به تأیید هویت است</string>
+
+
+    <string name="settings_notification_advanced">تنظمیات پیش‌رفتهٔ آگاهی</string>
+    <string name="settings_notification_troubleshoot">آگاهی‌های رفع‌اشکال</string>
+    <string name="settings_troubleshoot_test_system_settings_success">آگاهی‌ها در تنظیمات سامانه به کار افتاده‌اند.</string>
+    <string name="settings_troubleshoot_test_system_settings_failed">آگاهی‌ّا در تنظیمات سامانه از کار افتاده‌اند.
+\nلطفاً تنظیمات سامانه را بررسی کنید.</string>
+    <string name="settings_troubleshoot_test_account_settings_success">آگاهی‌ها برای حسابتان به کار افتاده‌اند.</string>
+    <string name="settings_troubleshoot_test_account_settings_failed">آگاهی‌ها برای حسابتان از کار افتاده‌اند.
+\nلطفاً تتظیمات حساب را بررسی کنید.</string>
+    <string name="settings_troubleshoot_test_device_settings_success">آگاهی‌ها برای این نشست به کار افتاده‌اند.</string>
+    <string name="settings_troubleshoot_test_device_settings_failed">آگاهی‌ها برای این نشست از کار افتاده‌اند.
+\nلطفاً تنظینات ریوت را بررسی کنید.</string>
+    <string name="settings_troubleshoot_test_bing_settings_failed">برخی آگاهی‌ها در تنظیمات سفارشیتان از کار افتاده‌اند.</string>
+    <string name="settings_troubleshoot_test_foreground_service_started_title">خدمت آگاهی</string>
+    <string name="settings_troubleshoot_test_foreground_service_startedt_success">خدمت آگاهی در حال اجراست.</string>
+    <string name="settings_troubleshoot_test_foreground_service_started_failed">خدمت آگاهی در حال اجرا نیست.
+\nتلاش کنید برنامه را دوباره شروع کنید.</string>
+    <string name="settings_troubleshoot_test_service_restart_title">شروع دوبارهٔ خودکار خدمت آگاهی</string>
+    <string name="settings_enable_all_notif">به کار انداختن أگاهی‌ها برای این حساب</string>
+    <string name="settings_enable_this_device">به کار انداختن أگاهی‌ها برای این نشست</string>
+    <string name="settings_noisy_notifications_preferences">پیکربندی أگاهی‌های پرصدا</string>
+    <string name="settings_call_notifications_preferences">پیکربندی أگاهی‌های تماس</string>
+    <string name="settings_silent_notifications_preferences">پیکربندی أگاهی‌های صامت</string>
+    <string name="settings_set_sync_delay">تأخیر بین همگام‌سازی‌ها</string>
+    <string name="settings_second">ثانیه</string>
+    <string name="settings_seconds">ثانیه</string>
+
+    <string name="settings_version">نگارش</string>
+    <string name="settings_olm_version">نگارش olm</string>
+    <string name="settings_app_term_conditions">شرایط و ضوابط</string>
+    <string name="settings_third_party_notices">تذکّرهای سوم‌شخص</string>
+    <string name="settings_copyright">حق رونوشت</string>
+    <string name="settings_privacy_policy">سیاست محرمانگی</string>
+    <string name="settings_keep_media">نگه‌داری رسانه</string>
+    <string name="settings_clear_cache">پاک‌سازی انباره</string>
+    <string name="settings_clear_media_cache">پاک‌سازی انبارهٔ رسانه</string>
+
+    <string name="settings_user_settings">تنظیمات کاربر</string>
+    <string name="settings_notifications">أگاهی‌ها</string>
+    <string name="settings_ignored_users">کاربران چشم‌پوشیده</string>
+    <string name="settings_other">دیگر</string>
+    <string name="settings_advanced">پیش‌رفته</string>
+    <string name="settings_integrations">یک‌پارچگی‌ها</string>
+    <string name="settings_cryptography">رمزنویسی</string>
+    <string name="settings_cryptography_manage_keys">مدیریت کلیدهای رمزنویسی</string>
+    <string name="settings_notifications_targets">هدف‌های آگاهی</string>
+    <string name="settings_contact">مخاطبان محلّی</string>
+    <string name="settings_contacts_app_permission">اجازهٔ مخاطبان</string>
+    <string name="settings_contacts_phonebook_country">کشور دفترچه تلفن</string>
+    <string name="settings_home_display">نمای حانه</string>
+    <string name="settings_pin_missed_notifications">سنجاق کردن اتاق‌هایی با آگاهی‌های بی‌پاسخ</string>
+    <string name="settings_pin_unread_messages">سنجاق کردن اتاق‌هایی با پیام‌های نخوانده</string>
+    <string name="settings_devices_list">نشست‌ها</string>
+    <string name="settings_inline_url_preview">پیش‌نمایش نشانی نامعتبر</string>
+    <string name="settings_send_typing_notifs">فرستادن آگاهی‌های نوشتن</string>
+    <string name="settings_send_markdown">قالب‌بندی مارک‌دون</string>
+    <string name="settings_show_read_receipts">نمایش رسیدهای خواندن</string>
+    <string name="settings_show_read_receipts_summary">برای یک فهرست باجزیییات، روی رسیدهای خواندن کلیک کنید.</string>
+    <string name="devices_delete_dialog_title">تأیید هویت</string>
+    <string name="devices_delete_pswd">گذرواژه:</string>
+    <string name="devices_delete_submit_button_label">ثبت</string>
+
+    <string name="settings_logged_in">واردشده به عنوان</string>
+    <string name="settings_home_server">کارساز خانگی</string>
+    <string name="settings_identity_server">کارساز هویت</string>
+    <string name="settings_integration_allow">اجازهٔ یک‌پارچگی‌ها</string>
+    <string name="settings_integration_manager">مدیر یکپارچگی</string>
+
+    <string name="settings_user_interface">رابط کاربری</string>
+    <string name="settings_interface_language">زبان</string>
+    <string name="settings_select_language">گزینش زبان</string>
+
+    <string name="settings_without_flair">هم‌اکنون عضو هیچ اجتماعی نیستید.</string>
+
+    <string name="room_settings_room_notifications_title">آگاهی‌ها</string>
+    <string name="room_settings_banned_users_title">کاربران مسدود</string>
+
+    <string name="room_settings_category_advanced_title">پیش‌رفته</string>
+    <string name="room_settings_room_internal_id">شناسهٔ داخلی این اتاق</string>
+    <string name="room_settings_addresses_pref_title">نشانی‌ها</string>
+    <string name="room_settings_labs_pref_title">آزمایشگاه‌ها</string>
+    <string name="room_settings_labs_end_to_end">رمزنگاری سرتاسری</string>
+    <string name="room_settings_labs_end_to_end_is_active">رمزنگاری سرتاسری فعّال است</string>
+    <string name="room_settings_labs_end_to_end_warnings">برای به کار انداختن رمزنگاری سرتاسری باید حارج شوید.</string>
+    <string name="room_settings_never_send_to_unverified_devices_title">رمزنگاری فقط به نشست‌های تأیید شده</string>
+    <string name="room_settings_add_new_group">شناسهٔ اجتماع جدید (مثلاً ‪+foo:matrix.org‬)</string>
+    <string name="room_settings_invalid_group_format_dialog_title">شناسهٔ اجتماع نامعتبر</string>
+    <string name="room_settings_invalid_group_format_dialog_body">%s یک شناسهٔ اجتماع معتبر نیست</string>
+
+
+    <string name="settings_theme">زمینه</string>
+
+    <string name="encryption_never_send_to_unverified_devices_title">رمزنگاری فقط به نشست‌های تأیید شده</string>
+    <string name="unknown_devices_alert_title">اتاق شامل نشست‌های ناشناخته</string>
+    <string name="directory_server_type_homeserver">برای فهرست شدن اتاق‌های عمومی از یک کاساز، نامش را بنویسید</string>
+    <string name="directory_server_all_rooms_on_server">تمامی اتاق‌های روی کارساز %s</string>
+    <string name="directory_server_native_rooms">تمامی اتاق‌های بومی %s</string>
+
+    <plurals name="notification_unread_notified_messages_in_room_rooms">
+        <item quantity="one">۱ اتاق</item>
+        <item quantity="other">%d اتاق</item>
+    </plurals>
+
+    <plurals name="notification_compat_summary_title">
+        <item quantity="one">%d آگاهی</item>
+        <item quantity="other">%d آگاهی</item>
+    </plurals>
+
+    <string name="room_widget_permission_theme">زمینه‌تان</string>
+    <string name="room_add_matrix_apps">افزودن کاره‌های ماتریس</string>
+    <string name="encrypted_message">پیام رمزنگاشته</string>
+
+    <string name="create_community">ایجاد اجتماع</string>
+    <string name="community_name">نام اجتماع</string>
+    <string name="community_id">شناسهٔ اجتماع</string>
+    <string name="group_details_rooms">اتاق‌ها</string>
+    <string name="rooms">اتاق‌ها</string>
+    <string name="filter_group_members">پالایش اعضای گروه</string>
+    <string name="filter_group_rooms">پالایش اتاق‌های گروهی</string>
+
+    <plurals name="group_rooms">
+        <item quantity="one">۱ اتاق</item>
+        <item quantity="other">%d اتاق</item>
+    </plurals>
+    <string name="group_no_long_description">مدیر اجتماع توضیحی بلند برای این اجتماع فراهم نکرده است.</string>
+
+    <string name="settings_lazy_loading_title">بار کردن تنبلانهٔ اعضای اتاق</string>
+    <string name="keys_backup_setup_step1_advanced">(پیش‌رفته)</string>
+    <string name="keys_backup_setup_step2_skip_button_title">(پیش‌رفته) برپایی با کلید بازیابی</string>
+    <string name="keys_backup_restore_is_getting_backup_version">گرفتن نگارش پشتیبان…</string>
+    <string name="keys_backup_get_version_error">شکست در گرفتن آخرین نگارش کلیدهای بازیابی (%s).</string>
+    <string name="keys_backup_info_title_version">نگارش</string>
+    <string name="edit">ویرایش</string>
+    <string name="reply">پاسخ</string>
+
+    <string name="global_retry">تلاش دوباره</string>
+    <string name="room_list_empty">برای آغاز استفاده از کاره، به اتاقی بپیوندید.</string>
+    <string name="send_you_invite">برایتان دعوتی فرستاد</string>
+    <string name="invited_by">دعوت‌شده به دست %s</string>
+
+    <string name="room_list_catchup_empty_title">همه‌چی سر جاشه!</string>
+    <string name="room_list_catchup_empty_body">هیچ پیام نخواندهٔ دیگری ندارید</string>
+    <string name="room_list_catchup_welcome_title">به خانه خوش آمدید!</string>
+    <string name="room_list_catchup_welcome_body">این‌جا به پیام‌های نخوانده برسید</string>
+    <string name="room_list_people_empty_title">گفت‌وگوها</string>
+    <string name="room_list_people_empty_body">گفت‌گوهای پیام مستقیمتان این‌جا نشان داده خواهند شد</string>
+    <string name="room_list_rooms_empty_title">اتاق‌ها</string>
+    <string name="room_list_rooms_empty_body">اتاق‌هایتان این‌جا نشان داده خواهند شد</string>
+
+    <string name="title_activity_emoji_reaction_picker">بازخودها</string>
+    <string name="reactions_agree">موافقت</string>
+    <string name="reactions_like">پسند</string>
+    <string name="message_add_reaction">افزودن بازخورد</string>
+    <string name="message_view_reaction">دیدن بازخوردها</string>
+    <string name="reactions">بازخوردها</string>
+
+    <string name="event_redacted_by_user_reason">رویداد به دست کاربر حذف شد</string>
+    <string name="event_redacted_by_admin_reason">رویداد به دست مدیر اتاق مدیریت شد</string>
+    <string name="last_edited_info_message">آخرین ویرایش به دست %1$s در %2$s</string>
+
+
+    <string name="malformed_message">رویداد بدشکل. نمی‌توان نمایش داد</string>
+    <string name="create_new_room">ایجاد اتاق جدید</string>
+    <string name="error_no_network">بدون شبکه. لطفاً اتّصال اینترنتیتان را بررسی کنید.</string>
+    <string name="action_change">تغییر</string>
+    <string name="change_room_directory_network">تغییر شبکه</string>
+    <string name="please_wait">لطفاً شکیبایی کنید…</string>
+    <string name="group_all_communities">تمام اجتماع‌ها</string>
+
+    <string name="room_preview_no_preview">این اتاق نمی‌تواند پیش‌نمایش یابد</string>
+    <string name="room_preview_world_readable_room_not_supported_yet">پیش‌نمایش اتاق‌های قابل خواندن به صورت عمومی هنوز در ریوت‌اکس پشتیبانی نمی‌شود</string>
+
+    <string name="fab_menu_create_room">اتاق‌ها</string>
+    <string name="fab_menu_create_chat">پیام‌های مستقیم</string>
+
+    <string name="create_room_title">اتاق جدید</string>
+    <string name="create_room_action_create">ایجاد</string>
+    <string name="create_room_name_hint">نام اتاق</string>
+    <string name="create_room_public_title">عمومی</string>
+    <string name="create_room_public_description">هرکسی می‌تواند به این اتاق بپیوندد</string>
+    <string name="create_room_directory_title">نمایهٔ اتاق‌ها</string>
+    <string name="create_room_directory_description">انتشار این اتاق در نمایهٔ اتاق‌ها</string>
+
+    <string name="settings_sdk_version">نگارش SDK ماتریس</string>
+    <string name="settings_general_title">عمومی</string>
+    <string name="settings_preferences">ترجیحات</string>
+    <string name="settings_security_and_privacy">امنیت و محرمانگی</string>
+    <string name="preference_voice_and_video">صدا و تصویر</string>
+    <string name="preference_root_help_about">راهنما و درباره</string>
+
+
+    <string name="send_suggestion">ارایهٔ پیشنهاد</string>
+    <string name="send_suggestion_content">لطفاً پیشنهادتان را در زیر بنویسید.</string>
+    <string name="send_suggestion_report_placeholder">پیشنهادتان را این‌جا شرح دهید</string>
+    <string name="send_suggestion_sent">ممنون. پیشنهاد با موفّقیت فرستاده شد</string>
+    <string name="send_suggestion_failed">فرستادن پیشنهاد شکست خورد (%s)</string>
+
+    <string name="settings_labs_show_hidden_events_in_timeline">نمایش رویدادهای نهفته در خط زمانی</string>
+
+    <string name="store_riotx_title">ریوت‌اکس - نسل بعدی کارخواه ماتریس</string>
+    <string name="bottom_action_people_x">پیام‌های مستقیم</string>
+
+    <string name="send_file_step_idle">منتظر…</string>
+    <string name="send_file_step_encrypting_thumbnail">رمزنگاری بندانگشتی‌ها…</string>
+    <string name="send_file_step_sending_thumbnail">فرستادن بندانگشتی‌ها (%1$s / %2$s)</string>
+    <string name="send_file_step_encrypting_file">رمزنگاری پرونده…</string>
+    <string name="send_file_step_sending_file">فرستادن پرونده (%1$s / %2$s)</string>
+
+    <string name="downloading_file">بارگری پرونده %1$s…</string>
+    <string name="downloaded_file">پرونده %1$s بارگیری شد!</string>
+
+    <string name="edited_suffix">(ویراسته)</string>
+
+    <string name="room_filtering_filter_hint">پالایش گفت‌وگوها…</string>
+    <string name="room_filtering_footer_create_new_room">ایجاد اتاقی جدید</string>
+    <string name="room_filtering_footer_create_new_direct_message">فرستادن یک پیام مستقیم جدید</string>
+    <string name="room_directory_search_hint">نام یا شناسه (‪#example:matrix.org‬)</string>
+
+    <string name="labs_swipe_to_reply_in_timeline">به کار انداختن کشیدن برای پاسخ در خط زمانی</string>
+
+    <string name="add_by_matrix_id">افزودن با شناسهٔ ماتریس</string>
+    <string name="direct_room_no_known_users">نتیجه‌ای پیدا نشد. برای جست‌وجو روی کارساز، از افزون با شناسهٔ ماتریس استفاده کنید.</string>
+    <string name="direct_room_filter_hint">پالایش با نام کاربری یا شناسه…</string>
+
+    <string name="a11y_create_direct_message">ایجاد یک گفت‌وگوی مستقیم جدید</string>
+    <string name="a11y_create_room">ایجاد اتاقی جدید</string>
+    <string name="report_content_spam">هرزنامه است</string>
+    <string name="report_content_inappropriate">نامناسب است</string>
+    <string name="report_content_custom">گزارش سفارشی…</string>
+    <string name="report_content_custom_title">گزارش این محتوا</string>
+    <string name="report_content_custom_hint">دلیل گزارش این محتوا</string>
+    <string name="report_content_custom_submit">گزارش</string>
+    <string name="block_user">انسداد کاربر</string>
+
+    <string name="content_reported_title">محتوا گزارش شد</string>
+    <string name="content_reported_as_spam_title">به عنوان هرزنامه گزارش شد</string>
+    <string name="content_reported_as_inappropriate_title">به عنوان نامناسب گزارش شد</string>
+    <string name="message_ignore_user">انسداد کاربر</string>
+
+    <string name="login_server_other_text">تنظیمات پیش‌رفته و سفارشی</string>
+
+    <string name="settings_show_devices_list">دیدن تمام نشست‌هایم</string>
+    <string name="settings_advanced_settings">تنظیمات پیش‌رفته</string>
+    <string name="settings_developer_mode">حالت توسعه‌دهنده</string>
+    <string name="settings_rageshake">تکان دادن</string>
+    <string name="rageshake_detected">تکان تشخیص داده شد!</string>
+    <string name="devices_other_devices">دیگر نشست‌ها</string>
+
+    <string name="room_profile_section_more_notifications">آگاهی‌ها</string>
+    <string name="room_list_sharing_header_recent_rooms">اتاق‌های اخیر</string>
+    <string name="room_list_sharing_header_other_rooms">دیگر اتاق‌ها</string>
+
+    <string name="settings_category_timeline">خط زمانی</string>
+
+    <string name="settings_category_composer">ویرایشگر پیام</string>
+
+    <string name="settings_active_sessions_list">نشست‌های فعّال</string>
+    <string name="settings_active_sessions_show_all">نمایش تمامی نشست‌ها</string>
+    <string name="settings_active_sessions_manage">مدیریت نشست‌ها</string>
+    <plurals name="settings_active_sessions_count">
+        <item quantity="one">%d نشست فعّال</item>
+        <item quantity="other">%d نشست فعّال</item>
+    </plurals>
+
+    <string name="room_member_profile_failed_to_get_devices">شکست در گرفتن نشست‌ها</string>
+    <string name="room_member_profile_sessions_section_title">نشست‌ها</string>
+    <string name="settings_dev_tools">ابزارهای توسعه</string>
 </resources>
diff --git a/vector/src/main/res/values-fi/strings.xml b/vector/src/main/res/values-fi/strings.xml
index fef747d546..d044bb5c1a 100644
--- a/vector/src/main/res/values-fi/strings.xml
+++ b/vector/src/main/res/values-fi/strings.xml
@@ -43,7 +43,7 @@
     <string name="missing_permissions_warning">Puuttuvien oikeuksien takia osa ominaisuuksista ei ole käytettävissä…</string>
     <string name="missing_permissions_to_start_conf_call">Sinulta puuttuu oikeus käynnistää ryhmäpuhelu tässä huoneessa</string>
     <string name="missing_permissions_title_to_start_conf_call">Puhelua ei voitu käynnistää</string>
-    <string name="device_information">Laitteen tiedot</string>
+    <string name="device_information">Istunnon tiedot</string>
     <string name="room_no_conference_call_in_encrypted_rooms">Ryhmäpuhelut eivät ole tuettuja salatuissa huoneissa</string>
     <string name="send_anyway">Lähetä silti</string>
     <string name="or">tai</string>
@@ -313,7 +313,7 @@
     <string name="room_participants_header_admin_tools">YLLÄPITÄJÄN TYÖKALUT</string>
     <string name="room_participants_header_call">PUHELUT</string>
     <string name="room_participants_header_direct_chats">YKSITYISKESKUSTELUT</string>
-    <string name="room_participants_header_devices">LAITTEET</string>
+    <string name="room_participants_header_devices">ISTUNNOT</string>
 
     <string name="room_participants_action_invite">Kutsu</string>
     <string name="room_participants_action_leave">Poistu huoneesta</string>
@@ -327,7 +327,7 @@
     <string name="room_participants_action_unignore">Näytä kaikki tämän käyttäjän viestit</string>
     <string name="room_participants_invite_search_another_user">Käyttäjätunnus, nimi tai sähköpostiosoite</string>
     <string name="room_participants_action_mention">Mainitse</string>
-    <string name="room_participants_action_devices_list">Näytä laitelista</string>
+    <string name="room_participants_action_devices_list">Näytä istuntolista</string>
     <string name="room_participants_power_level_prompt">Olet ylentämässä käyttäjää samalle tasolle kuin oma käyttäjätasosi. Et voi perua tätä toimintoa.\nOletko varma?</string>
 
     <string name="room_participants_invite_prompt_msg">Haluatko kutsua käyttäjän %s tähän keskusteluun\?</string>
@@ -350,7 +350,7 @@
     <string name="room_message_placeholder_not_encrypted">Lähetä viesti (salaamaton)…</string>
     <string name="room_offline_notification">Yhteys palvelimeen katkesi.</string>
     <string name="room_unsent_messages_notification">Viestejä ei lähetetty. %1$s vai %2$s\?</string>
-    <string name="room_unknown_devices_messages_notification">Viestejä ei lähetetty koska huoneessa on tuntemattomia laitteita. %1$s vai %2$s\?</string>
+    <string name="room_unknown_devices_messages_notification">Viestejä ei lähetetty, koska läsnä on tuntemattomia istuntoja. %1$s vai %2$s\?</string>
     <string name="room_prompt_resend">Lähetä kaikki uudelleen</string>
     <string name="room_prompt_cancel">Peruuta kaikki</string>
     <string name="room_resend_unsent_messages">Lähetä lähettämättömät viestit</string>
@@ -443,7 +443,7 @@
     <string name="settings_app_info_link_title">Sovelluksen tiedot</string>
 
     <string name="settings_enable_all_notif">Ota ilmoitukset käyttöön tällä tilillä</string>
-    <string name="settings_enable_this_device">Ota ilmoitukset käyttöön tällä laitteella</string>
+    <string name="settings_enable_this_device">Ota ilmoitukset käyttöön tässä istunnossa</string>
     <string name="settings_turn_screen_on">Näyttö päälle kolmeksi sekunniksi</string>
 
     <string name="settings_messages_in_one_to_one">Viestit yksityiskeskusteluissa</string>
@@ -482,8 +482,8 @@
     <string name="settings_home_display">Koti</string>
     <string name="settings_pin_missed_notifications">Kiinnitä huoneet, joissa on huomaamatta jääneitä ilmoituksia</string>
     <string name="settings_pin_unread_messages">Kiinnitä huoneet, joissa on lukemattomia viestejä</string>
-    <string name="settings_devices_list">Laitteet</string>
-    <string name="devices_details_dialog_title">Laitteen tiedot</string>
+    <string name="settings_devices_list">Istunnot</string>
+    <string name="devices_details_dialog_title">Istunnon tiedot</string>
     <string name="devices_details_id_title">ID</string>
     <string name="devices_details_name_title">Julkinen nimi</string>
     <string name="devices_details_device_name">Päivitä julkinen nimi</string>
@@ -618,11 +618,11 @@
     <string name="encryption_information_session_id">Sessio-ID</string>
     <string name="encryption_information_decryption_error">Salauksenpurkuvirhe</string>
 
-    <string name="encryption_information_sender_device_information">Lähettävän laitteen tiedot</string>
+    <string name="encryption_information_sender_device_information">Lähettäjän istunnon tiedot</string>
     <string name="encryption_information_device_name">Julkinen nimi</string>
     <string name="encryption_information_name">Julkinen nimi</string>
     <string name="encryption_information_device_id">Tunnus</string>
-    <string name="encryption_information_device_key">Laitteen avain</string>
+    <string name="encryption_information_device_key">Istunnon avain</string>
     <string name="encryption_information_verification">Vahvistus</string>
     <string name="encryption_information_ed25519_fingerprint">Ed25519-sormenjälki</string>
 
@@ -647,7 +647,7 @@
     <string name="encryption_information_verified">Vahvistettu</string>
     <string name="encryption_information_blocked">Kielletty</string>
 
-    <string name="encryption_information_unknown_device">tuntematon laite</string>
+    <string name="encryption_information_unknown_device">tuntematon istunto</string>
     <string name="encryption_information_none">ei mitään</string>
 
     <string name="encryption_information_verify">Vahvista</string>
@@ -665,7 +665,7 @@
 \nVoit tehdä sen nyt tai myöhemmin sovelluksen asetuksissa.</string>
 
     <!-- unknown devices management -->
-    <string name="unknown_devices_alert_title">Huoneessa on tuntemattomia laitteita</string>
+    <string name="unknown_devices_alert_title">Huoneessa on tuntemattomia istuntoja</string>
     <string name="unknown_devices_alert_message">Huoneessa on tuntemattomia laitteita joita ei ole vahvistettu.\nLaitteet eivät välttämättä kuulu väitetyille omistajilleen.\nJokainen uusi laite kannattaa vahvistaa ennen kuin jatkat, mutta voit myös lähettää viestit vahvistamattomille laitteille.\n\nTuntemattomat laitteet:</string>
 
     <!-- directory activity  -->
@@ -752,7 +752,7 @@
     <string name="settings_labs_native_camera">Käytä järjestelmän kamerasovellusta</string>
 
     <!-- share keys -->
-    <string name="you_added_a_new_device">Lisäsit uuden laitteen \'%s\', joka pyytää salausavaimia.</string>
+    <string name="you_added_a_new_device">Lisäsit uuden istunnon \'%s\', joka pyytää salausavaimia.</string>
     <string name="your_unverified_device_requesting">Vahvistamaton laitteesi \'%s\' pyytää salausavaimia.</string>
     <string name="start_verification">Aloita varmennus</string>
     <string name="share_without_verifying">Jaa ilman varmennusta</string>
@@ -890,7 +890,7 @@ Haluatko lisätä paketteja?</string>
     <string name="keys_backup_is_not_finished_please_wait">Avainten varmuuskopio ei ole valmis, odotathan hetken…</string>
     <string name="sign_out_bottom_sheet_warning_no_backup">Menetät salatut viestisi, jos kirjaudut ulos nyt</string>
     <string name="sign_out_bottom_sheet_warning_backing_up">Avainten varmuuskopio on meneillään. Jos kirjaudut ulos, menetät pääsyn salattuihin viesteihisi.</string>
-    <string name="sign_out_bottom_sheet_warning_backup_not_active">Turvallinen avainten varmuuskopio pitäisi olla käytössä kaikilla laitteillasi, jotta et menettäisi pääsyä salattuihin viesteihisi.</string>
+    <string name="sign_out_bottom_sheet_warning_backup_not_active">Turvallinen avainten varmuuskopio pitäisi olla käytössä kaikissa istunnoissasi, jotta et menettäisi pääsyä salattuihin viesteihisi.</string>
     <string name="sign_out_bottom_sheet_dont_want_secure_messages">En halua salattuja viestejäni</string>
     <string name="sign_out_bottom_sheet_backing_up_keys">Varmuuskopioidaan avaimia…</string>
     <string name="keys_backup_activate">Käytä avainten varmuuskopiointia</string>
@@ -913,12 +913,12 @@ Haluatko lisätä paketteja?</string>
     <string name="go_on_with">jatka sovelluksella…</string>
     <string name="error_no_external_application_found">Yhtään ulkopuolista sovellusta tämän toiminnon suorittamiseksi ei löytynyt.</string>
 
-    <string name="e2e_re_request_encryption_key"><u>Pyydä salausavaimia uudelleen</u> muilta laitteiltasi.</string>
+    <string name="e2e_re_request_encryption_key"><u>Pyydä salausavaimia uudelleen</u> muista istunnoistasi.</string>
 
     <string name="e2e_re_request_encryption_key_sent">Avainpyyntö lähetetty.</string>
 
     <string name="e2e_re_request_encryption_key_dialog_title">Pyyntö lähetetty</string>
-    <string name="e2e_re_request_encryption_key_dialog_content">Käynnistä Riot toisella laitteela, joka voi purkaa viestin, jotta se voi lähettää avaimet tähän laitteeseen.</string>
+    <string name="e2e_re_request_encryption_key_dialog_content">Käynnistä Riot toisella laitteella, joka voi purkaa viestin, jotta se voi lähettää avaimet tähän istuntoon.</string>
 
     <plurals name="membership_changes">
         <item quantity="one">yksi jäsenyysmuutos</item>
@@ -1018,9 +1018,9 @@ Haluatko lisätä paketteja?</string>
 \nTarkista tilisi asetukset.</string>
     <string name="settings_troubleshoot_test_account_settings_quickfix">Ota käyttöön</string>
 
-    <string name="settings_troubleshoot_test_device_settings_title">Laitteen asetukset.</string>
-    <string name="settings_troubleshoot_test_device_settings_success">Ilmoitukset ovat käytössä tällä laitteella.</string>
-    <string name="settings_troubleshoot_test_device_settings_failed">Ilmoituksia ei sallita tällä laitteella. 
+    <string name="settings_troubleshoot_test_device_settings_title">Istunnon asetukset.</string>
+    <string name="settings_troubleshoot_test_device_settings_success">Ilmoitukset ovat käytössä tässä istunnossa.</string>
+    <string name="settings_troubleshoot_test_device_settings_failed">Ilmoitukset eivät ole käytössä tässä istunnossa.
 \nTarkista Riotin asetukset.</string>
     <string name="settings_troubleshoot_test_device_settings_quickfix">Ota käyttöön</string>
 
@@ -1320,8 +1320,8 @@ Jotta et menetä mitään, automaattiset päivitykset kannattaa pitää käytös
         <item quantity="other">Varmuuskopio palautettiin %d avaimella.</item>
     </plurals>
     <plurals name="keys_backup_restore_success_description_part2">
-        <item quantity="one">yksi uusi avain lisätty tähän laitteeseen.</item>
-        <item quantity="other">%d uutta avainta lisätty tähän laitteeseen.</item>
+        <item quantity="one">Yksi uusi avain lisätty tähän istuntoon.</item>
+        <item quantity="other">%d uutta avainta lisätty tähän listuntoon.</item>
     </plurals>
 
     <string name="keys_backup_get_version_error">Uusimman palautusavaimen version hakeminen epäonnistui (%s).</string>
@@ -1332,11 +1332,11 @@ Jotta et menetä mitään, automaattiset päivitykset kannattaa pitää käytös
     <string name="keys_backup_settings_delete_backup_button">Poista varmuuskopio</string>
 
     <string name="keys_backup_settings_status_ok">Avaimien varmuuskopiointi on käytössä tällä laitteella.</string>
-    <string name="keys_backup_settings_status_ko">Avaimien varmuuskopiointi ei ole käytössä tällä laitteella.</string>
-    <string name="keys_backup_settings_status_not_setup">Avaimiasi ei varmuuskopioida tältä laitteelta.</string>
+    <string name="keys_backup_settings_status_ko">Avaimien varmuuskopiointi ei ole käytössä tässä istunnossa.</string>
+    <string name="keys_backup_settings_status_not_setup">Avaimiasi ei varmuuskopioida tästä istunnosta.</string>
 
     <string name="keys_backup_settings_signature_from_unknown_device">Varmuuskopiossa on allekirjoitus tuntemattomasta laitteesta ID:llä %s.</string>
-    <string name="keys_backup_settings_valid_signature_from_this_device">Varmuuskopiossa on pätevä allekirjoitus tältä laitteelta.</string>
+    <string name="keys_backup_settings_valid_signature_from_this_device">Varmuuskopiossa on pätevä allekirjoitus tästä istunnosta.</string>
     <string name="keys_backup_settings_valid_signature_from_verified_device">Varmuuskopiossa on pätevä allekirjoitus varmennetulta laitteelta %s.</string>
     <string name="keys_backup_settings_valid_signature_from_unverified_device">Varmuuskopiossa on pätevä allekirjoitus varmentamattomalta laitteelta %s</string>
     <string name="keys_backup_settings_invalid_signature_from_verified_device">Varmuuskopiossa on epäkelpo allekirjoitus varmennetulta laitteelta %s</string>
@@ -1451,21 +1451,21 @@ Jotta et menetä mitään, automaattiset päivitykset kannattaa pitää käytös
     <string name="sas_got_it">Selvä</string>
 
     <string name="sas_cancelled_dialog_title">Pyyntö peruttu</string>
-    <string name="sas_error_m_unexpected_message">Laite vastaanotti odottamattoman viestin</string>
+    <string name="sas_error_m_unexpected_message">Istunto vastaanotti odottamattoman viestin</string>
     <string name="sas_error_m_invalid_message">Virheellinen viesti vastaanotettu</string>
     <string name="sas_error_m_key_mismatch">Avain ei täsmää</string>
     <string name="sas_error_m_user_error">Käyttäjä ei täsmää</string>
     <string name="sas_error_unknown">Tuntematon virhe</string>
 
     <string name="keys_backup_setup_override_backup_prompt_tile">Kotipalvelimellasi on jo varmuuskopio</string>
-    <string name="keys_backup_setup_override_backup_prompt_description">Näyttää, että olet jo asettanut avainten varmuuskopioinnin toiselta laitteelta. Halutatko korvata sen tällä\?</string>
+    <string name="keys_backup_setup_override_backup_prompt_description">Näyttää, että olet jo asettanut avainten varmuuskopioinnin toisesta istunnosta. Halutatko korvata sen tällä\?</string>
     <string name="keys_backup_setup_override_replace">Korvaa</string>
     <string name="keys_backup_setup_override_stop">Seis</string>
 
     <string name="keys_backup_settings_checking_backup_state">Tarkistetaan varmuuskopion tilaa</string>
     <string name="sas_waiting_for_partner">Odotetaan vastapuolen varmistusta…</string>
 
-    <string name="sas_error_m_unknown_transaction">Laite ei ole tietoinen kyseisestä transaktiosta</string>
+    <string name="sas_error_m_unknown_transaction">Istunto ei ole tietoinen kyseisestä transaktiosta</string>
     <string name="sas_error_m_mismatched_sas">SAS ei täsmännyt</string>
     <string name="edit">Muokkaa</string>
     <string name="reply">Vastaa</string>
@@ -1577,7 +1577,7 @@ Jotta et menetä mitään, automaattiset päivitykset kannattaa pitää käytös
 
     <string name="message_view_edit_history">Näytä muokkaushistoria</string>
 
-    <string name="title_activity_verify_device">Vahvista laite</string>
+    <string name="title_activity_verify_device">Vahvista istunto</string>
 
     <string name="start_verification_short_label">Vahvista</string>
     <string name="key_share_request">Avaimen jakopyyntö</string>
@@ -1624,7 +1624,7 @@ Jotta et menetä mitään, automaattiset päivitykset kannattaa pitää käytös
     <string name="settings_set_workmanager_delay_summary">%s
 \nSynkronointia saatetaan lykätä resursseista (akusta) tai laitteen tilasta (virransäästö) riippuen.</string>
     <string name="encryption_information_device_name_with_warning">Julkinen nimi (näkyy ihmisille, joihin olet yhteydessä)</string>
-    <string name="device_name_warning">Laitteen julkinen nimi näkyy ihmisille, joihin olet yhteydessä</string>
+    <string name="device_name_warning">Istunnon julkinen nimi näkyy ihmisille, joihin olet yhteydessä</string>
     <string name="widget_integration_review_terms">Jatkaaksesi sinun täytyy hyväksyä palvelun käyttöehdot.</string>
 
     <string name="identity_server_not_defined">Et käytä identiteettipalvelinta</string>
@@ -2026,4 +2026,53 @@ Jotta et menetä mitään, automaattiset päivitykset kannattaa pitää käytös
 \n
 \n• palvelimen ylläpitäjä on estänyt pääsysi turvallisuussyistä.</string>
     <string name="soft_logout_signin_e2e_warning_notice">Kirjaudu sisään palauttaaksesi salausavaimesi, jotka ovat tallessa vain tällä laitteella. Tarvitset niitä lukeaksi kaikki salatut viestisi millä tahansa laitteella.</string>
+    <string name="settings_show_devices_list">Näytä kaikki istuntoni</string>
+    <string name="settings_advanced_settings">Lisäasetukset</string>
+    <string name="settings">Asetukset</string>
+    <string name="devices_current_device">Nykyinen istunto</string>
+    <string name="devices_other_devices">Muut istunnot</string>
+
+    <string name="create_room_encryption_title">Ota salaus käyttöön</string>
+    <string name="create_room_encryption_description">Salausta ei voi poistaa käytöstä, kun se on kerran otettu käyttöön.</string>
+
+    <string name="verification_request_waiting">Odotetaan…</string>
+    <string name="verification_request_other_cancelled">%s peruutti</string>
+    <string name="verification_request_you_cancelled">Sinä peruutit</string>
+    <string name="verification_request_other_accepted">%s hyväksyi</string>
+    <string name="verification_request_you_accepted">Sinä hyväksyit</string>
+    <string name="you">Sinä</string>
+
+    <string name="room_profile_section_security_learn_more">Lue lisää</string>
+    <string name="room_profile_section_more_notifications">Ilmoitukset</string>
+    <plurals name="room_profile_section_more_member_list">
+        <item quantity="one">Yksi henkilö</item>
+        <item quantity="other">%1$d ihmistä</item>
+    </plurals>
+    <string name="room_profile_section_more_leave">Poistu huoneesta</string>
+    <string name="room_profile_leaving_room">Poistutaan huoneesta…</string>
+
+    <string name="login_signup_username_hint">Käyttäjätunnus</string>
+    <string name="notification_initial_sync">Synkronoidaan tietoja ensimmäistä kertaa…</string>
+
+    <string name="settings_developer_mode">Kehittäjämoodi</string>
+    <string name="settings_developer_mode_summary">Kehittäjämoodi aktivoi piilotettuja ominaisuuksia, mutta voi tehdä sovelluksesta epävakaan. Vain kehittäjille!</string>
+    <string name="settings_rageshake">Raivoravistus</string>
+    <string name="settings_rageshake_detection_threshold">Tunnistusraja</string>
+    <string name="settings_rageshake_detection_threshold_summary">Ravista puhelintasi testataksesi tunnistusrajan</string>
+    <string name="rageshake_detected">Ravistus tunnistettu!</string>
+    <string name="autocomplete_limited_results">Näytetään vain ensimmäiset tulokset, kirjoita lisää kirjaimia…</string>
+
+    <string name="settings_developer_mode_fail_fast_summary">RiotX voi kaatuilla tavallista useammin odottamattomien virheiden vuoksi</string>
+
+    <string name="command_description_shrug">Lisää ¯\\_(ツ)_/¯ tavallisen viestin alkuun</string>
+
+    <string name="login_error_threepid_denied">Käyttämäsi sähköpostipalvelun ei ole sallittu rekisteröityä tälle palvelimelle</string>
+
+    <string name="verification_sas_match">Täsmäävät</string>
+    <string name="verification_sas_do_not_match">Eivät täsmää</string>
+    <string name="verify_user_sas_emoji_help_text">Vahvista käyttäjä tarkastamalla että seuraavat emojit vastaavat täysin heidän ruudullaan näkyviä.</string>
+    <string name="verify_user_sas_emoji_security_tip">Jos haluat kovaa tietoturvaa, käytä jotain toista luotettavaa viestintävälinettä tai tee toisen henkilön ollessa paikalla.</string>
+    <string name="verification_conclusion_not_secure">Ei turvallinen</string>
+    <string name="sent_a_video">Video.</string>
+    <string name="sent_an_image">Kuva.</string>
 </resources>
diff --git a/vector/src/main/res/values-fr/strings.xml b/vector/src/main/res/values-fr/strings.xml
index 76e2a0d0a7..190d781f2a 100644
--- a/vector/src/main/res/values-fr/strings.xml
+++ b/vector/src/main/res/values-fr/strings.xml
@@ -145,7 +145,7 @@
     <string name="login_error_not_json">Ne contient pas de JSON valide</string>
     <string name="read_receipts_list">Liste des accusés de lecture</string>
 
-    <string name="compression_options">"Envoyer en "</string>
+    <string name="compression_options">Envoyer en</string>
     <string name="compression_opt_list_original">Original</string>
     <string name="compression_opt_list_large">Grand</string>
     <string name="compression_opt_list_medium">Moyen</string>
@@ -287,7 +287,7 @@
     <string name="settings_enable_this_device">Activer les notifications pour cette session</string>
     <string name="settings_messages_in_one_to_one">Messages dans les discussions directes</string>
     <string name="settings_messages_in_group_chat">Messages dans les discussions de groupe</string>
-    <string name="settings_call_invitations">Demandes d’appel</string>
+    <string name="settings_call_invitations">Appels entrants</string>
     <string name="settings_messages_sent_by_bot">Messages envoyés par un robot</string>
 
     <string name="settings_background_sync">Synchronisation en arrière-plan</string>
@@ -407,7 +407,7 @@
     <string name="encryption_import_room_keys">Importer les clés des salons</string>
     <string name="encryption_import_import">Importer</string>
     <string name="encryption_never_send_to_unverified_devices_title">Chiffrer uniquement vers les sessions vérifiées</string>
-    <string name="encryption_information_not_verified">NON vérifié</string>
+    <string name="encryption_information_not_verified">Non vérifié</string>
     <string name="encryption_information_verified">Vérifié</string>
     <string name="encryption_information_blocked">Sur liste noire</string>
 
@@ -473,7 +473,7 @@
 
     <string name="attachment_cancel_upload">Annuler l’envoi ?</string>
     <string name="attachment_remaining_time_seconds">%d s</string>
-    <string name="attachment_remaining_time_minutes">%1$dm %2$ds</string>
+    <string name="attachment_remaining_time_minutes">%1$d min %2$d s</string>
 
     <string name="leave">Quitter</string>
     <string name="quote">Citer</string>
@@ -484,13 +484,13 @@
 
 Veuillez autoriser l’accès dans la prochaine fenêtre contextuelle pour pouvoir envoyer des fichiers depuis votre téléphone.</string>
     <string name="permissions_rationale_msg_camera">Riot a besoin d’accéder à votre appareil photo pour prendre des photos et passer des appels vidéo.</string>
-    <string name="permissions_rationale_msg_camera_explanation">
-
-Veuillez autoriser l’accès dans la prochaine fenêtre contextuelle pour pouvoir effectuer l’appel.</string>
+    <string name="permissions_rationale_msg_camera_explanation">"
+\n
+\nVeuillez autoriser l’accès dans la prochaine fenêtre contextuelle pour pouvoir effectuer l’appel."</string>
     <string name="permissions_rationale_msg_record_audio">Riot a besoin d’accéder à votre microphone pour passer des appels audio.</string>
-    <string name="permissions_rationale_msg_record_audio_explanation">
-
-Veuillez autoriser l’accès dans la prochaine fenêtre contextuelle pour pouvoir effectuer l’appel.</string>
+    <string name="permissions_rationale_msg_record_audio_explanation">"
+\n
+\nVeuillez autoriser l’accès dans la prochaine fenêtre contextuelle pour pouvoir effectuer l’appel."</string>
     <string name="permissions_rationale_msg_camera_and_audio">Riot a besoin d’accéder à votre appareil photo et à votre microphone pour passer des appels vidéo.
 
 Veuillez autoriser l’accès dans les prochaines fenêtres contextuelles pour pouvoir effectuer l’appel.</string>
@@ -602,8 +602,8 @@ Attention : ce fichier peut être supprimé si l’application est désinstallé
     <string name="encryption_import_room_keys_summary">Importer les clés à partir d’un fichier local</string>
     <string name="encryption_never_send_to_unverified_devices_summary">Ne jamais envoyer de messages chiffrés aux sessions non vérifiées depuis cette session.</string>
 
-    <string name="encryption_information_verify_device_warning">Pour vérifier que cette session est fiable, contactez son propriétaire en utilisant un autre moyen (par ex. en personne ou par téléphone) et demandez-lui si la clé qu’il voit dans ses paramètres utilisateur pour cette session correspond à la clé ci-dessous :</string>
-    <string name="encryption_information_verify_device_warning2">Si elle correspond, appuyez sur le bouton « Vérifier » ci-dessous. Si ce n’est pas le cas, quelqu’un d’autre intercepte cette session et vous devriez probablement le bloquer. À l’avenir, ce processus de vérification sera plus évolué.</string>
+    <string name="encryption_information_verify_device_warning">Confirmez en comparant les informations suivantes avec les paramètres utilisateur dans votre autre session :</string>
+    <string name="encryption_information_verify_device_warning2">Si elles ne correspondent pas, la sécurité de votre communication est peut-être compromise.</string>
     <string name="encryption_information_verify_key_match">Je confirme que les clés correspondent</string>
 
     <string name="e2e_enabling_on_app_update">Riot prend désormais en charge le chiffrement de bout en bout, mais vous devez vous reconnecter pour l’activer.
@@ -875,11 +875,11 @@ Voulez-vous en ajouter ?</string>
     <string name="dialog_user_consent_submit">Voir maintenant</string>
 
     <string name="deactivate_account_title">Désactiver le compte</string>
-    <string name="deactivate_account_content">Votre compte sera inutilisable de façon permanente. Vous ne pourrez plus vous connecter et personne ne pourra se réenregistrer avec le même identifiant d’utilisateur. Le compte quittera tous les salons auxquels il participe et tous ses détails seront supprimés du serveur d’identité. <b>Cette action est irréversible. </b>
-
-Désactiver votre compte <b>ne nous fait pas oublier les messages que vous avez envoyés par défaut</b>. Si vous souhaitez que nous oubliions vos messages, cochez la case ci-dessous.
-
-La visibilité des messages dans Matrix est identique à celle des e-mails. Si nous oublions vos messages, cela signifie que les messages que vous avez envoyés ne seront plus partagés avec les nouveaux utilisateurs ou les utilisateurs non enregistrés, mais les utilisateurs enregistrés qui ont déjà accès à ces messages en conserveront leur copie.</string>
+    <string name="deactivate_account_content">\"Votre compte sera inutilisable de façon permanente. Vous ne pourrez plus vous connecter et personne ne pourra se réenregistrer avec le même identifiant d’utilisateur. Le compte quittera tous les salons auxquels il participe et tous ses détails seront supprimés du serveur d’identité. <b>Cette action est irréversible.</b>
+\n
+\nDésactiver votre compte <b>ne nous fait pas oublier les messages que vous avez envoyés par défaut</b>. Si vous souhaitez que nous oubliions vos messages, cochez la case ci-dessous.
+\n
+\nLa visibilité des messages dans Matrix est identique à celle des e-mails. Si nous oublions vos messages, cela signifie que les messages que vous avez envoyés ne seront plus partagés avec les nouveaux utilisateurs ou les utilisateurs non enregistrés, mais les utilisateurs enregistrés qui ont déjà accès à ces messages en conserveront leur copie.\"</string>
     <string name="deactivate_account_delete_checkbox">Veuillez oublier tous les messages que j’ai envoyé quand mon compte sera désactivé (Avertissement : les futurs utilisateurs verront une version incomplète des conversations)</string>
     <string name="deactivate_account_prompt_password">Pour continuer, veuillez renseigner votre mot de passe :</string>
     <string name="deactivate_account_submit">Désactiver le compte</string>
@@ -889,7 +889,7 @@ La visibilité des messages dans Matrix est identique à celle des e-mails. Si n
     <string name="download">Télécharger</string>
     <string name="speak">Parler</string>
     <string name="clear">Effacer</string>
-    <string name="e2e_re_request_encryption_key"><u>Redemander les clés de chiffrement</u> à vos autres sessions.</string>
+    <string name="e2e_re_request_encryption_key">Redemander les clés de chiffrement à vos autres sessions.</string>
 
     <string name="e2e_re_request_encryption_key_sent">Demande de clé envoyée.</string>
 
@@ -1060,7 +1060,7 @@ Veuillez noter que cette action redémarrera l’application et pourra prendre u
     <string name="settings_troubleshoot_diagnostic">Diagnostics de résolution de problème</string>
     <string name="settings_troubleshoot_diagnostic_run_button_title">Lancer les tests</string>
     <string name="settings_troubleshoot_diagnostic_running_status">"Exécution…  (%1$d sur %2$d)"</string>
-    <string name="settings_troubleshoot_diagnostic_success_status">Le diagnostic de base est passé. Si vous ne recevez toujours pas de notifications, veuillez envoyer un rapport d’anomalie pour nous aider à résoudre le problème.</string>
+    <string name="settings_troubleshoot_diagnostic_success_status">Le diagnostic de base est passé. Si vous ne recevez toujours pas de notifications, envoyez un rapport d’anomalie pour nous aider à résoudre le problème.</string>
     <string name="settings_troubleshoot_diagnostic_failure_status_with_quickfix">Au moins un test a échoué, essayez les solutions suggérées.</string>
     <string name="settings_troubleshoot_diagnostic_failure_status_no_quickfix">Au moins un test a échoué, veuillez envoyer un rapport d’anomalie pour nous aider à résoudre le problème.</string>
 
@@ -1325,7 +1325,7 @@ Conservez votre clé de récupération en lieu sûr, comme un gestionnaire de mo
     <string name="keys_backup_banner_recover_line1">Ne perdez jamais vos messages chiffrés</string>
     <string name="keys_backup_banner_recover_line2">Utiliser la sauvegarde de clés</string>
 
-    <string name="keys_backup_banner_update_line1">Nouvelles clés de messages chiffrés</string>
+    <string name="keys_backup_banner_update_line1">Nouvelles clés de message sécurisé</string>
     <string name="keys_backup_banner_update_line2">Gérer la sauvegarde de clés</string>
 
     <string name="keys_backup_banner_in_progress">Sauvegarde de clés…</string>
@@ -2087,8 +2087,8 @@ Si vous n’avez pas configuré de nouvelle méthode de récupération, un attaq
 
     <string name="room_member_jump_to_read_receipt">Aller à l’accusé de lecture</string>
 
-    <string name="rendering_event_error_type_of_event_not_handled">RiotX ne gère pas (encore) les évènements de type « %1$s »</string>
-    <string name="rendering_event_error_type_of_message_not_handled">RiotX ne gère pas (encore) les messages de type « %1$s »</string>
+    <string name="rendering_event_error_type_of_event_not_handled">RiotX ne gère pas les évènements de type « %1$s »</string>
+    <string name="rendering_event_error_type_of_message_not_handled">RiotX ne gère pas les messages de type « %1$s »</string>
     <string name="rendering_event_error_exception">RiotX a rencontré un problème lors de l’affichage du contenu de l’évènement ayant pour identifiant « %1$s »</string>
 
     <string name="unignore">Ne plus ignorer</string>
@@ -2136,7 +2136,7 @@ Si vous n’avez pas configuré de nouvelle méthode de récupération, un attaq
     <string name="settings_active_sessions_list">Sessions actives</string>
     <string name="settings_active_sessions_show_all">Afficher toutes les sessions</string>
     <string name="settings_active_sessions_manage">Gérer les sessions</string>
-    <string name="settings_active_sessions_signout_device">Déconnecter cette session</string>
+    <string name="settings_active_sessions_signout_device">Se déconnecter de cette session</string>
 
     <string name="settings_failed_to_get_crypto_device_info">Aucune information cryptographique n’est disponible</string>
 
@@ -2152,7 +2152,7 @@ Si vous n’avez pas configuré de nouvelle méthode de récupération, un attaq
     <string name="crosssigning_other_user_not_trust">Les autres utilisateurs ne lui font peut-être pas confiance</string>
     <string name="complete_security">Compléter la sécurité</string>
 
-    <string name="verification_open_other_to_verify">Ouvrez une session existante et utilisez-la pour vérifier celle-ci, pour lui permettre d’accéder aux messages chiffrés. Si vous ne pouvez pas le faire, utilisez votre clé de récupération ou votre phrase secrète.</string>
+    <string name="verification_open_other_to_verify">Utilisez une session existante pour vérifier celle-ci, ce qui lui permettra d’avoir accès aux messages chiffrés.</string>
 
 
     <string name="verification_profile_verify">Vérifier</string>
@@ -2174,8 +2174,223 @@ Si vous n’avez pas configuré de nouvelle méthode de récupération, un attaq
 
     <string name="a11y_qr_code_for_verification">Code QR</string>
 
+    <string name="qr_code_scanned_by_other_notice">On y est presque ! Est-ce que %s affiche le même bouclier \?</string>
     <string name="qr_code_scanned_by_other_yes">Oui</string>
     <string name="qr_code_scanned_by_other_no">Non</string>
 
     <string name="no_connectivity_to_the_server_indicator">La connectivité avec le serveur a été perdue</string>
+    <string name="login_signup_username_hint">Nom d’utilisateur</string>
+    <string name="settings_dev_tools">Outils de développement</string>
+    <string name="settings_account_data">Données du compte</string>
+    <plurals name="poll_info">
+        <item quantity="one">%d vote</item>
+        <item quantity="other">%d votes</item>
+    </plurals>
+    <plurals name="poll_info_final">
+        <item quantity="one">%d vote − Résultats finaux</item>
+        <item quantity="other">%d votes − Résultats finaux</item>
+    </plurals>
+    <string name="poll_item_selected_aria">Option sélectionnée</string>
+    <string name="command_description_poll">Crée un sondage simple</string>
+    <string name="verification_cannot_access_other_session">Utiliser une phrase secrète ou une clé de récupération</string>
+    <string name="verification_use_passphrase">Si vous n’avez pas accès à une session existante</string>
+
+    <string name="new_signin">Nouvelle connexion</string>
+
+    <string name="enter_secret_storage_invalid">Impossible de trouver les secrets dans le stockage</string>
+    <string name="enter_secret_storage_passphrase">Saisir la phrase secrète du coffre secret</string>
+    <string name="enter_secret_storage_passphrase_warning">Attention :</string>
+    <string name="enter_secret_storage_passphrase_warning_text">Vous devriez accéder à votre coffre secret uniquement depuis un appareil de confiance</string>
+
+    <string name="message_action_item_redact">Supprimer…</string>
+    <string name="share_confirm_room">Voulez-vous envoyer cette pièce jointe à %1$s \?</string>
+    <plurals name="send_images_with_original_size">
+        <item quantity="one">Envoyer l’image en taille originale</item>
+        <item quantity="other">Envoyer les images en taille originale</item>
+    </plurals>
+
+    <string name="delete_event_dialog_title">Confirmer la suppression</string>
+    <string name="delete_event_dialog_content">Voulez-vous vraiment supprimer cet évènement \? Notez que si vous supprimez un changement de nom ou de sujet du salon, cela pourrait annuler le changement.</string>
+    <string name="delete_event_dialog_reason_checkbox">Fournir un motif</string>
+    <string name="delete_event_dialog_reason_hint">Motif de la suppression</string>
+
+    <string name="event_redacted_by_user_reason_with_reason">Évènement supprimé par l’utilisateur, motif : %1$s</string>
+    <string name="event_redacted_by_admin_reason_with_reason">Évènement modéré par l’administrateur du salon, motif : %1$s</string>
+
+    <string name="keys_backup_restore_success_title_already_up_to_date">Les clés sont déjà à jour !</string>
+
+    <string name="login_mobile_device_riotx">RiotX Android</string>
+
+    <string name="settings_key_requests">Demandes de clé</string>
+
+    <string name="e2e_use_keybackup">Déverrouiller l’historique des messages chiffrés</string>
+
+    <string name="refresh">Actualiser</string>
+
+    <string name="new_session">Nouvelle connexion. Était-ce vous \?</string>
+    <string name="new_session_review">Appuyer pour examiner et vérifier</string>
+    <string name="verify_new_session_notice">Utilisez cette session pour vérifiez la nouvelle, ce qui lui permettra d’avoir accès aux messages chiffrés.</string>
+    <string name="verify_new_session_was_not_me">Ce n’était pas moi</string>
+    <string name="verify_new_session_compromized">Votre compte est peut-être compromis</string>
+
+    <string name="verify_cancel_self_verification_from_untrusted">Si vous annulez, vous ne pourrez pas lire les messages chiffrés sur cet appareil, et les autres utilisateurs ne lui feront pas confiance</string>
+    <string name="verify_cancel_self_verification_from_trusted">Si vous annulez, vous ne pourrez pas lire les messages chiffrés sur votre nouvel appareil, et les autres utilisateurs ne lui feront pas confiance</string>
+    <string name="verify_cancel_other">Vous ne vérifierez pas %1$s (%2$s) si vous annulez maintenant. Recommencez sur son profil utilisateur.</string>
+
+    <string name="verify_not_me_self_verification">Un des éléments suivants est peut-être compromis :
+\n
+\n- Votre mot de passe
+\n- Votre serveur d’accueil
+\n- Cet appareil ou l’autre appareil
+\n- La connexion internet utilisée par un des deux appareils
+\n
+\nNous vous recommandons de modifier immédiatement votre mot de passe et votre clé de récupération dans les paramètres.</string>
+
+    <string name="verify_cancelled_notice">Vérifiez vos appareils depuis les paramètres.</string>
+    <string name="verification_cancelled">Vérification annulée</string>
+
+    <string name="recovery_passphrase">Phrase de récupération</string>
+    <string name="message_key">clé des messages</string>
+    <string name="account_password">Mot de passe du compte</string>
+
+    <string name="set_recovery_passphrase">Définissez un %s</string>
+    <string name="generate_message_key">Générez une clé de messages</string>
+
+    <string name="confirm_recovery_passphrase">Confirmez le %s</string>
+
+    <string name="enter_account_password">Saisissez votre %s pour continuer.</string>
+
+    <string name="bootstrap_info_text">Sécurisez et débloquez vos messages chiffrés et vos vérifications avec un %s.</string>
+    <string name="bootstrap_info_confirm_text">Saisissez à nouveau votre %s pour le confirmer.</string>
+    <string name="bootstrap_dont_reuse_pwd">Ne réutilisez pas votre mot de passe de compte.</string>
+
+
+    <string name="bootstrap_loading_text">Cela peut prendre plusieurs secondes, veuillez patienter.</string>
+    <string name="bootstrap_loading_title">Configuration de la récupération.</string>
+    <string name="your_recovery_key">Votre clé de récupération</string>
+    <string name="bootstrap_finish_title">Vous avez terminé !</string>
+    <string name="keep_it_safe">Conservez-le en lieu sûr</string>
+    <string name="finish">Terminer</string>
+
+    <string name="bootstrap_save_key_description">Utilisez cette %1$s comme filet de sécurité au cas où vous oublieriez votre %2$s.</string>
+
+    <string name="bootstrap_crosssigning_progress_initializing">Publication des clés d’identité créées</string>
+    <string name="bootstrap_crosssigning_progress_pbkdf2">Génération d’une clé sécurisée depuis la phrase secrète</string>
+    <string name="bootstrap_crosssigning_progress_default_key">Définition de la clé par défaut du SSSS</string>
+    <string name="bootstrap_crosssigning_progress_save_msk">Synchronisation de la clé maîtresse</string>
+    <string name="bootstrap_crosssigning_progress_save_usk">Synchronisation de la clé de l’utilisateur</string>
+    <string name="bootstrap_crosssigning_progress_save_ssk">Synchronisation de la clé d’auto-signature</string>
+    <string name="bootstrap_crosssigning_progress_key_backup">Configuration de la sauvegarde de clés</string>
+
+
+    <string name="bootstrap_cross_signing_success">Votre %2$s et votre %1$s sont bien réglés.
+\n
+\nConservez-les en lieu sûr ! Vous en aurez besoin pour débloquer les messages chiffrés et vos informations sécurisées si vous perdez toutes vos sessions actives.</string>
+
+    <string name="bootstrap_crosssigning_print_it">Imprimez-le et conservez-le en lieu sûr</string>
+    <string name="bootstrap_crosssigning_save_usb">Sauvegardez-le sur une clé USB ou un disque de sauvegarde</string>
+    <string name="bootstrap_crosssigning_save_cloud">Copiez-le sur votre stockage dans le cloud personnel</string>
+
+    <string name="auth_flow_not_supported">Vous ne pouvez pas faire ça depuis votre portable</string>
+
+    <string name="bootstrap_skip_text">La configuration d’un mot de passe de messages vous permet des sécuriser et déverrouiller les messages chiffrés et les vérifications.
+\n
+\nSi vous ne voulez pas définir un mot de passe de messages, générez plutôt une clé de messages.</string>
+    <string name="bootstrap_skip_text_no_gen_key">La configuration d’une Phrase de récupération vous permet des sécuriser et déverrouiller les messages chiffrés et les vérifications.</string>
+
+
+    <string name="encryption_enabled">Chiffrement activé</string>
+    <string name="encryption_enabled_tile_description">Les messages de ce salon sont chiffrés de bout en bout. Apprenez-en plus et vérifiez les utilisateurs sur leur profil.</string>
+    <string name="encryption_not_enabled">Chiffrement pas activé</string>
+    <string name="encryption_unknown_algorithm_tile_description">Le chiffrement utilisé par ce salon n’est pas pris en charge</string>
+
+    <string name="room_created_summary_item">%s a créé et configuré ce salon.</string>
+
+    <string name="qr_code_scanned_self_verif_notice">On y est presque ! L’autre appareil affiche-t-il le même bouclier \?</string>
+    <string name="qr_code_scanned_verif_waiting_notice">On y est presque ! En attente de la confirmation…</string>
+    <string name="qr_code_scanned_verif_waiting">En attente de %s…</string>
+
+    <string name="error_failed_to_import_keys">Échec de l’importation des clés</string>
+
+    <string name="settings_notification_configuration">Configuration des notifications</string>
+    <string name="settings_messages_at_room">Messages contenant @room</string>
+    <string name="settings_messages_in_e2e_one_to_one">Messages chiffrés dans les discussions individuelles</string>
+    <string name="settings_messages_in_e2e_group_chat">Messages chiffrés dans les discussions de groupe</string>
+    <string name="settings_when_rooms_are_upgraded">Quand les salons sont mis à niveau</string>
+    <string name="settings_troubleshoot_title">Résolution de problèmes</string>
+    <string name="settings_notification_advanced_summary_riotx">Définir l’importance des notifications par évènement</string>
+
+    <string name="command_description_plain">Envoie un message en texte simple, sans l’interpréter comme du Markdown</string>
+
+    <string name="auth_invalid_login_param_space_in_password">Nom et/ou mot de passe incorrect(s). Le mot de passe saisi commence ou se termine par des espaces, veuillez le vérifier.</string>
+
+    <string name="room_message_placeholder">Message…</string>
+
+    <string name="upgrade_security">Mise à niveau du chiffrement disponible</string>
+    <string name="bootstrap_enter_recovery">Entrez votre %s pour continuer</string>
+    <string name="use_file">Utiliser un fichier</string>
+
+    <string name="enter_backup_passphrase">Entrez %s</string>
+    <string name="backup_recovery_passphrase">Phrase de récupération</string>
+    <string name="bootstrap_invalid_recovery_key">Ce n\'est pas une clé de récupération valide</string>
+    <string name="recovery_key_empty_error_message">Veuillez entrer une clé de récupération</string>
+
+    <string name="bootstrap_progress_checking_backup">Vérification de la clé de sauvegarde</string>
+    <string name="bootstrap_progress_checking_backup_with_info">Vérification de la clé de sauvegarde (%s)</string>
+    <string name="bootstrap_progress_generating_ssss">Génération de la clé SSSS à partir de la phrase secrète</string>
+    <string name="bootstrap_progress_generating_ssss_with_info">Génération de la clé SSSS à partir de la phrase secrète (%s)</string>
+    <string name="bootstrap_progress_generating_ssss_recovery">Génération de la clé SSSS à partir de la clé de récupération</string>
+    <string name="bootstrap_progress_storing_in_sss">Stockage du secret de sauvegarde dans le SSSS</string>
+    <string name="new_session_review_with_info">%1$s (%2$s)</string>
+
+    <string name="security_prompt_text">Vérifiez vos sessions et les autres pour garantir la sûreté de vos discussions</string>
+
+    <string name="bootstrap_progress_compute_curve_key">Récupération de la clé de courbe</string>
+    <string name="bootstrap_migration_enter_backup_password">Saisissez votre phrase secrète de sauvegarde de clés pour continuer.</string>
+    <string name="bootstrap_migration_use_recovery_key">utiliser votre clé de récupération de sauvegarde de clés</string>
+    <string name="bootstrap_migration_with_passphrase_helper_with_link">Vous ne connaissez pas votre phrase secrète de sauvegarde de clés, vous pouvez %s.</string>
+    <string name="bootstrap_migration_backup_recovery_key">Clé de récupération de sauvegarde de clés</string>
+
+    <string name="settings_security_prevent_screenshots_title">Empêcher les captures d’écran de l’application</string>
+    <string name="settings_security_prevent_screenshots_summary">L’activation de ce paramètre ajoute FLAG_SECURE à toutes les activités. Redémarrez l’application pour que la modification soit prise en compte.</string>
+
+    <string name="media_file_added_to_gallery">Fichier multimédia ajouté à la galerie</string>
+    <string name="error_adding_media_file_to_gallery">Impossible d’ajouter le fichier multimédia à la galerie</string>
+    <string name="change_password_summary">Définir un nouveau mot de passe de compte…</string>
+
+    <string name="use_other_session_content_description">Utilisez la dernière version de Riot sur vos autres appareils : Riot Web, Riot pour Bureau, Riot iOS, RiotX pour Android, ou un autre client Matrix qui prend en charge la signature croisée</string>
+    <string name="riot_desktop_web">Riot Web
+\nRiot pour Bureau</string>
+    <string name="riot_ios_android">Riot iOS
+\nRiot X pour Android</string>
+    <string name="or_other_mx_capabale_client">ou un autre client Matrix qui prend en charge la signature croisée</string>
+    <string name="use_latest_riot">Utilisez la dernière version de Riot sur vos autre appareils :</string>
+    <string name="command_description_discard_session">Force la session de groupe sortante actuelle dans un salon chiffré à être abandonnée</string>
+    <string name="command_description_discard_session_not_handled">Seulement pris en charge dans les salons chiffrés</string>
+    <string name="enter_secret_storage_passphrase_or_key">Utilisez votre %1$s ou votre %2$s pour continuer.</string>
+    <string name="use_recovery_key">Utiliser la clé de récupération</string>
+    <string name="enter_secret_storage_input_key">Sélectionnez votre clé de récupération ou saisissez-la manuellement avec le clavier ou en la copiant depuis le presse-papiers</string>
+    <string name="keys_backup_recovery_key_error_decrypt">La sauvegarde n’a pas pu être déchiffrée avec cette clé de récupération : veuillez vérifier que vous avez saisi la bonne clé de récupération.</string>
+    <string name="failed_to_access_secure_storage">Échec d’accès au coffre secret</string>
+
+    <string name="cross_signing_verify_by_text">Vérifier manuellement avec un texte</string>
+    <string name="crosssigning_verify_session">Vérifier la connexion</string>
+    <string name="cross_signing_verify_by_emoji">Vérifier de façon interactive avec des émojis</string>
+    <string name="confirm_your_identity">Confirmez votre identité en vérifiant cette connexion depuis une de vos autres sessions, ce qui lui permettra d’avoir accès à vos messages chiffrés.</string>
+    <string name="mark_as_verified">Marquer comme fiable</string>
+
+    <string name="error_empty_field_choose_user_name">Veuillez choisir un nom d’utilisateur.</string>
+    <string name="error_empty_field_choose_password">Veuillez choisir un mot de passe.</string>
+    <string name="external_link_confirmation_title">Vérifiez ce lien</string>
+    <string name="external_link_confirmation_message">Le lien %1$s vous emmène à un autre site : %2$s.
+\n
+\nVoulez-vous vraiment continuer \?</string>
+
+    <string name="create_room_dm_failure">Nous n’avons pas pu créer votre conversation directe. Vérifiez les utilisateurs que vous souhaitez inviter et réessayez.</string>
+    <string name="unencrypted">Non chiffré</string>
+    <string name="encrypted_unverified">Chiffré par un appareil non vérifié</string>
+    <string name="review_logins">Vérifiez où vous vous êtes connecté</string>
+    <string name="verify_other_sessions">Vérifiez toutes les sessions pour vous assurer que votre compte et vos messages sont en sécurité</string>
+    <string name="verify_this_session">Vérifiez la nouvelle connexion accédant à votre compte : %1$s</string>
+
 </resources>
diff --git a/vector/src/main/res/values-fy/strings.xml b/vector/src/main/res/values-fy/strings.xml
index 13b3b21468..87e1b59509 100644
--- a/vector/src/main/res/values-fy/strings.xml
+++ b/vector/src/main/res/values-fy/strings.xml
@@ -78,4 +78,83 @@
     <string name="missing_permissions_to_start_conf_call">Om in gearkomst yn dit groepspetear te starten hasto útnûgingsrjochten nedich</string>
     <string name="missing_permissions_title_to_start_conf_call">Kin de oprop net starte</string>
     <string name="device_information">Apparaatynformaasje</string>
+    <string name="room_no_conference_call_in_encrypted_rooms">Gearkomstpetearen wurde net stipe yn fersifere petearen</string>
+    <string name="call_anyway">Dochs belje</string>
+    <string name="send_anyway">Dochs ferstjoere</string>
+    <string name="or">of</string>
+    <string name="invite">Utnûgje</string>
+    <string name="offline">Offline</string>
+    <string name="accept">Akseptearje</string>
+    <string name="skip">Oerslaan</string>
+    <string name="done">Klear</string>
+    <string name="abort">Ofbrekke</string>
+    <string name="ignore">Negearje</string>
+    <string name="review">Beoardielje</string>
+    <string name="decline">Wegerje</string>
+
+    <string name="action_exit">Ofslute</string>
+    <string name="actions">Aksjes</string>
+    <string name="action_sign_out">Ofmelde</string>
+    <string name="action_sign_out_confirmation_simple">Binne jo wis dat jo jo ôfmelde wolle\?</string>
+    <string name="action_voice_call">Spraakoprop</string>
+    <string name="action_video_call">Fideo-oprop</string>
+    <string name="action_global_search">Globaal sykje</string>
+    <string name="action_mark_all_as_read">Alles as lêzen markearje</string>
+    <string name="action_historical">Histoarysk</string>
+    <string name="action_quick_reply">Flugge reaksje</string>
+    <string name="action_mark_room_read">As lêzen markearje</string>
+    <string name="action_open">Iepenje</string>
+    <string name="action_close">Slute</string>
+    <string name="copied_to_clipboard">Nei klamboerd kopiearre</string>
+    <string name="disable">Utskeakelje</string>
+
+    <string name="dialog_title_confirmation">Befêstiging</string>
+    <string name="dialog_title_warning">Warskôging</string>
+    <string name="dialog_title_error">Flater</string>
+
+    <string name="bottom_action_home">Start</string>
+    <string name="bottom_action_favourites">Favoriten</string>
+    <string name="bottom_action_people">Minsken</string>
+    <string name="bottom_action_rooms">Petearen</string>
+    <string name="bottom_action_groups">Mienskippen</string>
+
+    <string name="home_filter_placeholder_home">Petearnammen filterje</string>
+    <string name="home_filter_placeholder_favorites">Favoriten filterje</string>
+    <string name="home_filter_placeholder_people">Persoanen filterje</string>
+    <string name="home_filter_placeholder_rooms">Petearnammen filterje</string>
+    <string name="home_filter_placeholder_groups">Mienskipsnammen filterje</string>
+
+    <string name="invitations_header">Utnûgingen</string>
+    <string name="low_priority_header">Lege prioriteit</string>
+    <string name="system_alerts_header">Systeemmeldingen</string>
+
+    <string name="direct_chats_header">Petearen</string>
+    <string name="local_address_book_header">Lokale kontaktelist</string>
+    <string name="user_directory_header">Brûkerskatalogus</string>
+    <string name="matrix_only_filter">Allinnich Matrix-kontakten</string>
+    <string name="no_conversation_placeholder">Gjin petearen</string>
+    <string name="no_contact_access_placeholder">Jo hawwe Riot gjin tagong ta jo lokale kontakten jûn</string>
+    <string name="no_result_placeholder">Gjin resultaten</string>
+    <string name="people_no_identity_server">Gjin identiteitsserver konfigurearre.</string>
+
+    <string name="rooms_header">Petearen</string>
+    <string name="rooms_directory_header">Petearkatalogus</string>
+    <string name="no_room_placeholder">Gjin petearen</string>
+    <string name="no_public_room_placeholder">Gjin publike petearen beskikber</string>
+    <plurals name="public_room_nb_users">
+        <item quantity="one">1 brûker</item>
+        <item quantity="other">%d brûkers</item>
+    </plurals>
+
+    <string name="groups_invite_header">Utnûgje</string>
+    <string name="groups_header">Mienskippen</string>
+    <string name="no_group_placeholder">Gjin groepen</string>
+
+    <string name="send_bug_report_include_logs">Lochboek ferstjoere</string>
+    <string name="send_bug_report_include_crash_logs">Ungeloklochboek ferstjoere</string>
+    <string name="send_bug_report_include_screenshot">Skermôfdruk ferstjoere</string>
+    <string name="send_bug_report">Flater melde</string>
+    <string name="send_bug_report_description">Beskriuw de flater. Wat hawwe jo dien\? Wat ferwachten jo dat der barre soe\? Wat is der echt bard\?</string>
+    <string name="send_bug_report_description_in_english">Beskriuw it probleem yn it Ingelsk, wannear mooglik.</string>
+    <string name="send_bug_report_placeholder">Beskriuw hjir jo probleem</string>
 </resources>
diff --git a/vector/src/main/res/values-gl/strings.xml b/vector/src/main/res/values-gl/strings.xml
index e708f27c70..c01d8afcf4 100644
--- a/vector/src/main/res/values-gl/strings.xml
+++ b/vector/src/main/res/values-gl/strings.xml
@@ -460,7 +460,7 @@ Pode engadir a dirección de correo na sección de configuración de perfil.</st
     <string name="event_formatter_widget_removed">%1$s eliminado por %2$s</string>
     <plurals name="active_widgets">
         <item quantity="one">1 trebello activo</item>
-        <item quantity="other">%1 trebellos activos</item>
+        <item quantity="other">%d trebellos activos</item>
     </plurals>
 
     <string name="widget_integration_unable_to_create">Non se puido crear o trebello.</string>
diff --git a/vector/src/main/res/values-hu/strings.xml b/vector/src/main/res/values-hu/strings.xml
index c4dde2e079..ca32ce03f2 100644
--- a/vector/src/main/res/values-hu/strings.xml
+++ b/vector/src/main/res/values-hu/strings.xml
@@ -555,7 +555,7 @@ Vedd figyelembe, hogy az alkalmazás újraindul  ami sok időt vehet igénybe."<
     <string name="encryption_information_sender_device_information">A küldő munkamenet információi</string>
     <string name="encryption_information_device_name">Nyilvános név</string>
     <string name="encryption_information_name">Nyilvános név</string>
-    <string name="encryption_information_device_id">Azon.</string>
+    <string name="encryption_information_device_id">Azonosító</string>
     <string name="encryption_information_device_key">Munkamenet kulcs</string>
     <string name="encryption_information_verification">Hitelesítés</string>
     <string name="encryption_information_ed25519_fingerprint">Ed25519 ujjlenyomat</string>
@@ -884,7 +884,7 @@ Matrixban az üzenetek láthatósága hasonlít az e-mailre. Az üzenet törlés
     <string name="download">Letöltés</string>
     <string name="speak">Beszélj</string>
     <string name="clear">Törlés</string>
-    <string name="e2e_re_request_encryption_key">Végpontok közötti titkosításhoz használt <u>kulcsok újrakérése</u> a többi munkamenetedtől.</string>
+    <string name="e2e_re_request_encryption_key">Végpontok közötti titkosításhoz használt kulcsok újrakérése a többi munkamenetedtől.</string>
 
     <string name="e2e_re_request_encryption_key_sent">Kulcs újrakérve.</string>
 
@@ -1319,7 +1319,7 @@ A Visszaállítási Kulcsot tartsd biztonságos helyen, mint pl. egy jelszókeze
     <string name="keys_backup_banner_recover_line1">Soha ne veszíts el titkosított üzenetet</string>
     <string name="keys_backup_banner_recover_line2">Kulcs Mentés használata</string>
 
-    <string name="keys_backup_banner_update_line1">Új titkosítási kulcsok</string>
+    <string name="keys_backup_banner_update_line1">Új titkosított üzenet kulcsok</string>
     <string name="keys_backup_banner_update_line2">Kulcs Mentések kezelése</string>
 
     <string name="keys_backup_banner_in_progress">Kulcsok mentése…</string>
@@ -1497,7 +1497,7 @@ Ha nem te állítottad be a visszaállítási metódust, akkor egy támadó pró
     <string name="group_all_communities">Minden közösség</string>
 
     <string name="room_preview_no_preview">Ennek a szobának nincs előnézete</string>
-    <string name="room_preview_world_readable_room_not_supported_yet">A RiotX-ben a nyilvános szoba előnézete egyenlőre nem támogatott</string>
+    <string name="room_preview_world_readable_room_not_supported_yet">A RiotX-ben a nyilvános szoba előnézete egyelőre nem támogatott</string>
 
     <string name="fab_menu_create_room">Szobák</string>
     <string name="fab_menu_create_chat">Közvetlen üzenetek</string>
@@ -1631,7 +1631,7 @@ Ha nem te állítottad be a visszaállítási metódust, akkor egy támadó pró
     <string name="none">Nincs</string>
     <string name="revoke">Visszavonás</string>
     <string name="disconnect">Bontás</string>
-    <string name="people_no_identity_server">Azonosítási szerver nincs beállítva.</string>
+    <string name="people_no_identity_server">Nincs beállítva azonosítási kiszolgáló.</string>
 
     <string name="call_failed_no_ice_title">A hívás sikertelen a hibásan beállított szerver miatt</string>
     <string name="call_failed_no_ice_description">Kérd meg a matrix szervered (%1$s) adminisztrátorát, hogy állítson be egy TURN szervert, hogy a hívások megbízhatóan működjenek.
@@ -1895,7 +1895,7 @@ Ha nem te állítottad be a visszaállítási metódust, akkor egy támadó pró
     <string name="login_set_msisdn_submit">Következő</string>
 
     <string name="login_msisdn_confirm_title">Telefonszám ellenőrzése</string>
-    <string name="login_msisdn_confirm_notice">Elküldtük a kódot ide: %1$s. Add meg itt alul amivel ellenőrizhetjük, hogy te te vagy.</string>
+    <string name="login_msisdn_confirm_notice">Elküldtük a kódot ide: %1$s. Add meg itt alul amivel ellenőrizhetjük, hogy te vagy.</string>
     <string name="login_msisdn_confirm_hint">Kód megadása</string>
     <string name="login_msisdn_confirm_send_again">Küld újra</string>
     <string name="login_msisdn_confirm_submit">Következő</string>
@@ -2082,8 +2082,8 @@ Ha nem te állítottad be a visszaállítási metódust, akkor egy támadó pró
 
     <string name="room_member_jump_to_read_receipt">Olvasási visszaigazolásra ugrás</string>
 
-    <string name="rendering_event_error_type_of_event_not_handled">RiotX (egyenlőre) nem kezeli ezt az eseményt: \'%1$s\'</string>
-    <string name="rendering_event_error_type_of_message_not_handled">RiotX (egyenlőre) nem kezeli ezt az üzenet típust: \'%1$s\'</string>
+    <string name="rendering_event_error_type_of_event_not_handled">RiotX nem kezeli ezt az eseményt: \'%1$s\'</string>
+    <string name="rendering_event_error_type_of_message_not_handled">RiotX nem kezeli ezt az üzenet típust: \'%1$s\'</string>
     <string name="rendering_event_error_exception">RiotX problémába ütközött az esemény (azon: %1$s) megjelenítésekor</string>
 
     <string name="unignore">Figyelembe vesz</string>
@@ -2147,7 +2147,7 @@ Ha nem te állítottad be a visszaállítási metódust, akkor egy támadó pró
     <string name="crosssigning_other_user_not_trust">Más felhasználók lehet, hogy nem bíznak benne</string>
     <string name="complete_security">Biztonság beállítása</string>
 
-    <string name="verification_open_other_to_verify">A titkosított üzenetekhez való hozzáféréshez nyiss meg egy létező munkamenetet és használd ennek a hitelesítésére. Ha egyhez sem férsz hozzá használd a visszaállítási kulcsodat vagy jelmondatodat.</string>
+    <string name="verification_open_other_to_verify">A titkosított üzenetekhez való hozzáféréshez nyiss meg egy létező munkamenetet és használd ennek a hitelesítésére.</string>
 
 
     <string name="verification_profile_verify">Ellenőriz</string>
@@ -2169,8 +2169,217 @@ Ha nem te állítottad be a visszaállítási metódust, akkor egy támadó pró
 
     <string name="a11y_qr_code_for_verification">QR kód</string>
 
+    <string name="qr_code_scanned_by_other_notice">Majdnem kész! %s is ugyanazt a pajzsot mutatja\?</string>
     <string name="qr_code_scanned_by_other_yes">Igen</string>
     <string name="qr_code_scanned_by_other_no">Nem</string>
 
     <string name="no_connectivity_to_the_server_indicator">Megszakadt a kapcsolat a szerverrel</string>
+    <string name="login_signup_username_hint">Felhasználónév</string>
+    <string name="settings_dev_tools">Fejlesztői Eszközök</string>
+    <string name="settings_account_data">Fiók Adatok</string>
+    <plurals name="poll_info">
+        <item quantity="one">%d szavazat</item>
+        <item quantity="other">%d szavazat</item>
+    </plurals>
+    <plurals name="poll_info_final">
+        <item quantity="one">Végeredmény - %d szavazat</item>
+        <item quantity="other">Végeredmény - %d szavazat</item>
+    </plurals>
+    <string name="poll_item_selected_aria">Kiválasztott Beállítások</string>
+    <string name="command_description_poll">Egyszerű szavazás készítése</string>
+    <string name="verification_cannot_access_other_session">Használd a visszaállítási eljárást</string>
+    <string name="verification_use_passphrase">Ha nem érsz el létező munkamenetet</string>
+
+    <string name="new_signin">Új Bejelentkezés</string>
+
+    <string name="enter_secret_storage_invalid">A tárolóban nem található jelszó/kulcs</string>
+    <string name="enter_secret_storage_passphrase">Add meg a jelmondatot a biztonsági tárolóhoz</string>
+    <string name="enter_secret_storage_passphrase_warning">Figyelem:</string>
+    <string name="enter_secret_storage_passphrase_warning_text">Csak biztonságos eszközről férj hozzá a biztonsági tárolóhoz</string>
+
+    <string name="message_action_item_redact">Töröl…</string>
+    <string name="share_confirm_room">Ezt a csatolmányt el szeretnéd küldeni ide: %1$s\?</string>
+    <plurals name="send_images_with_original_size">
+        <item quantity="one">Kép küldése eredeti méretben</item>
+        <item quantity="other">Képek küldése eredeti méretben</item>
+    </plurals>
+
+    <string name="delete_event_dialog_title">Törlés megerősítése</string>
+    <string name="delete_event_dialog_content">Biztos hogy eltávolítod (törlöd) ezt az eseményt\? Figyelem, ha törlöd vagy megváltoztatod a szoba nevét vagy a témát ez a változtatás érvényét vesztheti.</string>
+    <string name="delete_event_dialog_reason_checkbox">Ok megadása</string>
+    <string name="delete_event_dialog_reason_hint">Ok a kitakaráshoz</string>
+
+    <string name="event_redacted_by_user_reason_with_reason">Az eseményt a felhasználó törölte, ezért: %1$s</string>
+    <string name="event_redacted_by_admin_reason_with_reason">Az eseményt a szoba adminisztrátora moderálta, ezért: %1$s</string>
+
+    <string name="keys_backup_restore_success_title_already_up_to_date">A kulcsok már frissek!</string>
+
+    <string name="login_mobile_device_riotx">RiotX Android</string>
+
+    <string name="settings_key_requests">Kulcs kérések</string>
+
+    <string name="e2e_use_keybackup">Régi titkosított üzenetek feloldása</string>
+
+    <string name="refresh">Frissítés</string>
+
+    <string name="new_session">Új bejelentkezés. Ez te vagy\?</string>
+    <string name="new_session_review">A megtekintéshez és ellenőrzéshez koppints</string>
+    <string name="verify_new_session_notice">Az új munkamenet ellenőrzéséhez használd ezt, amivel hozzáférést adsz a titkosított üzenetekhez.</string>
+    <string name="verify_new_session_was_not_me">Nem én voltam</string>
+    <string name="verify_new_session_compromized">A fiókodat lehet, hogy feltörték</string>
+
+    <string name="verify_cancel_self_verification_from_untrusted">Ha megszakítod akkor ezen az eszközön nem tudod majd elolvasni a titkosított üzeneteket és mások nem fogják megbízhatónak látni</string>
+    <string name="verify_cancel_self_verification_from_trusted">Ha megszakítod akkor az eszközödön nem tudod majd elolvasni a titkosított üzeneteket és mások nem fogják megbízhatónak látni</string>
+    <string name="verify_cancel_other">Ha most megszakítod akkor ezt nem fogod ellenőrizni: %1$s (%2$s). A felhasználói profilból újrakezdheted.</string>
+
+    <string name="verify_not_me_self_verification">Az egyik az alábbiak közül kompromittálódhatott:
+\n
+\n- A jelszavad
+\n- A matrix szervered
+\n- Ez vagy egy másik eszköz
+\n- Valamelyik eszköz által használt internet elérés
+\n
+\nJavasoljuk, hogy azonnal cseréld le a jelszavadat és a visszaállítási kulcsot a Beállításokban.</string>
+
+    <string name="verify_cancelled_notice">Ellenőrizd az eszközödet a Beállításokból.</string>
+    <string name="verification_cancelled">Ellenőrzés megszakítva</string>
+
+    <string name="recovery_passphrase">Visszaállítási jelmondat</string>
+    <string name="message_key">Üzenet Kulcs</string>
+    <string name="account_password">Fiók Jelszó</string>
+
+    <string name="set_recovery_passphrase">Beállítás: %s</string>
+    <string name="generate_message_key">Üzenet kulcs létrehozása</string>
+
+    <string name="confirm_recovery_passphrase">Megerősít: %s</string>
+
+    <string name="enter_account_password">A továbblépéshez add meg: %s.</string>
+
+    <string name="bootstrap_info_text">Helyezd biztonságba és férj hozzá a titkosított üzenetekhez valamint bízz meg benne ezzel: %s.</string>
+    <string name="bootstrap_info_confirm_text">A megerősítéshez add meg újra ezt: %s.</string>
+    <string name="bootstrap_dont_reuse_pwd">Ne a fiók jelszavadat használd.</string>
+
+
+    <string name="bootstrap_loading_text">Ez eltarthat néhány másodpercig, kérlek legyél türelmes.</string>
+    <string name="bootstrap_loading_title">Visszaállítás beállítása.</string>
+    <string name="your_recovery_key">Visszaállítási kulcsod</string>
+    <string name="bootstrap_finish_title">Kész vagy!</string>
+    <string name="keep_it_safe">Tartsd biztonságban</string>
+    <string name="finish">Befejez</string>
+
+    <string name="bootstrap_save_key_description">A biztonság kedvéért használd ezt: %1$s arra az esetre ha elfelejtenéd ezt: %2$s.</string>
+
+    <string name="bootstrap_crosssigning_progress_initializing">Az elkészített azonosítási kulcsok közzé tétele</string>
+    <string name="bootstrap_crosssigning_progress_pbkdf2">Biztonságos kulcs készítése a jelmondatból</string>
+    <string name="bootstrap_crosssigning_progress_default_key">SSSS alapértelmezett kulcs meghatározása</string>
+    <string name="bootstrap_crosssigning_progress_save_msk">Mester kulcs szinkronizálása</string>
+    <string name="bootstrap_crosssigning_progress_save_usk">Felhasználói kulcs szinkronizálása</string>
+    <string name="bootstrap_crosssigning_progress_save_ssk">Saját magával aláírt kulcs szinkronizálása</string>
+    <string name="bootstrap_crosssigning_progress_key_backup">Kulcs Mentés beállítása</string>
+
+
+    <string name="bootstrap_cross_signing_success">Ezek lettek beállítva: %2$s és %1$s.
+\n
+\nTartsd őket biztonságban! Szükség lesz rájuk a titkosított üzenetek és biztonsági információk eléréséhez ha minden aktív munkameneted megszűnik.</string>
+
+    <string name="bootstrap_crosssigning_print_it">Nyomtasd ki és tárold valahol biztonságos helyen</string>
+    <string name="bootstrap_crosssigning_save_usb">Mentsd el egy USB kulcsra vagy mentő eszközre</string>
+    <string name="bootstrap_crosssigning_save_cloud">Másold fel a személyes felhő tárhelyedre</string>
+
+    <string name="auth_flow_not_supported">Mobilról ezt nem tudod megtenni</string>
+
+    <string name="bootstrap_skip_text">Az Üzenet Jelszó beállításával biztonságba helyezheted és hozzáférhetsz a titkosított üzeneteidhez valamint a bizalomhoz.
+\n
+\nHa nem akarsz Üzenet Jelszót beállítani, hozz létre inkább Üzenet Kulcsot.</string>
+    <string name="bootstrap_skip_text_no_gen_key">Az Visszaállítási Jelmondat beállításával biztonságba helyezheted és hozzáférhetsz a titkosított üzeneteidhez valamint a bizalomhoz.</string>
+
+
+    <string name="encryption_enabled">Titkosítás bekapcsolva</string>
+    <string name="encryption_enabled_tile_description">Ebben a szobában az üzenetek végpontok között titkosítottak. További információkért és ellenőrzéshez nyisd meg a felhasználók profilját.</string>
+    <string name="encryption_not_enabled">Titkosítás nincs engedélyezve</string>
+    <string name="encryption_unknown_algorithm_tile_description">A szobában használt titkosítás nem támogatott</string>
+
+    <string name="room_created_summary_item">%s elkészítette és beállította a szobát.</string>
+
+    <string name="qr_code_scanned_self_verif_notice">Majdnem kész! A többi eszközöd is ugyanazt a pajzsot mutatja\?</string>
+    <string name="qr_code_scanned_verif_waiting_notice">Majdnem kész! Várakozás a megerősítésre…</string>
+    <string name="qr_code_scanned_verif_waiting">Várakozás erre: %s…</string>
+
+    <string name="error_failed_to_import_keys">A kulcsok betöltése sikertelen</string>
+
+    <string name="settings_notification_configuration">Értesítések beállítása</string>
+    <string name="settings_messages_at_room">Az üzenetek „@room”-ot tartalmaznak</string>
+    <string name="settings_messages_in_e2e_one_to_one">Titkosított üzenetek közvetlen csevegésekben</string>
+    <string name="settings_messages_in_e2e_group_chat">Titkosított üzenetek a csoportos beszélgetésekben</string>
+    <string name="settings_when_rooms_are_upgraded">Ha a szobák fejlesztésre kerülnek</string>
+    <string name="settings_troubleshoot_title">Hibakeresés</string>
+    <string name="settings_notification_advanced_summary_riotx">Értesítés fontosságának beállítása eseménynél</string>
+
+    <string name="command_description_plain">Az üzenet elküldése sima szövegként anélkül, hogy „markdown” formázás lenne</string>
+
+    <string name="auth_invalid_login_param_space_in_password">Felhasználói név és/vagy jelszó hibás. A beírt jelszó szóközzel kezdődik vagy ér véget, kérlek ellenőrizd.</string>
+
+    <string name="room_message_placeholder">Üzenet…</string>
+
+    <string name="upgrade_security">A titkosítás fejlesztése elérhető</string>
+    <string name="security_prompt_text">Ellenőrizd magad és másokat, hogy a csevegéseid biztonságban legyenek</string>
+
+    <string name="bootstrap_enter_recovery">A továbblépéshez add meg: %s</string>
+    <string name="use_file">Fájl használata</string>
+
+    <string name="enter_backup_passphrase">Bevitel: %s</string>
+    <string name="backup_recovery_passphrase">Visszaállítási Jelmondat</string>
+    <string name="bootstrap_invalid_recovery_key">Ez nem egy érvényes visszaállítási kulcs</string>
+    <string name="recovery_key_empty_error_message">Kérlek add meg a visszaállítási kulcsot</string>
+
+    <string name="bootstrap_progress_checking_backup">Mentés Kulcs ellenőrzése</string>
+    <string name="bootstrap_progress_checking_backup_with_info">Mentés Kulcs (%s) ellenőrzése</string>
+    <string name="bootstrap_progress_compute_curve_key">Curve kulcs megszerzése</string>
+    <string name="bootstrap_progress_generating_ssss">SSSS kulcs készítése a jelmondatból</string>
+    <string name="bootstrap_progress_generating_ssss_with_info">SSSS kulcs készítése a jelmondatból (%s)</string>
+    <string name="bootstrap_progress_generating_ssss_recovery">SSSS kulcs készítése a visszaállítási kulcsból</string>
+    <string name="bootstrap_progress_storing_in_sss">Kulcsmentés titok tárolása az SSSS-ben</string>
+    <string name="new_session_review_with_info">%1$s (%2$s)</string>
+
+    <string name="bootstrap_migration_enter_backup_password">A továbblépéshez add meg a kulcs mentés jelmondatát.</string>
+    <string name="bootstrap_migration_use_recovery_key">használd a Kulcs Mentés visszaállítási kulcsot</string>
+    <string name="bootstrap_migration_with_passphrase_helper_with_link">Ha nem tudod a Kulcs Mentés Jelmondatodat, akkor %s.</string>
+    <string name="bootstrap_migration_backup_recovery_key">Kulcs Mentés visszaállítási kulcs</string>
+
+    <string name="settings_security_prevent_screenshots_title">Az alkalmazásról képernyőkép készítésének megakadályozása</string>
+    <string name="settings_security_prevent_screenshots_summary">A beállítással minden \"Activiti\" megkapja a \"FLAG_SECURE\" flaget. Indítsd újra az alkalmazást, hogy a változás életbe léphessen.</string>
+
+    <string name="media_file_added_to_gallery">A média fájl a Galériához hozzáadva</string>
+    <string name="error_adding_media_file_to_gallery">A média fájlt nem sikerült hozzáadni a Galériához</string>
+    <string name="change_password_summary">Új fiók jelszó beállítása…</string>
+
+    <string name="riot_desktop_web">Riot Web
+\nRiot Desktop</string>
+    <string name="riot_ios_android">Riot iOS
+\nRiot X for Android</string>
+    <string name="or_other_mx_capabale_client">vagy másik eszközök közötti hitelesítésre alkalmas Matrix kliensre</string>
+    <string name="use_latest_riot">A Riot legújabb kliensét használd a többi eszközödön:</string>
+    <string name="command_description_discard_session">A jelenlegi csoport munkamenet törlését kikényszeríti a titkosított szobában</string>
+    <string name="command_description_discard_session_not_handled">Csak a titkosított szobákban támogatott</string>
+    <string name="enter_secret_storage_passphrase_or_key">Használd ezt: %1$s vagy ezt: %2$s a továbblépéshez.</string>
+    <string name="use_recovery_key">Használd a Visszaállítási Kulcsot</string>
+    <string name="enter_secret_storage_input_key">Válaszd ki a Visszaállítási Kulcsot, add meg kézzel vagy másold be a vágólapról</string>
+    <string name="keys_backup_recovery_key_error_decrypt">Ezzel a Visszaállítási Kulccsal a mentést nem lehet visszafejteni: kérlek ellenőrizd, hogy a visszaállítási kulcsot jól adtad-e meg.</string>
+    <string name="failed_to_access_secure_storage">A biztonsági tárolóhoz nem sikerült hozzáférni</string>
+
+    <string name="unencrypted">Titkosítatlan</string>
+    <string name="encrypted_unverified">Ellenőrizetlen eszközzel titkosította</string>
+    <string name="review_logins">Tekintsd át hol vagy bejelentkezve</string>
+    <string name="verify_other_sessions">Ellenőrizd minden munkamenetedet, hogy a fiókod és az üzeneteid biztonságban legyenek</string>
+    <string name="verify_this_session">Ellenőrizd ezt az új bejelentkezést ami hozzáfér a fiókodhoz: %1$s</string>
+
+    <string name="cross_signing_verify_by_text">Manuális szöveges ellenőrzés</string>
+    <string name="crosssigning_verify_session">Belépés ellenőrzése</string>
+    <string name="cross_signing_verify_by_emoji">Közös ellenőrzés Emodzsival</string>
+    <string name="mark_as_verified">Megbízhatónak jelölés</string>
+
+    <string name="error_empty_field_choose_user_name">Kérlek válasz felhasználói nevet.</string>
+    <string name="error_empty_field_choose_password">Kérlek válassz jelszót.</string>
+    <string name="external_link_confirmation_title">Ezt a hivatkozást ellenőrizd le még egyszer</string>
+    <string name="create_room_dm_failure">A közvetlen üzenetedet nem sikerült elkészíteni. Ellenőrizd azokat a felhasználókat akiket meg szeretnél hívni és próbáld újra.</string>
 </resources>
diff --git a/vector/src/main/res/values-it/strings.xml b/vector/src/main/res/values-it/strings.xml
index 92b235c5dd..25c23b6b5f 100644
--- a/vector/src/main/res/values-it/strings.xml
+++ b/vector/src/main/res/values-it/strings.xml
@@ -38,7 +38,7 @@
     <string name="ongoing_conference_call_voice">Audio</string>
     <string name="ongoing_conference_call_video">Video</string>
     <string name="cannot_start_call">Impossibile avviare la chiamata, riprova più tardi</string>
-    <string name="missing_permissions_warning">Poichè i tuoi permessi non sono sufficienti, alcune funzioni potrebbero non esser disponibili…</string>
+    <string name="missing_permissions_warning">Poiché i tuoi permessi non sono sufficienti, alcune funzioni potrebbero non esser disponibili…</string>
     <string name="missing_permissions_to_start_conf_call">Non hai permessi sufficienti per avviare una conferenza in questa stanza</string>
     <string name="missing_permissions_title_to_start_conf_call">Impossibile avviare la chiamata</string>
     <string name="device_information">Informazioni sulla sessione</string>
@@ -268,7 +268,7 @@
 \n
 \nTi sta bene comunicare i dati di tutti i tuoi contatti per questo scopo\?</string>
 
-    <string name="permissions_action_not_performed_missing_permissions">Purtroppo l\'azione non è stata eseguita poichè mancano i permessi</string>
+    <string name="permissions_action_not_performed_missing_permissions">Purtroppo l\'azione non è stata eseguita poiché mancano i permessi</string>
 
     <!-- medias slider string -->
     <string name="media_slider_saved">Salvato</string>
@@ -668,8 +668,8 @@
     <string name="encryption_information_unblock">Togli dalla lista nera</string>
 
     <string name="encryption_information_verify_device">Verifica la sessione</string>
-    <string name="encryption_information_verify_device_warning">Per verificare se questa sessione sia affidabile, contatta il suo proprietario utilizzando altre vie di comunicazione (es. di persona o per telefono) e chiedigli se la chiave che vede nelle Impostazioni Utente per questa sessione corrisponde a quella riportata sotto:</string>
-    <string name="encryption_information_verify_device_warning2">Se corrisponde, premi il pulsante di verifica qui sotto. In caso contrario, qualcun altro sta intercettando questa sessione e probabilmente dovresti metterlo in lista nera. In futuro il processo di verifica sarà più sofisticato.</string>
+    <string name="encryption_information_verify_device_warning">Conferma confrontando la seguente con le impostazioni utente della tua altra sessione:</string>
+    <string name="encryption_information_verify_device_warning2">Se non corrispondono, la sicurezza delle tue comunicazioni potrebbe essere compromessa.</string>
     <string name="encryption_information_verify_key_match">Ho verificato che le chiavi corrispondono</string>
 
     <string name="e2e_enabling_on_app_update">Riot supporta ora la crittografia da-utente-a-utente, ma per abilitarla devi riconnetterti.
@@ -939,7 +939,7 @@
     <string name="download">Scarica</string>
     <string name="speak">Parla</string>
     <string name="clear">Svuota</string>
-    <string name="e2e_re_request_encryption_key"><u>Richiedi di nuovo le chiavi di crittografia</u> dalle tue altre sessioni.</string>
+    <string name="e2e_re_request_encryption_key">Richiedi di nuovo le chiavi di crittografia dalle tue altre sessioni.</string>
 
     <string name="e2e_re_request_encryption_key_sent">La richiesta della chiave è stata inviata.</string>
 
@@ -1392,7 +1392,7 @@
     <string name="keys_backup_banner_recover_line1">Non perdere mai i messaggi cifrati</string>
     <string name="keys_backup_banner_recover_line2">Usa il Backup delle chiavi</string>
 
-    <string name="keys_backup_banner_update_line1">Nuove chiavi di crittografia</string>
+    <string name="keys_backup_banner_update_line1">Nuove chiavi per messaggi sicuri</string>
     <string name="keys_backup_banner_update_line2">Gestisci nel Backup delle chiavi</string>
 
     <string name="keys_backup_banner_in_progress">Backup chiavi in corso…</string>
@@ -2132,8 +2132,8 @@
 
     <string name="room_member_jump_to_read_receipt">Vai alla ricevuta di lettura</string>
 
-    <string name="rendering_event_error_type_of_event_not_handled">RiotX non gestisce eventi del tipo \'%1$s\' (non ancora)</string>
-    <string name="rendering_event_error_type_of_message_not_handled">RiotX non gestisce messaggi del tipo \'%1$s\' (non ancora)</string>
+    <string name="rendering_event_error_type_of_event_not_handled">RiotX non gestisce eventi del tipo \'%1$s\'</string>
+    <string name="rendering_event_error_type_of_message_not_handled">RiotX non gestisce messaggi del tipo \'%1$s\'</string>
     <string name="rendering_event_error_exception">RiotX ha riscontrato un errore con il rendering del contenuto dell\'evento con id \'%1$s\'</string>
 
     <string name="unignore">Non ignorare</string>
@@ -2185,7 +2185,7 @@
 
     <string name="settings_failed_to_get_crypto_device_info">Nessuna informazione crittografica disponibile</string>
 
-    <string name="settings_active_sessions_verified_device_desc">Questa sessione è fidata per i messaggi sicuri perchè l\'hai verificata:</string>
+    <string name="settings_active_sessions_verified_device_desc">Questa sessione è fidata per i messaggi sicuri perché l\'hai verificata:</string>
     <string name="settings_active_sessions_unverified_device_desc">Verifica questa sessione per segnarla come fidata e darle l\'accesso ai messaggi cifrati. Se non hai fatto l\'accesso a questa sessione il tuo account potrebbe essere compromesso:</string>
 
     <plurals name="settings_active_sessions_count">
@@ -2193,11 +2193,11 @@
         <item quantity="other">%d sessioni attive</item>
     </plurals>
 
-    <string name="crosssigning_verify_this_session">Verifica questa sessione</string>
+    <string name="crosssigning_verify_this_session">Verifica questo accesso</string>
     <string name="crosssigning_other_user_not_trust">Gli altri utenti potrebbero non fidarsi</string>
     <string name="complete_security">Completa la sicurezza</string>
 
-    <string name="verification_open_other_to_verify">Apri una sessione esistente e usala per verificare questa, dandole l\'accesso ai messaggi cifrati. Se non riesci ad accedere a nessuna, usa la tua chiave o password di recupero.</string>
+    <string name="verification_open_other_to_verify">Usa una sessione esistente per verificare questa, dandole l\'accesso ai messaggi cifrati.</string>
 
 
     <string name="verification_profile_verify">Verifica</string>
@@ -2209,7 +2209,7 @@
     <string name="trusted">Fidato</string>
     <string name="not_trusted">Non fidato</string>
 
-    <string name="verification_profile_device_verified_because">Questa sessione è fidata per i messaggi sicuri perchè %1$s (%2$s) l\'ha verificata:</string>
+    <string name="verification_profile_device_verified_because">Questa sessione è fidata per i messaggi sicuri perché %1$s (%2$s) l\'ha verificata:</string>
     <string name="verification_profile_device_new_signing">%1$s (%2$s) ha fatto l\'accesso con una nuova sessione:</string>
     <string name="verification_profile_device_untrust_info">Finché questo utente non si fida di questa sessione, i messaggi inviati da e verso di essa sono etichettati con avvisi. In alternativa, puoi verificarlo manualmente.</string>
 
@@ -2219,8 +2219,223 @@
 
     <string name="a11y_qr_code_for_verification">Codice QR</string>
 
+    <string name="qr_code_scanned_by_other_notice">Quasi fatto! %s sta mostrando lo stesso scudo\?</string>
     <string name="qr_code_scanned_by_other_yes">Sì</string>
     <string name="qr_code_scanned_by_other_no">No</string>
 
     <string name="no_connectivity_to_the_server_indicator">La connessione al server è stata persa</string>
+    <string name="login_signup_username_hint">Nome utente</string>
+    <string name="settings_dev_tools">Strumenti Svil</string>
+    <string name="settings_account_data">Dati account</string>
+    <plurals name="poll_info">
+        <item quantity="one">%d voto</item>
+        <item quantity="other">%d voti</item>
+    </plurals>
+    <plurals name="poll_info_final">
+        <item quantity="one">%d voto - Risultato finale</item>
+        <item quantity="other">%d voti - Risultato finale</item>
+    </plurals>
+    <string name="poll_item_selected_aria">Opzione selezionata</string>
+    <string name="command_description_poll">Crea un semplice sondaggio</string>
+    <string name="verification_cannot_access_other_session">Usa una password o chiave di recupero</string>
+    <string name="verification_use_passphrase">Se non puoi accedere a una sessione esistente</string>
+
+    <string name="new_signin">Nuovo accesso</string>
+
+    <string name="enter_secret_storage_invalid">Impossibile trovare segreti nell\'archivio</string>
+    <string name="enter_secret_storage_passphrase">Inserisci la password dell\'archivio segreto</string>
+    <string name="enter_secret_storage_passphrase_warning">Attenzione:</string>
+    <string name="enter_secret_storage_passphrase_warning_text">Dovresti accedere all\'archivio segreto solo da un dispositivo fidato</string>
+
+    <string name="message_action_item_redact">Rimuovi…</string>
+    <string name="share_confirm_room">Vuoi inviare questo allegato a %1$s\?</string>
+    <plurals name="send_images_with_original_size">
+        <item quantity="one">Invia immagine nella dimensione originale</item>
+        <item quantity="other">Invia immagini nella dimensione originale</item>
+    </plurals>
+
+    <string name="delete_event_dialog_title">Conferma rimozione</string>
+    <string name="delete_event_dialog_content">Sei sicuro di volere rimuovere (eliminare) questo evento\? Nota che se elimini il nome della stanza o cambi l\'argomento, ciò potrebbe annullare la modifica.</string>
+    <string name="delete_event_dialog_reason_checkbox">Includi un motivo</string>
+    <string name="delete_event_dialog_reason_hint">Motivo della revisione</string>
+
+    <string name="event_redacted_by_user_reason_with_reason">Evento eliminato da un utente, motivo: %1$s</string>
+    <string name="event_redacted_by_admin_reason_with_reason">Evento moderato da un admin della stanza, motivo: %1$s</string>
+
+    <string name="keys_backup_restore_success_title_already_up_to_date">Le chiavi sono già aggiornate!</string>
+
+    <string name="login_mobile_device_riotx">RiotX Android</string>
+
+    <string name="settings_key_requests">Richieste di chiavi</string>
+
+    <string name="e2e_use_keybackup">Sblocca la cronologia dei messaggi cifrati</string>
+
+    <string name="refresh">Ricarica</string>
+
+    <string name="new_session">Nuovo accesso. Eri tu\?</string>
+    <string name="new_session_review">Tocca per controllare e verificare</string>
+    <string name="verify_new_session_notice">Usa questa sessione per verificare quella nuova, dandole l\'accesso ai messaggi cifrati.</string>
+    <string name="verify_new_session_was_not_me">Non ero io</string>
+    <string name="verify_new_session_compromized">Il tuo account potrebbe essere compromesso</string>
+
+    <string name="verify_cancel_self_verification_from_untrusted">Se annulli, non potrai leggere i messaggi cifrati su questo dispositivo e altri utenti non si fideranno di esso</string>
+    <string name="verify_cancel_self_verification_from_trusted">Se annulli, non potrai leggere i messaggi cifrati sul tuo nuovo dispositivo e altri utenti non si fideranno di esso</string>
+    <string name="verify_cancel_other">Non verificherai %1$s (%2$s) se annulli adesso. Ricomincia nel suo profilo utente.</string>
+
+    <string name="verify_not_me_self_verification">Uno dei seguenti potrebbe essere compromesso:
+\n
+\n- La tua password
+\n- Il tuo homeserver
+\n- Questo dispositivo, o l\'altro
+\n- La connessione internet usata da uno dei dispositivi
+\n
+\nTi consigliamo di cambiare immediatamente la password e le chiavi di recupero nelle impostazioni.</string>
+
+    <string name="verify_cancelled_notice">Verifica i tuoi dispositivi dalle impostazioni.</string>
+    <string name="verification_cancelled">Verifica annullata</string>
+
+    <string name="recovery_passphrase">Password di ripristino</string>
+    <string name="message_key">chiave dei messaggi</string>
+    <string name="account_password">password dell\'account</string>
+
+    <string name="set_recovery_passphrase">Imposta una %s</string>
+    <string name="generate_message_key">Genera una chiave dei messaggi</string>
+
+    <string name="confirm_recovery_passphrase">Conferma la %s</string>
+
+    <string name="enter_account_password">Inserisci la tua %s per continuare.</string>
+
+    <string name="bootstrap_info_text">Proteggi e sblocca i messaggi cifrati e fidati con una %s.</string>
+    <string name="bootstrap_info_confirm_text">Inserisci la tua %s di nuovo per confermarla.</string>
+    <string name="bootstrap_dont_reuse_pwd">Non riutilizzare la tua password dell\'account.</string>
+
+
+    <string name="bootstrap_loading_text">Potrebbe impiegarci qualche secondo, porta pazienza.</string>
+    <string name="bootstrap_loading_title">Inizializzazione del ripristino.</string>
+    <string name="your_recovery_key">La tua chiave di recupero</string>
+    <string name="bootstrap_finish_title">Hai finito!</string>
+    <string name="keep_it_safe">Tienila al sicuro</string>
+    <string name="finish">Fine</string>
+
+    <string name="bootstrap_save_key_description">Usa questa %1$s come una rete di salvataggio in caso ti dimentichi la tua %2$s.</string>
+
+    <string name="bootstrap_crosssigning_progress_initializing">Pubblicazione delle chiavi di identità create</string>
+    <string name="bootstrap_crosssigning_progress_pbkdf2">Generazione della chiave sicura dalla password</string>
+    <string name="bootstrap_crosssigning_progress_default_key">Definizione della chiave predefinita SSSS</string>
+    <string name="bootstrap_crosssigning_progress_save_msk">Sincronizzazione della chiave principale</string>
+    <string name="bootstrap_crosssigning_progress_save_usk">Sincronizzazione della chiave utente</string>
+    <string name="bootstrap_crosssigning_progress_save_ssk">Sincronizzazione della chiave di auto-firma</string>
+    <string name="bootstrap_crosssigning_progress_key_backup">Inizializzazione del backup chiavi</string>
+
+
+    <string name="bootstrap_cross_signing_success">La tua %2$s e la %1$s sono ora impostate.
+\n
+\nTienile al sicuro! Ti serviranno per sbloccare i messaggi cifrati e informazioni sicure se perdi tutte le tue sessioni attive.</string>
+
+    <string name="bootstrap_crosssigning_print_it">Stampala e conservala in un posto sicuro</string>
+    <string name="bootstrap_crosssigning_save_usb">Salvala in una penna USB o disco di backup</string>
+    <string name="bootstrap_crosssigning_save_cloud">Copiala nella tua archiviazione online</string>
+
+    <string name="auth_flow_not_supported">Non puoi farlo da mobile</string>
+
+    <string name="bootstrap_skip_text">Impostare una password dei messaggi ti consente di proteggere e sbloccare i messaggi cifrati e di fidarti.
+\n
+\nSe non vuoi impostare una password dei messaggi, genera una chiave dei messaggi.</string>
+    <string name="bootstrap_skip_text_no_gen_key">Impostare una password di ripristino ti consente di proteggere e sbloccare i messaggi cifrati e di fidarti.</string>
+
+
+    <string name="encryption_enabled">Cifratura attiva</string>
+    <string name="encryption_enabled_tile_description">I messaggi in questa stanza sono cifrati end-to-end. Maggiori info e verifica degli utenti nel loro profilo.</string>
+    <string name="encryption_not_enabled">Cifratura non attiva</string>
+    <string name="encryption_unknown_algorithm_tile_description">La cifratura usata da questa stanza non è supportata</string>
+
+    <string name="room_created_summary_item">%s ha creato e configurato la stanza.</string>
+
+    <string name="qr_code_scanned_self_verif_notice">Quasi fatto! L\'altro dispositivo sta mostrando lo stesso scudo\?</string>
+    <string name="qr_code_scanned_verif_waiting_notice">Quasi fatto! In attesa della conferma…</string>
+    <string name="qr_code_scanned_verif_waiting">In attesa di %s…</string>
+
+    <string name="error_failed_to_import_keys">Importazione chiavi fallita</string>
+
+    <string name="settings_notification_configuration">Configurazione delle notifiche</string>
+    <string name="settings_messages_at_room">Messaggi contenenti @room</string>
+    <string name="settings_messages_in_e2e_one_to_one">Messaggi cifrati in conversazioni private</string>
+    <string name="settings_messages_in_e2e_group_chat">Messaggi cifrati in chat di gruppo</string>
+    <string name="settings_when_rooms_are_upgraded">Quando le stanze vengono aggiornate</string>
+    <string name="settings_troubleshoot_title">Risoluzione problemi</string>
+    <string name="settings_notification_advanced_summary_riotx">Imposta l\'importanza della notifica per evento</string>
+
+    <string name="command_description_plain">Invia un messaggio come testo semplice, senza interpretarlo come markdown</string>
+
+    <string name="auth_invalid_login_param_space_in_password">Nome utente e/o password errati. La password inserita inizia o termina con spazi, controllala.</string>
+
+    <string name="room_message_placeholder">Messaggio…</string>
+
+    <string name="upgrade_security">Aggiornamento cifratura disponibile</string>
+    <string name="security_prompt_text">Verifica te stesso e gli altri per tenere al sicuro le chat</string>
+
+    <string name="bootstrap_enter_recovery">Inserisci la tua %s per continuare</string>
+    <string name="use_file">Usa file</string>
+
+    <string name="enter_backup_passphrase">Inserisci la %s</string>
+    <string name="backup_recovery_passphrase">Password di ripristino</string>
+    <string name="bootstrap_invalid_recovery_key">Non è una chiave di ripristino valida</string>
+    <string name="recovery_key_empty_error_message">Inserisci una chiave di ripristino</string>
+
+    <string name="bootstrap_progress_checking_backup">Controllo della chiave di backup</string>
+    <string name="bootstrap_progress_checking_backup_with_info">Controllo della chiave di backup (%s)</string>
+    <string name="bootstrap_progress_compute_curve_key">Rilevazione chiave di curva ellittica</string>
+    <string name="bootstrap_progress_generating_ssss">Generazione chiave SSSS dalla password</string>
+    <string name="bootstrap_progress_generating_ssss_with_info">Generazione chiave SSSS dalla password (%s)</string>
+    <string name="bootstrap_progress_generating_ssss_recovery">Generazione chiave SSSS dalla chiave di ripristino</string>
+    <string name="bootstrap_progress_storing_in_sss">Memorizzazione segreto della chiave in SSSS</string>
+    <string name="new_session_review_with_info">%1$s (%2$s)</string>
+
+    <string name="bootstrap_migration_enter_backup_password">Inserisci la password del backup chiavi per continuare.</string>
+    <string name="bootstrap_migration_use_recovery_key">usare la chiave di ripristino del backup chiavi</string>
+    <string name="bootstrap_migration_with_passphrase_helper_with_link">Non conosci la password del backup chiavi, puoi %s.</string>
+    <string name="bootstrap_migration_backup_recovery_key">Chiave di ripristino del backup chiavi</string>
+
+    <string name="settings_security_prevent_screenshots_title">Impedisci la cattura di schermate dell\'app</string>
+    <string name="settings_security_prevent_screenshots_summary">Attivandolo verrà aggiunto FLAG_SECURE a tutte le Activity. Riavvia l\'applicazione per applicare le modifiche.</string>
+
+    <string name="media_file_added_to_gallery">File multimediale aggiunto alla galleria</string>
+    <string name="error_adding_media_file_to_gallery">Impossibile aggiungere il file multimediale alla galleria</string>
+    <string name="change_password_summary">Imposta una nuova password dell\'account…</string>
+
+    <string name="use_other_session_content_description">Usa l\'ultima versione di Riot sui tuoi altri dispositivi, Riot Web, Riot Desktop, Riot iOS, RiotX per Android o un altro client Matrix che supporti la firma incrociata</string>
+    <string name="riot_desktop_web">Riot Web
+\nRiot Desktop</string>
+    <string name="riot_ios_android">Riot iOS
+\nRiot X per Android</string>
+    <string name="or_other_mx_capabale_client">o un altro client Matrix che supporti la firma incrociata</string>
+    <string name="use_latest_riot">Usa l\'ultimo Riot sui tuoi altri dispositivi:</string>
+    <string name="command_description_discard_session">Forza l\'attuale sessione di gruppo in uscita in una stanza cifrata ad essere scartata</string>
+    <string name="command_description_discard_session_not_handled">Supportato solo nelle stanze cifrate</string>
+    <string name="enter_secret_storage_passphrase_or_key">Usa la tua %1$s o la %2$s per continuare.</string>
+    <string name="use_recovery_key">Usa la chiave di recupero</string>
+    <string name="enter_secret_storage_input_key">Seleziona la tua chiave di recupero, oppure inseriscila a mano digitandola o incollando dagli appunti</string>
+    <string name="keys_backup_recovery_key_error_decrypt">Impossibile decifrare il backup con questa chiave di recupero: verifica di avere inserito la chiave giusta.</string>
+    <string name="failed_to_access_secure_storage">Accesso all\'archivio sicuro fallito</string>
+
+    <string name="unencrypted">Non cifrato</string>
+    <string name="encrypted_unverified">Cifrato da un dispositivo non verificato</string>
+    <string name="review_logins">Controlla dove hai fatto l\'accesso</string>
+    <string name="verify_other_sessions">Verifica tutte le tue sessioni per assicurarti che il tuo account e i messaggi siano protetti</string>
+    <string name="verify_this_session">Verifica il nuovo accesso entrando nel tuo account: %1$s</string>
+
+    <string name="cross_signing_verify_by_text">Verifica manualmente con testo</string>
+    <string name="crosssigning_verify_session">Verifica accesso</string>
+    <string name="cross_signing_verify_by_emoji">Verifica interattivamente con emoji</string>
+    <string name="confirm_your_identity">Conferma la tua identità verificando questo accesso da una delle tua altre sessioni, dandole l\'accesso ai messaggi cifrati.</string>
+    <string name="mark_as_verified">Segna come fidato</string>
+
+    <string name="error_empty_field_choose_user_name">Scegli un nome utente.</string>
+    <string name="error_empty_field_choose_password">Scegli una password.</string>
+    <string name="external_link_confirmation_title">Verifica questo collegamento</string>
+    <string name="external_link_confirmation_message">Il collegamento %1$s ti sta portando ad un altro sito: %2$s.
+\n
+\nSei sicuro di volere continuare\?</string>
+
+    <string name="create_room_dm_failure">Impossibile creare il messaggio diretto. Controlla gli utenti che vuoi invitare e riprova.</string>
 </resources>
diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml
index c44c400208..6507c31620 100644
--- a/vector/src/main/res/values-ja/strings.xml
+++ b/vector/src/main/res/values-ja/strings.xml
@@ -1071,4 +1071,10 @@ Matrixでのメッセージの可視性は電子メールと同様です。メ
     <string name="keys_backup_info_title_algorithm">アルゴリズム</string>
     <string name="keys_backup_info_title_signature">署名</string>
 
+    <string name="settings_notification_troubleshoot">通知に関する問題の解決</string>
+    <string name="settings_troubleshoot_test_system_settings_title">システム設定</string>
+    <string name="settings_troubleshoot_test_account_settings_title">アカウント設定</string>
+    <string name="settings_troubleshoot_test_bing_settings_title">カスタム設定</string>
+    <string name="settings_troubleshoot_test_service_boot_title">起動時の実行</string>
+    <string name="settings_troubleshoot_test_bg_restricted_title">バックグラウンド制限の確認</string>
 </resources>
diff --git a/vector/src/main/res/values-nb-rNO/strings.xml b/vector/src/main/res/values-nb-rNO/strings.xml
new file mode 100644
index 0000000000..54cac5a112
--- /dev/null
+++ b/vector/src/main/res/values-nb-rNO/strings.xml
@@ -0,0 +1,726 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<resources>
+    <string name="resources_language">nb</string>
+    <string name="resources_country_code">NO</string>
+    <string name="resources_script">Latn</string>
+
+    <string name="light_theme">Lyst tema</string>
+    <string name="dark_theme">Mørkt tema</string>
+    <string name="black_them">Svart tema</string>
+    <string name="notification_sync_init">Klargjør tjenesten</string>
+    <string name="notification_sync_in_progress">Synkroniserer …</string>
+    <string name="title_activity_home">Meldinger</string>
+    <string name="title_activity_room">Rom</string>
+    <string name="title_activity_settings">Innstillinger</string>
+    <string name="title_activity_member_details">Medlemsdetaljer</string>
+    <string name="title_activity_historical">Historisk</string>
+    <string name="title_activity_bug_report">Feilrapport</string>
+    <string name="title_activity_choose_sticker">Send et klistremerke</string>
+    <string name="are_you_sure">Er du sikker\?</string>
+    <string name="loading">Laster…</string>
+
+    <string name="ok">OK</string>
+    <string name="cancel">Lukk</string>
+    <string name="save">Lagre</string>
+    <string name="leave">Forlat</string>
+    <string name="send">Send</string>
+    <string name="copy">Kopier</string>
+    <string name="resend">Send på nytt</string>
+    <string name="redact">Fjern</string>
+    <string name="quote">Sitering</string>
+    <string name="download">Nedlastning</string>
+    <string name="share">Del</string>
+    <string name="clear">Tøm</string>
+    <string name="later">Senere</string>
+    <string name="forward">Neste</string>
+    <string name="permalink">Permalenke</string>
+    <string name="view_source">Vis kilden</string>
+    <string name="delete">Slett</string>
+    <string name="rename">Endre navn</string>
+    <string name="none">Ingen</string>
+    <string name="revoke">Tilbakekall</string>
+    <string name="disconnect">Koble fra</string>
+    <string name="ongoing_conference_call_voice">Stemme</string>
+    <string name="ongoing_conference_call_video">Film</string>
+    <string name="or">eller</string>
+    <string name="invite">Inviter</string>
+    <string name="offline">Frakoblet</string>
+    <string name="accept">Godta</string>
+    <string name="skip">Hopp over</string>
+    <string name="done">Fullført</string>
+    <string name="abort">Løp vekk</string>
+    <string name="ignore">Ignorer</string>
+    <string name="review">Gjennomgang</string>
+    <string name="decline">Avslå</string>
+
+    <string name="action_exit">Avslutt</string>
+    <string name="actions">Handlinger</string>
+    <string name="action_sign_out">Logg ut</string>
+    <string name="action_historical">Historisk</string>
+    <string name="action_close">Lukk</string>
+    <string name="copied_to_clipboard">Kopiert til utklippstavle</string>
+    <string name="disable">Slå av</string>
+
+    <string name="dialog_title_warning">Advarsel</string>
+    <string name="dialog_title_error">Feil</string>
+
+    <string name="bottom_action_home">Hjem</string>
+    <string name="bottom_action_people">Folk</string>
+    <string name="bottom_action_rooms">Rom</string>
+    <string name="bottom_action_groups">Samfunn</string>
+
+    <string name="invitations_header">Invitasjoner</string>
+    <string name="low_priority_header">Lavprioritet</string>
+    <string name="no_result_placeholder">Ingen treff</string>
+    <string name="rooms_header">Rom</string>
+    <string name="no_room_placeholder">Ingen rom</string>
+    <string name="groups_invite_header">Inviter</string>
+    <string name="groups_header">Samfunn</string>
+    <string name="no_group_placeholder">Ingen grupper</string>
+
+    <string name="send_bug_report">Meld fra om en bug</string>
+    <string name="send_bug_report_progress">Fremgang (%s%%)</string>
+
+    <string name="read_receipt">Les</string>
+
+    <string name="join_room">Bli med i rommet</string>
+    <string name="username">Brukernavn</string>
+    <string name="create_account">Opprett konto</string>
+    <string name="login">Logg inn</string>
+    <string name="logout">Logg ut</string>
+    <string name="identity_url">Identitetstjener-URL</string>
+    <string name="search">Søk</string>
+
+    <string name="option_take_photo">Ta et bilde</string>
+    <string name="option_take_video">Spill inn en video</string>
+
+    <string name="auth_login">Logg inn</string>
+    <string name="auth_register">Opprett konto</string>
+    <string name="auth_submit">Send</string>
+    <string name="auth_skip">Hopp over</string>
+    <string name="auth_return_to_login">Gå tilbake til påloggingsskjermen</string>
+    <string name="auth_password_placeholder">Passord</string>
+    <string name="auth_new_password_placeholder">Nytt passord</string>
+    <string name="auth_email_placeholder">E-postadresse</string>
+    <string name="auth_phone_number_placeholder">Telefonnummer</string>
+    <string name="auth_invalid_token">Ugyldig token</string>
+    <string name="auth_forgot_password">Glemt passord\?</string>
+    <string name="auth_reset_password_next_step_button">Jeg har verifisert E-postadressen min</string>
+    <string name="login_error_invalid_home_server">Vennligst skriv inn en gyldig URL</string>
+    <string name="login_mobile_device">Mobil</string>
+
+    <string name="compression_opt_list_original">Original</string>
+    <string name="compression_opt_list_large">Store</string>
+    <string name="compression_opt_list_medium">Medium</string>
+    <string name="compression_opt_list_small">Små</string>
+
+    <string name="yesterday">I går</string>
+    <string name="today">I dag</string>
+
+    <string name="permissions_rationale_popup_title">Informasjon</string>
+    <string name="media_slider_saved">Lagret</string>
+    <string name="yes">JA</string>
+    <string name="no">NEI</string>
+    <string name="_continue">Fortsett</string>
+
+    <string name="remove">Fjern</string>
+    <string name="join">Bli med</string>
+    <string name="preview">Forhåndsvisning</string>
+    <string name="reject">Avvis</string>
+
+    <string name="room_sync_in_progress">Synkroniserer …</string>
+    <plurals name="format_time_s">
+        <item quantity="one">1sek</item>
+        <item quantity="other">%dsek</item>
+    </plurals>
+    <plurals name="format_time_m">
+        <item quantity="one">1m</item>
+        <item quantity="other">%dm</item>
+    </plurals>
+    <plurals name="format_time_h">
+        <item quantity="one">1t</item>
+        <item quantity="other">%dt</item>
+    </plurals>
+    <plurals name="format_time_d">
+        <item quantity="one">1d</item>
+        <item quantity="other">%dd</item>
+    </plurals>
+
+    <string name="room_participants_create">Lag</string>
+
+    <string name="room_participants_online">Tilkoblet</string>
+    <string name="room_participants_offline">Frakoblet</string>
+    <string name="room_participants_idle">Rolig</string>
+    <string name="room_participants_action_invite">Inviter</string>
+    <string name="room_participants_action_ban">Utesteng</string>
+    <string name="room_participants_action_unban">Opphev utestengelse</string>
+    <string name="room_participants_action_kick">Spark ut</string>
+    <string name="room_participants_invite_join_names_combined">%1$s %2$s</string>
+
+    <string name="room_menu_search">Søk</string>
+    <string name="room_message_file_not_found">Filen ble ikke funnet</string>
+    <string name="ssl_trust">Stol på</string>
+    <string name="ssl_logout_account">Logg ut</string>
+    <string name="ssl_remain_offline">Ignorer</string>
+    <string name="room_details_people">Folk</string>
+    <string name="room_details_files">Filer</string>
+    <string name="room_details_settings">Instillinger</string>
+    <string name="room_details_people_present_group_name">BLE MED</string>
+
+    <string name="room_event_action_cancel_upload">Avbryt opplastning</string>
+    <string name="room_event_action_cancel_download">Avbryt nedlasting</string>
+
+    <string name="search_no_results">Ingen treff</string>
+    <string name="tab_title_search_rooms">ROM</string>
+    <string name="room_recents_conversations">ROM</string>
+    <string name="room_settings_mute">Demp</string>
+    <string name="room_settings_direct_chat">Direktesamtale</string>
+    <string name="room_settings_forget">Glem</string>
+    <string name="room_sliding_menu_messages">Meldinger</string>
+    <string name="room_sliding_menu_settings">Instillinger</string>
+    <string name="room_sliding_menu_version">Versjon</string>
+    <string name="room_sliding_menu_version_x">Versjn %s</string>
+    <string name="room_sliding_menu_copyright">Opphavsrettighet</string>
+    <string name="settings_profile_picture">Profilbilde</string>
+    <string name="settings_display_name">Visningsnavn</string>
+    <string name="settings_email_address">E-post</string>
+    <string name="settings_phone_number">Telefon</string>
+    <string name="open_settings">Åpne Innstillinger</string>
+
+    <string name="settings_troubleshoot_test_account_settings_quickfix">Slå på</string>
+
+    <string name="settings_troubleshoot_test_device_settings_quickfix">Slå på</string>
+
+    <string name="settings_notification_privacy_normal">Vanlig</string>
+    <string name="settings_notification_ringtone">Varslingslyd</string>
+    <string name="settings_seconds">sekunder</string>
+
+    <string name="settings_version">Versjon</string>
+    <string name="settings_copyright">Opphavsrettighet</string>
+    <string name="settings_privacy_policy">Retningslinjer for personvern</string>
+    <string name="settings_clear_cache">Tøm mellomlageret</string>
+    <string name="settings_notifications">Varsler</string>
+    <string name="settings_other">Annet</string>
+    <string name="settings_advanced">Avansert</string>
+    <string name="settings_cryptography">Kryptografi</string>
+    <string name="settings_contact">Lokale kontakter</string>
+    <string name="settings_devices_list">Sesjoner</string>
+    <string name="settings_send_typing_notifs">Send varsler om at du skriver</string>
+    <string name="settings_analytics">Analyser</string>
+    <string name="settings_opt_in_of_analytics">Send analytiske data</string>
+    <string name="settings_opt_in_of_analytics_ok">Ja, jeg vil hjelpe til!</string>
+
+    <string name="devices_details_id_title">ID</string>
+    <string name="devices_details_name_title">Offentlig navn</string>
+    <string name="devices_details_last_seen_title">Sist sett</string>
+    <string name="devices_delete_dialog_title">Autentisering</string>
+    <string name="devices_delete_pswd">Passord:</string>
+    <string name="devices_delete_submit_button_label">Send</string>
+
+    <string name="settings_logged_in">Logget inn som</string>
+    <string name="settings_identity_server">Identitetstjener</string>
+    <string name="settings_user_interface">Brukergrensesnitt</string>
+    <string name="settings_interface_language">Språk</string>
+    <string name="settings_password">Passord</string>
+    <string name="settings_change_password">Endre passord</string>
+    <string name="settings_old_password">Nåværende passord</string>
+    <string name="settings_new_password">Nytt passord</string>
+    <string name="settings_confirm_password">Bekreft nytt passord</string>
+    <string name="passwords_do_not_match">Passordene er ikke like</string>
+
+    <string name="settings_phone_number_country_label">Land</string>
+    <string name="settings_phone_number_label">Telefonnummer</string>
+    <string name="settings_phone_number_code">Kode</string>
+    <string name="settings_media">Media</string>
+    <string name="compression_opt_list_choose">Velg</string>
+    <string name="media_source_choose">Velg</string>
+    <string name="settings_flair">Merkeskilt</string>
+    <string name="media_saving_period_3_days">3 dager</string>
+    <string name="media_saving_period_1_week">1 uke</string>
+    <string name="media_saving_period_1_month">1 måned</string>
+    <string name="media_saving_period_forever">For alltid</string>
+
+    <string name="room_settings_topic">Emne</string>
+    <string name="room_settings_tag_pref_entry_low_priority">Lavprioritet</string>
+    <string name="room_settings_tag_pref_entry_none">Ingen</string>
+
+    <string name="room_settings_room_notifications_title">Varsler</string>
+    <string name="room_settings_read_history_entry_anyone">Alle</string>
+    <string name="room_settings_banned_users_title">Bannlyste brukere</string>
+
+    <string name="room_settings_category_advanced_title">Avansert</string>
+    <string name="room_settings_addresses_pref_title">Adresser</string>
+    <string name="directory_title">Mappe</string>
+    <string name="settings_theme">Tema</string>
+
+    <string name="encryption_information_device_info">Hendelsesinformasjon</string>
+    <string name="encryption_information_user_id">Bruker-ID</string>
+    <string name="encryption_information_algorithm">Algoritme</string>
+    <string name="encryption_information_session_id">Økt-ID</string>
+    <string name="device_name_warning">Det offentlige navnet til en økt er synlig for folkene du kommuniserer med</string>
+    <string name="encryption_information_device_id">ID</string>
+    <string name="encryption_information_device_key">Øktnøkkel</string>
+    <string name="encryption_information_verification">Verifisering</string>
+    <string name="encryption_export_export">Eksporter</string>
+    <string name="encryption_import_import">Importer</string>
+    <string name="encryption_information_blocked">Svartelistet</string>
+
+    <string name="encryption_information_none">ingen</string>
+
+    <string name="encryption_information_verify">Bekreft</string>
+    <string name="encryption_information_block">Svarteliste</string>
+    <string name="directory_server_placeholder">Hjemmetjener-URL</string>
+    <string name="lock_screen_hint">Skriv her …</string>
+
+    <string name="notification_unknown_room_name">Rom</string>
+    <string name="notification_sender_me">Meg</string>
+    <string name="font_size">Skriftstørrelse</string>
+    <string name="small">Små</string>
+    <string name="normal">Vanlig</string>
+    <string name="large">Store</string>
+    <string name="larger">Større</string>
+    <string name="largest">Det største</string>
+    <string name="huge">Enorm</string>
+
+    <string name="room_widget_open_in_browser">Åpne i nettleser</string>
+    <string name="room_widget_permission_user_id">Din bruker-ID</string>
+    <string name="room_widget_permission_theme">Ditt tema</string>
+    <string name="room_widget_permission_widget_id">Modul-ID</string>
+    <string name="room_widget_permission_room_id">Rom-ID</string>
+
+
+    <string name="room_widget_resource_grant_permission">Tillat</string>
+    <string name="start_verification_short_label">Bekreft</string>
+    <string name="share_without_verifying_short_label">Del</string>
+    <string name="ignore_request_short_label">Ignorer</string>
+
+    <string name="notification_off">Av</string>
+    <string name="create">Lag</string>
+    <string name="community_name_hint">Eksempel</string>
+    <string name="community_id_hint">eksempel</string>
+
+    <string name="group_details_home">Hjem</string>
+    <string name="group_details_people">Folk</string>
+    <string name="joined">Ble med</string>
+    <string name="invited">Invitert</string>
+    <string name="rejoin">Bli med igjen</string>
+    <string name="forget_room">Glem rommet</string>
+
+    <string name="avatar">Profilbilde</string>
+
+    <string name="deactivate_account_title">Deaktiver kontoen</string>
+    <string name="deactivate_account_submit">Deaktiver kontoen</string>
+
+    <string name="error_empty_field_enter_user_name">Vennligst skriv inn et brukernavn.</string>
+    <string name="merged_events_expand">utvid</string>
+    <string name="merged_events_collapse">skjul</string>
+
+    <string name="show_info_area_always">Alltid</string>
+    <string name="generic_label">%1$s:</string>
+    <string name="generic_label_and_value">%1$s: %2$s</string>
+    <string name="keys_backup_setup_step1_title">Aldri mist krypterte beskjeder</string>
+    <string name="keys_backup_setup_step3_button_title">Fullført</string>
+    <string name="keys_backup_setup_step3_share_recovery_file">Del</string>
+    <string name="keys_backup_setup_step3_save_button_title">Lagre som fil</string>
+    <string name="keys_backup_setup_override_replace">Erstatt</string>
+    <string name="keys_backup_setup_override_stop">Stopp</string>
+
+    <string name="unexpected_error">Uventet feil</string>
+    <string name="keys_backup_setup_skip_title">Er du sikker\?</string>
+    <string name="keys_backup_banner_setup_line1">Aldri mist krypterte beskjeder</string>
+    <string name="keys_backup_banner_recover_line1">Aldri mist krypterte beskjeder</string>
+    <string name="keys_backup_info_title_version">Versjon</string>
+    <string name="keys_backup_info_title_algorithm">Algoritme</string>
+    <string name="keys_backup_info_title_signature">Signatur</string>
+
+    <string name="sas_verified">Verifisert!</string>
+    <string name="sas_got_it">Jeg forstår</string>
+
+    <string name="sas_incoming_request_notif_title">Verifiseringsforespørsel</string>
+    <string name="sas_error_unknown">Ukjent feil</string>
+
+    <string name="edit">Rediger</string>
+    <string name="reply">Svar</string>
+
+    <string name="global_retry">Prøv igjen</string>
+    <string name="invited_by">Invitert av %s</string>
+
+    <string name="title_activity_emoji_reaction_picker">Reaksjoner</string>
+    <string name="reactions_like">Like</string>
+    <string name="reactions">Reaksjoner</string>
+
+    <string name="action_change">Endre</string>
+    <string name="please_wait">Vennligst vent …</string>
+    <string name="create_room_title">Nytt rom</string>
+    <string name="create_room_public_title">Offentlig</string>
+    <string name="settings_general_title">Generelt</string>
+    <string name="settings_preferences">Brukervalg</string>
+    <string name="settings_security_and_privacy">Sikkerhet og personvern</string>
+    <string name="settings_expert">Ekspert</string>
+    <string name="push_gateway_item_format">Format:</string>
+
+    <string name="preference_voice_and_video">Stemme og video</string>
+    <string name="preference_root_help_about">Hjelp/Om</string>
+
+
+    <string name="settings_labs_show_hidden_events_in_timeline">Vis skjulte hendelser i tidslinjen</string>
+
+    <string name="send_file_step_idle">Venter …</string>
+    <string name="edited_suffix">(redigert)</string>
+
+    <string name="terms_of_service">Vilkår for bruk</string>
+    <string name="change_identity_server">Bytt ut identitetstjener</string>
+    <string name="settings_discovery_mail_pending">Venter</string>
+
+    <string name="a11y_create_room">Opprett et nytt rom</string>
+    <string name="a11y_show_password">Vis passord</string>
+    <string name="a11y_hide_password">Skjul passord</string>
+    <string name="attachment_type_file">Fil</string>
+    <string name="attachment_type_contact">Kontakt oss</string>
+    <string name="attachment_type_camera">Kamera</string>
+    <string name="attachment_type_audio">Lyd</string>
+    <string name="attachment_type_gallery">Galleri</string>
+    <string name="room_list_quick_actions_notifications_mute">Demp</string>
+    <string name="room_list_quick_actions_settings">Instillinger</string>
+    <string name="login_server_modular_learn_more">Lær mer</string>
+    <string name="login_server_other_title">Annet</string>
+    <string name="login_continue">Fortsett</string>
+    <string name="login_signup">Registrer deg</string>
+    <string name="login_signin">Logg inn</string>
+    <string name="login_signin_sso">Fortsett med SSO</string>
+
+    <string name="login_reset_password_submit">Neste</string>
+    <string name="login_reset_password_email_hint">E-post</string>
+    <string name="login_reset_password_password_hint">Nytt passord</string>
+
+    <string name="login_reset_password_warning_submit">Fortsett</string>
+
+    <string name="login_reset_password_mail_confirmation_submit">Jeg har verifisert E-postadressen min</string>
+
+    <string name="login_reset_password_success_title">Suksess!</string>
+    <string name="login_reset_password_success_notice">Passordet ditt har blitt tilbakestilt.</string>
+    <string name="login_reset_password_cancel_confirmation_title">Advarsel</string>
+    <string name="login_set_email_mandatory_hint">E-post</string>
+    <string name="login_set_email_optional_hint">E-post (valgfritt)</string>
+    <string name="login_set_email_submit">Neste</string>
+
+    <string name="login_set_msisdn_mandatory_hint">Telefonnummer</string>
+    <string name="login_set_msisdn_submit">Neste</string>
+
+    <string name="login_msisdn_confirm_hint">Skriv inn kode</string>
+    <string name="login_msisdn_confirm_submit">Neste</string>
+
+    <string name="login_signup_username_hint">Brukernavn</string>
+    <string name="login_signup_password_hint">Passord</string>
+    <string name="login_signup_submit">Neste</string>
+    <string name="login_signup_cancel_confirmation_title">Advarsel</string>
+    <string name="login_wait_for_email_title">Vennligst sjekk eposten din</string>
+    <string name="seen_by">Sett av</string>
+
+    <string name="soft_logout_signin_title">Logg på</string>
+    <string name="soft_logout_signin_submit">Logg på</string>
+    <string name="soft_logout_signin_password_hint">Passord</string>
+    <string name="settings">Instillinger</string>
+    <string name="devices_current_device">Gjeldende økt</string>
+    <string name="command_description_shrug">Føyer til ¯\\_(ツ)_/¯ på en råtekstmelding</string>
+
+    <string name="sent_a_video">Video.</string>
+    <string name="sent_an_image">Bilde.</string>
+    <string name="sent_an_audio_file">Lyd</string>
+    <string name="sent_a_file">Fil</string>
+
+    <string name="verification_request_you_cancelled">Du avbrøt</string>
+    <string name="verification_request_you_accepted">Du aksepterte</string>
+    <string name="verification_request">Verifiseringsforespørsel</string>
+
+
+    <string name="you">Du</string>
+
+    <string name="verification_verify_user">Verifiser %s</string>
+    <string name="verification_verified_user">Verifiserte %s</string>
+    <string name="room_profile_section_security">Sikkerhet</string>
+    <string name="room_profile_section_security_learn_more">Lær mer</string>
+    <string name="room_profile_section_more">Mer</string>
+    <string name="room_profile_section_more_notifications">Varsler</string>
+    <string name="room_profile_section_more_uploads">Opplastinger</string>
+    <string name="room_member_power_level_moderators">Ordstyrere</string>
+    <string name="room_member_power_level_custom">Tilpasset</string>
+    <string name="room_member_power_level_invites">Invitasjoner</string>
+    <string name="room_member_power_level_users">Brukere</string>
+
+    <string name="unignore">Opphev ignorering</string>
+
+    <string name="settings_category_timeline">Tidslinje</string>
+
+    <string name="room_settings_enable_encryption_dialog_title">Vil du skru på kryptering\?</string>
+    <string name="verification_profile_verify">Bekreft</string>
+    <string name="verification_profile_warning">Advarsel</string>
+
+    <string name="room_member_profile_sessions_section_title">Sesjoner</string>
+    <string name="qr_code_scanned_by_other_yes">Ja</string>
+    <string name="enter_secret_storage_passphrase_warning">Advarsel:</string>
+    <string name="delete_event_dialog_title">Bekreft fjerning</string>
+    <string name="status_theme">Status.im-tema</string>
+
+    <string name="notification_listening_for_events">Lytter etter hendelser</string>
+    <string name="title_activity_verify_device">Verifiser økten</string>
+
+    <string name="active_call">Aktiv samtale</string>
+    <string name="send_bug_report_include_logs">Send loggbøker</string>
+    <string name="auth_send_reset_email">Send tilbakestillings-E-post</string>
+    <string name="auth_username_in_use">Brukernavnet er i bruk</string>
+    <string name="auth_home_server">Hjemmetjener:</string>
+    <string name="auth_identity_server">Identitetstjener:</string>
+    <string name="settings_call_category">Samtaler</string>
+    <plurals name="room_title_members">
+        <item quantity="one">1 medlem</item>
+        <item quantity="other">%d medlemmer</item>
+    </plurals>
+    <string name="room_title_one_member">1 medlem</string>
+
+    <string name="room_participants_now">%1$s nå</string>
+    <string name="room_one_user_is_typing">%s skriver …</string>
+    <string name="search_hint">Søk</string>
+    <string name="search_members_hint">Filtrer rommets medlemmer</string>
+    <plurals name="directory_search_rooms">
+        <item quantity="one">1 rom</item>
+        <item quantity="other">%d rom</item>
+    </plurals>
+    <string name="room_settings_all_messages">Alle meldinger</string>
+    <string name="room_settings_mention_only">Kun nevninger</string>
+    <string name="settings_olm_version">olm-versjon</string>
+    <string name="settings_deactivate_account_section">Deaktiver kontoen</string>
+    <string name="settings_opt_in_of_analytics_summary">Riot samler inn anonyme statistikker for å hjelpe oss med å forbedre programmet.</string>
+    <string name="devices_details_last_seen_format">%1$s @ %2$s</string>
+    <string name="settings_integration_manager">Integreringsbehandler</string>
+
+    <string name="room_settings_room_name">Rommets navn</string>
+    <string name="room_settings_room_read_history_rules_pref_dialog_title">Hvem kan lese historikken\?</string>
+    <string name="room_settings_room_access_rules_pref_dialog_title">Hvem kan gå inn i dette rommet\?</string>
+
+    <string name="room_settings_read_history_entry_members_only_option_time_shared">Kun medlemmer (f.o.m. da denne innstillingen ble valgt)</string>
+    <string name="room_settings_read_history_entry_members_only_invited">Kun medlemmer (f.o.m. da de ble invitert)</string>
+    <string name="room_settings_read_history_entry_members_only_joined">Kun medlemmer (f.o.m. de ble med)</string>
+
+    <string name="room_settings_room_access_entry_only_invited">Kun folk som har blitt invitert</string>
+    <string name="room_settings_no_flair">Dette rommet viser ikke merkeskilter for noen samfunn</string>
+    <string name="room_settings_copy_room_id">Kopier rommets ID</string>
+    <string name="encryption_export_e2e_room_keys">Eksporter E2E-romnøkler</string>
+    <string name="encryption_export_room_keys">Eksporter romnøkler</string>
+    <string name="encryption_import_e2e_room_keys">Importer E2E-romnøkler</string>
+    <string name="encryption_import_room_keys">Importer romnøkler</string>
+    <string name="encryption_information_verified">Verifisert</string>
+    <string name="encryption_information_unverify">Av-verifiser</string>
+    <string name="encryption_information_verify_device">Verifiser økten</string>
+    <plurals name="notification_unread_notified_messages_in_room_rooms">
+        <item quantity="one">1 rom</item>
+        <item quantity="other">%d rom</item>
+    </plurals>
+
+    <plurals name="notification_compat_summary_line_for_room">
+        <item quantity="one">%1$s: 1 melding</item>
+        <item quantity="other">%1$s: %2$d meldinger</item>
+    </plurals>
+    <plurals name="notification_compat_summary_title">
+        <item quantity="one">%d varsel</item>
+        <item quantity="other">%d varsler</item>
+    </plurals>
+
+    <string name="notification_unknown_new_event">Ny hendelse</string>
+    <string name="notification_new_messages">Nye meldinger</string>
+    <string name="notification_new_invitation">Ny invitasjon</string>
+    <string name="tiny">Bitteliten</string>
+    <plurals name="active_widgets">
+        <item quantity="one">1 aktiv modul</item>
+        <item quantity="other">%d aktive moduler</item>
+    </plurals>
+
+
+    <string name="room_widget_activity_title">Modul</string>
+    <string name="room_widget_permission_title">Last inn modul</string>
+    <string name="room_widget_permission_display_name">Ditt visningsnavn</string>
+    <string name="room_widget_permission_avatar_url">Din avatars URL</string>
+    <string name="room_add_matrix_apps">Legg til Matrix-apper</string>
+    <string name="start_verification">Begynn verifisering</string>
+    <string name="conference_call_warning_title">Advarsel!</string>
+    <string name="command_error">Kommandofeil</string>
+    <string name="command_description_part_room">Forlat rommet</string>
+    <string name="command_description_topic">Velg rommets tema</string>
+    <string name="notification_silent">Stille</string>
+    <string name="notification_noisy">Bråkete</string>
+
+    <string name="encrypted_message">Kryptert melding</string>
+
+    <string name="create_community">Opprett et samfunn</string>
+    <string name="community_name">Samfunnsnavn</string>
+    <string name="community_id">Samfunns-ID</string>
+    <string name="group_details_rooms">Rom</string>
+    <string name="no_users_placeholder">Ingen brukere</string>
+
+    <string name="rooms">Rom</string>
+    <plurals name="group_members">
+        <item quantity="one">1 medlem</item>
+        <item quantity="other">%d medlemmer</item>
+    </plurals>
+
+    <plurals name="group_rooms">
+        <item quantity="one">1 rom</item>
+        <item quantity="other">%d rom</item>
+    </plurals>
+    <string name="reason_colon">Årsak: %1$s</string>
+    <string name="deactivate_account_prompt_password">For å gå videre, vennligst skriv inn passordet ditt:</string>
+    <string name="plus_x">+%d</string>
+    <string name="x_plus">%d+</string>
+    <string name="keys_backup_setup">Begynn å bruke Nøkkelsikkerhetskopiering</string>
+    <string name="new_recovery_method_popup_was_me">Det var meg</string>
+    <string name="keys_backup_banner_setup_line2">Begynn å bruke Nøkkelsikkerhetskopiering</string>
+
+    <string name="send_you_invite">Sendte deg en invitasjon</string>
+    <string name="room_list_rooms_empty_title">Rom</string>
+    <string name="create_new_room">Opprett et nytt rom</string>
+    <string name="fab_menu_create_room">Rom</string>
+    <string name="fab_menu_create_chat">Direktemeldinger</string>
+
+    <string name="create_room_name_hint">Rommets navn</string>
+    <string name="alpha_disclaimer_title">Velkommen til betaen!</string>
+    <string name="push_gateway_item_url">URL:</string>
+    <string name="bottom_action_people_x">Direktemeldinger</string>
+
+    <string name="message_edits">Meldingsredigeringer</string>
+    <string name="room_filtering_filter_hint">Filtrer samtaler …</string>
+    <string name="room_filtering_footer_create_new_room">Opprett et nytt rom</string>
+    <string name="joining_room">Blir med i rommet …</string>
+
+    <string name="identity_server">Identitetstjener</string>
+    <string name="settings_discovery_enter_identity_server">Skriv inn en ny identitetstjener</string>
+    <string name="send_attachment">Send vedlegg</string>
+
+    <string name="attachment_type_sticker">Klistremerke</string>
+    <string name="report_content_spam">Det er søppelpost</string>
+    <string name="room_list_quick_actions_notifications_all">Alle meldinger</string>
+    <string name="room_list_quick_actions_notifications_mentions">Kun nevninger</string>
+    <string name="room_list_quick_actions_leave">Forlat rommet</string>
+    <string name="timeline_unread_messages">Uleste meldinger</string>
+
+    <string name="login_splash_submit">Kom i gang</string>
+
+    <string name="login_server_title">Velg en tjener</string>
+    <string name="login_reset_password_on">Tilbakestill passordet på %1$s</string>
+    <string name="login_reset_password_warning_title">Advarsel!</string>
+    <string name="login_set_email_title">Velg en E-postadresse</string>
+    <string name="login_set_msisdn_title">Velg et telefonnummer</string>
+    <string name="login_terms_title">Godkjenn vilkårene for å fortsette</string>
+
+    <string name="settings_advanced_settings">Avanserte innstillinger</string>
+    <string name="settings_developer_mode">Utviklermodus</string>
+    <string name="create_room_encryption_description">Dersom dette først har blitt skrudd på, kan kryptering aldri bli skrudd av.</string>
+
+    <string name="verification_sas_match">De samsvarer</string>
+    <string name="verification_conclusion_not_secure">Ikke sikker</string>
+    <string name="verification_request_waiting">Venter …</string>
+    <string name="verification_verify_device">Verifiser denne økten</string>
+    <string name="a13n_qr_code_description">QR-kodebilde</string>
+
+    <string name="room_profile_section_more_leave">Forlat rommet</string>
+    <string name="room_profile_leaving_room">Forlater rommet …</string>
+
+    <string name="room_settings_enable_encryption_warning">Dersom dette først har blitt skrudd på, kan kryptering aldri bli skrudd av.</string>
+
+    <string name="settings_active_sessions_list">Aktive økter</string>
+    <string name="settings_active_sessions_show_all">Vis alle økter</string>
+    <string name="settings_active_sessions_manage">Behandle økter</string>
+    <string name="crosssigning_verify_this_session">Verifiser denne økten</string>
+    <string name="verification_profile_verified">Verifisert</string>
+    <string name="trusted">Betrodd</string>
+    <string name="not_trusted">Ikke betrodd</string>
+
+    <string name="a11y_qr_code_for_verification">QR-kode</string>
+
+    <string name="qr_code_scanned_by_other_no">Nei</string>
+
+    <string name="settings_dev_tools">Utviklerverktøy</string>
+    <string name="new_signin">Ny innlogging</string>
+
+    <string name="message_action_item_redact">Fjern …</string>
+    <string name="notification_noisy_notifications">Bråkete notifikasjoner</string>
+    <string name="notification_silent_notifications">Stille notifikasjoner</string>
+
+    <string name="title_activity_group_details">Samfunnsdetaljer</string>
+    <string name="title_activity_keys_backup_setup">Sikkerhetskopiering av nøkler</string>
+    <string name="title_activity_keys_backup_restore">Bruk sikkerhetskopiering av nøkler</string>
+    <string name="keys_backup_is_not_finished_please_wait">nøkkelbackup er ikke fulllført, vennligst vent…</string>
+    <string name="sign_out_bottom_sheet_warning_no_backup">du kommer til å miste dine enkrypterte meldinger hvis du logger ut nå</string>
+    <string name="sign_out_bottom_sheet_warning_backing_up">Sikkerhetskopiering av nøkler pågår. Hvis du logger ut nå mister du tilgang til dine enkrypterte meldinger.</string>
+    <string name="sign_out_bottom_sheet_warning_backup_not_active">Sikker sikkerhetskopiering av nøkler burde være aktivt på alle øktene dine for å unngå å miste tilgang til dine enkrypterte meldinger.</string>
+    <string name="sign_out_bottom_sheet_dont_want_secure_messages">Jeg vil ikke ha mine enkrypterte meldinger</string>
+    <string name="sign_out_bottom_sheet_backing_up_keys">Sikkerhetskopierer nøkler…</string>
+    <string name="keys_backup_activate">Bruk sikkerhetskopiering av nøkler</string>
+    <string name="backup">Sikkerhetskopi</string>
+    <string name="sign_out_bottom_sheet_will_lose_secure_messages">Du kommer til å miste tilgang til dine enkrypterte meldinger med mindre du sikkerhetskopierer nøklene dine før du logger av.</string>
+
+    <string name="dialog_title_third_party_licences">Tredjepartslinsenser</string>
+
+    <string name="stay">Bli</string>
+    <string name="speak">Snakk</string>
+    <string name="view_decrypted_source">Se dekryptert kilde</string>
+    <string name="report_content">Rapporter innhold</string>
+    <string name="ongoing_conference_call">Pågående konferansesamtale.
+\nBli med som %1$s eller %2$s</string>
+    <string name="cannot_start_call">Kan ikke starte samtalen, vennligst prøv igjen senere</string>
+    <string name="missing_permissions_warning">På grunn av manglende tillatelse, kan noen funksjoner mangle…</string>
+    <string name="missing_permissions_error">Denne handlingen er ikke mulig på grunn av manglende tillatelser.</string>
+    <string name="missing_permissions_to_start_conf_call">Du må ha tillatelse til å invitere for å starte en konferanse i dette rommet</string>
+    <string name="missing_permissions_title_to_start_conf_call">Kan ikke starte samtale</string>
+    <string name="device_information">Informasjon om Økten</string>
+    <string name="room_no_conference_call_in_encrypted_rooms">Konferansesamtaler er ikke støttet i enkrypterte rom</string>
+    <string name="call_anyway">Ring likevel.</string>
+    <string name="send_anyway">Send likevel</string>
+    <string name="action_sign_out_confirmation_simple">Er du sikker på at vil logge ut\?</string>
+    <string name="action_voice_call">Telefonsamtale</string>
+    <string name="action_video_call">Videosamtale</string>
+    <string name="action_global_search">Globalt søk</string>
+    <string name="action_mark_all_as_read">Marker alle som lest</string>
+    <string name="action_quick_reply">Raskt svar</string>
+    <string name="action_mark_room_read">Marker som lest</string>
+    <string name="action_open">Åpne</string>
+    <string name="dialog_title_confirmation">Bekreftelse</string>
+    <string name="bottom_action_favourites">Favoritter</string>
+    <string name="home_filter_placeholder_home">Filtrer romnavn</string>
+    <string name="home_filter_placeholder_favorites">Filtrer favoritter</string>
+    <string name="home_filter_placeholder_people">Filtrer folk</string>
+    <string name="home_filter_placeholder_rooms">Filtrer romnavn</string>
+    <string name="home_filter_placeholder_groups">Filtrer samfunnsnavn</string>
+
+    <string name="system_alerts_header">Systemadvarsler</string>
+
+    <string name="direct_chats_header">Samtaler</string>
+    <string name="local_address_book_header">Lokal adressebok</string>
+    <string name="user_directory_header">Brukerkatalog</string>
+    <string name="matrix_only_filter">Bare matrix-kontakter</string>
+    <string name="no_conversation_placeholder">Ingen samtaler</string>
+    <string name="no_contact_access_placeholder">Du ga ikke Riot tilgang til dine lokale kontakter</string>
+    <string name="people_no_identity_server">Ingen identitetsserver konfigurert.</string>
+
+    <string name="rooms_directory_header">Romkatalog</string>
+    <string name="no_public_room_placeholder">Ingen offentlige rom tilgjengelig</string>
+    <plurals name="public_room_nb_users">
+        <item quantity="one">1 bruker</item>
+        <item quantity="other">%d brukere</item>
+    </plurals>
+
+    <string name="send_bug_report_include_crash_logs">Send kjæsjlogg</string>
+    <string name="send_bug_report_include_screenshot">Send skjermbilde</string>
+    <string name="send_bug_report_description">Vennligst forklar feilen. Hva gjorde du\? Hva forventet du at skulle skje\? Hva skjedde i stedet\?</string>
+    <string name="send_bug_report_description_in_english">Om mulig, vennligst beskriv på engelsk.</string>
+    <string name="send_bug_report_placeholder">Forklar problemet ditt her</string>
+    <string name="send_bug_report_logs_description">For å diagnotisere feil, logger fra denne klienten vil bli sendt med denne feilmeldingen. Feilmeldingen, som inkluderer loggene og skjermdumper, blir ikke offentlig synlig. Hvis du foretrekker å bare sende teksten over, vennligst fjern merkene fra boksene:</string>
+    <string name="send_bug_report_alert_message">Det ser ut som du rister på telefonen i frustrasjon. Har du list til å åpne feilrapporteringsskjermen\?</string>
+    <string name="send_bug_report_app_crashed">Applikasjonen kræsjet sist gang. Har du lyst til å åpne kræsjskjermen\?</string>
+    <string name="send_bug_report_rage_shake">Sinnarist for å rapportere feil</string>
+
+    <string name="send_bug_report_sent">Feilrapport har blitt sendt</string>
+    <string name="send_bug_report_failed">feilrapporten feilet å sendes (%s)</string>
+    <string name="send_files_in">Send inn i</string>
+    <string name="hs_url">Hjemmetjener URL</string>
+    <string name="start_new_chat">Start ny chat</string>
+</resources>
diff --git a/vector/src/main/res/values-nl/strings.xml b/vector/src/main/res/values-nl/strings.xml
index bacc675f86..eac681e604 100755
--- a/vector/src/main/res/values-nl/strings.xml
+++ b/vector/src/main/res/values-nl/strings.xml
@@ -40,7 +40,7 @@
     <string name="missing_permissions_warning">Sommige functies zijn misschien afwezig wegens ontbrekende rechten…</string>
     <string name="missing_permissions_to_start_conf_call">Om een vergadering in dit groepsgesprek te starten heeft u uitnodigingsrechten nodig</string>
     <string name="missing_permissions_title_to_start_conf_call">Kan de oproep niet starten</string>
-    <string name="device_information">Apparaatinformatie</string>
+    <string name="device_information">Sessie-informatie</string>
     <string name="room_no_conference_call_in_encrypted_rooms">Vergadergesprekken worden niet ondersteund in versleutelde gesprekken</string>
     <string name="send_anyway">Toch sturen</string>
     <string name="or">of</string>
@@ -174,9 +174,9 @@
     <string name="auth_reset_password_missing_password">Er moet een nieuw wachtwoord ingevoerd worden.</string>
     <string name="auth_reset_password_email_validation_message">Er is een e-mail verstuurd naar %s. Klik hieronder zodra u de koppeling in de e-mail hebt bezocht.</string>
     <string name="auth_reset_password_error_unauthorized">Verifiëren van het e-mailadres is mislukt: zorg dat u op de koppeling in de e-mail hebt geklikt</string>
-    <string name="auth_reset_password_success_message">Uw wachtwoord is opnieuw ingesteld.
-\n
-\nU bent op alle apparaten afgemeld en zult niet langer pushmeldingen ontvangen. Om meldingen opnieuw in te schakelen, meldt u zich op elk apparaat opnieuw aan.</string>
+    <string name="auth_reset_password_success_message">Uw wachtwoord is opnieuw ingesteld. 
+\n 
+\nU bent op alle sessies afgemeld en zult niet langer pushmeldingen ontvangen. Om meldingen opnieuw in te schakelen, meldt u zich op elk apparaat opnieuw aan.</string>
 
     <!-- Login Screen -->
     <string name="login_error_must_start_http">URL moet met http[s]:// beginnen</string>
@@ -196,8 +196,8 @@
     <string name="login_error_login_email_not_yet">Er is nog niet op de koppeling in de e-mail geklikt</string>
 
     <!-- crypto warnings -->
-    <string name="e2e_need_log_in_again">U moet zich opnieuw aanmelden om de sleutels voor eind-tot-eind-versleuteling voor dit apparaat te genereren, en om de publieke sleutel naar uw thuisserver te sturen.
-\nDit is eenmalig.
+    <string name="e2e_need_log_in_again">U moet zich opnieuw aanmelden om de sleutels voor eind-tot-eind-versleuteling voor deze sessie te genereren, en om de publieke sleutel naar uw thuisserver te sturen. 
+\nDit is eenmalig. 
 \nExcuses voor het ongemak.</string>
 
     <!-- read receipts list Screen -->
@@ -261,12 +261,11 @@
     <string name="permissions_rationale_msg_camera_and_audio">Riot heeft toegang nodig tot uw camera en microfoon om video-oproepen te maken.
 \n
 \nVerleen toegang op de volgende pop-ups om de oproep te maken.</string>
-    <string name="permissions_rationale_msg_contacts">Riot heeft toegang nodig tot uw adresboek om andere Matrix-gebruikers te vinden aan de hand van hun e-mailadressen en telefoonnummers.
-\n
-\nVerleen toegang op de volgende pop-up om gebruikers op Riot te ontdekken via uw adresboek.</string>
-    <string name="permissions_msg_contacts_warning_other_androids">Riot heeft toegang nodig tot uw adresboek om andere Matrix-gebruikers te vinden aan de hand van hun e-mailadressen en telefoonnummers.
-\n
-\nRiot toegang verlenen tot uw contacten\?</string>
+    <string name="permissions_rationale_msg_contacts">Riot kan uw adresboek benaderen om andere Matrix-gebruikers te vinden aan de hand van hun e-mailadressen en telefoonnummers. 
+\nAls u het goed vindt om uw adresboek hiervoor te delen, verleen dan toegang op de volgende pop-up.</string>
+    <string name="permissions_msg_contacts_warning_other_androids">Riot kan uw adresboek gebruiken om andere Matrix-gebruikers te vinden aan de hand van hun e-mailadressen en telefoonnummers. 
+\n 
+\nWilt u uw adresboek hiervoor delen\?</string>
 
     <string name="permissions_action_not_performed_missing_permissions">Sorry. De actie is niet toegepast vanwege ontbrekende rechten</string>
 
@@ -312,7 +311,7 @@
     <string name="room_participants_header_admin_tools">BEHEERDERSGEREEDSCHAPPEN</string>
     <string name="room_participants_header_call">BELLEN</string>
     <string name="room_participants_header_direct_chats">TWEEGESPREKKEN</string>
-    <string name="room_participants_header_devices">APPARATEN</string>
+    <string name="room_participants_header_devices">SESSIES</string>
 
     <string name="room_participants_action_invite">Uitnodigen</string>
     <string name="room_participants_action_leave">Dit gesprek verlaten</string>
@@ -326,7 +325,7 @@
     <string name="room_participants_action_unignore">Alle berichten van deze gebruiker tonen</string>
     <string name="room_participants_invite_search_another_user">Gebruikers-ID, naam of e-mailadres</string>
     <string name="room_participants_action_mention">Vermelden</string>
-    <string name="room_participants_action_devices_list">Lijst met apparaten weergeven</string>
+    <string name="room_participants_action_devices_list">Sessielijst weergeven</string>
     <string name="room_participants_power_level_prompt">U kunt deze veranderingen niet ongedaan maken aangezien u de gebruiker tot hetzelfde niveau als uzelf promoveert.
 \nWeet u het zeker\?</string>
 
@@ -350,7 +349,7 @@
     <string name="room_message_placeholder_encrypted">Verstuur een versleuteld bericht…</string>
     <string name="room_message_placeholder_not_encrypted">Verstuur een bericht (niet versleuteld)…</string>
     <string name="room_unsent_messages_notification">Berichten zijn niet verstuurd. Nu %1$s of %2$s\?</string>
-    <string name="room_unknown_devices_messages_notification">Berichten zijn niet verstuurd omdat er onbekende apparaten aanwezig zijn. Nu %1$s of %2$s?</string>
+    <string name="room_unknown_devices_messages_notification">Berichten zijn niet verstuurd omdat er onbekende sessies aanwezig zijn. Nu %1$s of %2$s\?</string>
     <string name="room_prompt_resend">alles opnieuw versturen</string>
     <string name="room_prompt_cancel">alles annuleren</string>
     <string name="room_resend_unsent_messages">Onverstuurde berichten opnieuw versturen</string>
@@ -442,7 +441,7 @@
     <string name="settings_app_info_link_title">App-informatie</string>
 
     <string name="settings_enable_all_notif">Meldingen voor deze account inschakelen</string>
-    <string name="settings_enable_this_device">Meldingen voor dit apparaat inschakelen</string>
+    <string name="settings_enable_this_device">Meldingen voor deze sessie inschakelen</string>
     <string name="settings_turn_screen_on">Het scherm voor 3 seconden aanzetten</string>
 
     <string name="settings_messages_in_one_to_one">Berichten in één-op-één-gesprekken</string>
@@ -454,7 +453,7 @@
     <string name="settings_background_sync">Synchronisatie in de achtergrond</string>
     <string name="settings_enable_background_sync">Achtergrondssynchronisatie inschakelen</string>
     <string name="settings_set_sync_timeout">Synchronisatieverzoek is verlopen</string>
-    <string name="settings_set_sync_delay">Pauze tussen elk verzoek</string>
+    <string name="settings_set_sync_delay">Pauze tussen elk synchronisatie</string>
     <string name="settings_second">seconde</string>
     <string name="settings_seconds">seconden</string>
 
@@ -481,11 +480,11 @@
     <string name="settings_home_display">Startscherm</string>
     <string name="settings_pin_missed_notifications">Gesprekken met gemiste meldingen vastprikken</string>
     <string name="settings_pin_unread_messages">Gesprekken met ongelezen berichten vastprikken</string>
-    <string name="settings_devices_list">Apparaten</string>
-    <string name="devices_details_dialog_title">Apparaatinformatie</string>
+    <string name="settings_devices_list">Sessies</string>
+    <string name="devices_details_dialog_title">Sessie-informatie</string>
     <string name="devices_details_id_title">ID</string>
-    <string name="devices_details_name_title">Naam</string>
-    <string name="devices_details_device_name">Apparaatnaam</string>
+    <string name="devices_details_name_title">Publieke naam</string>
+    <string name="devices_details_device_name">Publieke naam bijwerken</string>
 
     <string name="devices_details_last_seen_title">Laatst gezien</string>
     <string name="devices_details_last_seen_format">%1$s @ %2$s</string>
@@ -579,8 +578,8 @@
     <string name="room_settings_labs_end_to_end">Eind-tot-eind-versleuteling</string>
     <string name="room_settings_labs_end_to_end_warnings">Om de versleuteling in te schakelen dient u zich eerst af te melden.</string>
     <string name="room_settings_labs_end_to_end_is_active">Eind-tot-eind-versleuteling is actief</string>
-    <string name="room_settings_never_send_to_unverified_devices_title">Alleen naar geverifieerde apparaten versleutelen</string>
-    <string name="room_settings_never_send_to_unverified_devices_summary">Ongeverifieerde apparaten in dit gesprek nooit berichten sturen vanaf dit apparaat.</string>
+    <string name="room_settings_never_send_to_unverified_devices_title">Alleen naar geverifieerde sessies versleutelen</string>
+    <string name="room_settings_never_send_to_unverified_devices_summary">Ongeverifieerde sessies in dit gesprek nooit berichten sturen vanaf deze sessie.</string>
 
     <!-- Room settings: advanced addresses -->
     <string name="room_settings_addresses_no_local_addresses">Dit gesprek heeft geen lokale adressen</string>
@@ -618,11 +617,11 @@
     <string name="encryption_information_session_id">Sessie-ID</string>
     <string name="encryption_information_decryption_error">Ontsleutelingsfout</string>
 
-    <string name="encryption_information_sender_device_information">Informatie over apparaat van afzender</string>
-    <string name="encryption_information_device_name">Apparaatnaam</string>
-    <string name="encryption_information_name">Naam</string>
-    <string name="encryption_information_device_id">Apparaats-ID</string>
-    <string name="encryption_information_device_key">Apparaatssleutel</string>
+    <string name="encryption_information_sender_device_information">Informatie over sessie van afzender</string>
+    <string name="encryption_information_device_name">Publieke naam</string>
+    <string name="encryption_information_name">Publieke naam</string>
+    <string name="encryption_information_device_id">ID</string>
+    <string name="encryption_information_device_key">Sessiesleutel</string>
     <string name="encryption_information_verification">Verificatie</string>
     <string name="encryption_information_ed25519_fingerprint">Ed25519-vingerafdruk</string>
 
@@ -640,14 +639,14 @@
     <string name="encryption_import_room_keys">Gesprekssleutels importeren</string>
     <string name="encryption_import_room_keys_summary">Importeer de sleutels uit een lokaal bestand</string>
     <string name="encryption_import_import">Importeren</string>
-    <string name="encryption_never_send_to_unverified_devices_title">Enkel naar geverifieerde apparaten versleutelen</string>
-    <string name="encryption_never_send_to_unverified_devices_summary">Versleutelde berichten nooit naar ongeverifieerde apparaten sturen vanaf dit apparaat.</string>
+    <string name="encryption_never_send_to_unverified_devices_title">Enkel naar geverifieerde sessies versleutelen</string>
+    <string name="encryption_never_send_to_unverified_devices_summary">Versleutelde berichten nooit naar ongeverifieerde sessies sturen vanaf deze sessie.</string>
 
     <string name="encryption_information_not_verified">NIET geverifieerd</string>
     <string name="encryption_information_verified">Geverifieerd</string>
     <string name="encryption_information_blocked">Geblokkeerd</string>
 
-    <string name="encryption_information_unknown_device">onbekend apparaat</string>
+    <string name="encryption_information_unknown_device">onbekende sessie</string>
     <string name="encryption_information_none">geen</string>
 
     <string name="encryption_information_verify">Verifiëren</string>
@@ -655,9 +654,9 @@
     <string name="encryption_information_block">Blokkeringslijst</string>
     <string name="encryption_information_unblock">Deblokkeringslijst</string>
 
-    <string name="encryption_information_verify_device">Apparaat verifiëren</string>
-    <string name="encryption_information_verify_device_warning">Om te verifiëren dat dit apparaat vertrouwd kan worden, contacteert u de eigenaar via een andere methode (bv. persoonlijk of via een telefoontje) en vraagt u hem/haar of de sleutel die hij/zij ziet in zijn/haar Gebruikersinstellingen van dit apparaat overeenkomt met de sleutel hieronder:</string>
-    <string name="encryption_information_verify_device_warning2">Als het overeenkomt, drukt u op de knop ‘Verifiëren’ hieronder. Als het niet overeenkomt, dan onderschept iemand anders het apparaat en zou u het beter blokkeren. In de toekomst zal dit verificatieproces verbeterd worden.</string>
+    <string name="encryption_information_verify_device">Sessie verifiëren</string>
+    <string name="encryption_information_verify_device_warning">Om te verifiëren dat deze sessie vertrouwd kan worden, contacteert u de eigenaar via een andere methode (bv. persoonlijk of via een telefoontje) en vraagt u hem/haar of de sleutel die hij/zij ziet in zijn/haar Gebruikersinstellingen van deze sessie overeenkomt met de sleutel hieronder:</string>
+    <string name="encryption_information_verify_device_warning2">Als het overeenkomt, drukt u op de knop ‘Verifiëren’ hieronder. Als het niet overeenkomt, dan onderschept iemand anders deze sessie en zou u het beter blokkeren. In de toekomst zal dit verificatieproces verbeterd worden.</string>
     <string name="encryption_information_verify_key_match">Ik verifieer dat de sleutels overeenkomen</string>
 
     <string name="e2e_enabling_on_app_update">Riot ondersteunt nu eind-tot-eind-versleuteling, maar u moet zich opnieuw aanmelden om het in te schakelen.
@@ -665,12 +664,12 @@
 \nU kunt dit nu of later doen vanuit de app-instellingen.</string>
 
     <!-- unknown devices management -->
-    <string name="unknown_devices_alert_title">Dit gesprek bevat onbekende apparaten</string>
-    <string name="unknown_devices_alert_message">Dit gesprek bevat onbekende apparaten die niet geverifieerd zijn. 
-\nDit betekent dat er geen garantie is dat de apparaten bij de gebruikers horen waartoe ze beweren te horen. 
-\nWe raden u aan om bij elk apparaat door het verificatieprocces heen te gaan voordat u verdergaat, maar u kunt het bericht ook zonder te verifiëren opnieuw versturen. 
+    <string name="unknown_devices_alert_title">Dit gesprek bevat onbekende sessies</string>
+    <string name="unknown_devices_alert_message">Dit gesprek bevat onbekende sessies die niet geverifieerd zijn. 
+\nDit betekent dat er geen garantie is dat de sessies bij de gebruikers horen waartoe ze beweren te horen. 
+\nWe raden u aan om bij elke sessie door het verificatieprocces heen te gaan voordat u verdergaat, maar u kunt het bericht ook zonder te verifiëren opnieuw versturen. 
 \n 
-\nOnbekende apparaten:</string>
+\nOnbekende sessies:</string>
 
     <!-- directory activity  -->
     <string name="select_room_directory">Kies een gesprekscatalogus</string>
@@ -757,8 +756,8 @@
     <string name="settings_labs_native_camera">Systeemcamera gebruiken</string>
 
     <!-- share keys -->
-    <string name="you_added_a_new_device">U heeft een nieuw apparaat ‘%s’ toegevoegd, dat versleutelingssleutels aanvraagt.</string>
-    <string name="your_unverified_device_requesting">Uw ongeverifieerde apparaat ‘%s’ vraagt versleutelingssleutels aan.</string>
+    <string name="you_added_a_new_device">U heeft een nieuwe sessie ‘%s’ toegevoegd, die versleutelingssleutels aanvraagt.</string>
+    <string name="your_unverified_device_requesting">Uw ongeverifieerde sessie ‘%s’ vraagt versleutelingssleutels aan.</string>
     <string name="start_verification">Verificatie starten</string>
     <string name="share_without_verifying">Delen zonder te verifiëren</string>
     <string name="ignore_request">Verzoek negeren</string>
@@ -920,7 +919,7 @@
     <string name="settings_deactivate_my_account">Mijn account deactiveren</string>
 
     <string name="startup_notification_privacy_title">Meldingsprivacy</string>
-    <string name="startup_notification_privacy_message">Riot kan in de achtergrond werken om uw meldingen veilig en privé te beheren. Dit beïnvloedt mogelijk het accuverbruik.</string>
+    <string name="startup_notification_privacy_message">Riot kan op de achtergrond werken om uw meldingen veilig en privé te beheren. Dit beïnvloedt mogelijk het accuverbruik.</string>
     <string name="startup_notification_privacy_button_grant">Toestemming verlenen</string>
     <string name="startup_notification_privacy_button_other">Kies een andere optie</string>
 
@@ -948,12 +947,12 @@
 
     <string name="download">Downloaden</string>
     <string name="speak">Inspreken</string>
-    <string name="e2e_re_request_encryption_key">Beveiligingssleutels van uw apparaten <u>opnieuw aanvragen</u>.</string>
+    <string name="e2e_re_request_encryption_key">Beveiligingssleutels van uw sessies <u>opnieuw aanvragen</u>.</string>
 
     <string name="e2e_re_request_encryption_key_sent">Sleutelaanvraag verstuurd.</string>
 
     <string name="e2e_re_request_encryption_key_dialog_title">Aanvraag verstuurd</string>
-    <string name="e2e_re_request_encryption_key_dialog_content">Start Riot op een ander apparaat dat het bericht kan ontsleutelen, zodat het de sleutels naar dit apparaat kan sturen.</string>
+    <string name="e2e_re_request_encryption_key_dialog_content">Start Riot op een ander apparaat dat het bericht kan ontsleutelen, zodat het de sleutels naar deze sessie kan sturen.</string>
 
     <string name="lock_screen_hint">Typ hier…</string>
 
@@ -1091,7 +1090,7 @@
     <string name="keys_backup_is_not_finished_please_wait">Sleutelback-up is nog niet klaar, even geduld…</string>
     <string name="sign_out_bottom_sheet_warning_no_backup">Indien u zich nu afmeldt, zult u uw versleutelde berichten verliezen</string>
     <string name="sign_out_bottom_sheet_warning_backing_up">Sleutelback-up is bezig. Indien u zich nu afmeldt, zult u de toegang tot uw versleutelde berichten verliezen.</string>
-    <string name="sign_out_bottom_sheet_warning_backup_not_active">Veilige sleutelback-up dient actief te zijn op al uw apparaten om de toegang tot uw versleutelde berichten niet te verliezen.</string>
+    <string name="sign_out_bottom_sheet_warning_backup_not_active">Veilige sleutelback-up dient actief te zijn op al uw sessies om de toegang tot uw versleutelde berichten niet te verliezen.</string>
     <string name="sign_out_bottom_sheet_dont_want_secure_messages">Ik wil mijn versleutelde berichten niet</string>
     <string name="sign_out_bottom_sheet_backing_up_keys">Sleutels worden geback-upt…</string>
     <string name="keys_backup_activate">Sleutelback-up gebruiken</string>
@@ -1136,9 +1135,9 @@
 \nGelieve de accountinstellingen te controleren.</string>
     <string name="settings_troubleshoot_test_account_settings_quickfix">Inschakelen</string>
 
-    <string name="settings_troubleshoot_test_device_settings_title">Apparaatinstellingen.</string>
-    <string name="settings_troubleshoot_test_device_settings_success">Meldingen zijn ingeschakeld voor dit apparaat.</string>
-    <string name="settings_troubleshoot_test_device_settings_failed">Meldingen zijn niet toegestaan voor dit apparaat.
+    <string name="settings_troubleshoot_test_device_settings_title">Sessie-instellingen.</string>
+    <string name="settings_troubleshoot_test_device_settings_success">Meldingen zijn ingeschakeld voor deze sessie.</string>
+    <string name="settings_troubleshoot_test_device_settings_failed">Meldingen zijn niet ingeschakeld voor deze sessie. 
 \nGelieve de Riot-instellingen te controleren.</string>
     <string name="settings_troubleshoot_test_device_settings_quickfix">Inschakelen</string>
 
@@ -1378,14 +1377,14 @@
     <string name="keys_backup_recovery_code_error_decrypt">De back-up kan met deze herstelsleutel niet ontsleuteld worden: controleer of u de juiste herstelsleutel heeft ingevoerd.</string>
 
     <string name="keys_backup_restore_success_title">Back-up hersteld %s!</string>
-    <string name="keys_backup_restore_success_description">%1$d sessiesleutels hersteld, en %2$d nieuwe sleutel(s) die dit apparaat nog niet kende toegevoegd</string>
+    <string name="keys_backup_restore_success_description">%1$d sessiesleutels hersteld, en %2$d nieuwe sleutel(s) die deze sessie nog niet kende toegevoegd</string>
     <plurals name="keys_backup_restore_success_description_part1">
         <item quantity="one">Back-up met %d sleutel hersteld.</item>
         <item quantity="other">Back-up met %d sleutels hersteld.</item>
     </plurals>
     <plurals name="keys_backup_restore_success_description_part2">
-        <item quantity="one">Er is %d nieuwe sleutel toegevoegd aan dit apparaat.</item>
-        <item quantity="other">Er zijn %d nieuwe sleutels toegevoegd aan dit apparaat.</item>
+        <item quantity="one">Er is %d nieuwe sleutel toegevoegd aan deze sessie.</item>
+        <item quantity="other">Er zijn %d nieuwe sleutels toegevoegd aan deze sessie.</item>
     </plurals>
 
     <string name="keys_backup_get_version_error">Verkrijgen van laatste herstelsleutelversie (%s) mislukt.</string>
@@ -1395,19 +1394,19 @@
     <string name="keys_backup_settings_restore_backup_button">Herstellen uit back-up</string>
     <string name="keys_backup_settings_delete_backup_button">Back-up verwijderen</string>
 
-    <string name="keys_backup_settings_status_ok">Sleutelback-up is correct ingesteld voor dit apparaat.</string>
-    <string name="keys_backup_settings_status_ko">Sleutelback-up is niet actief op dit apparaat.</string>
-    <string name="keys_backup_settings_status_not_setup">Uw sleutels worden niet geback-upt vanaf dit apparaat.</string>
+    <string name="keys_backup_settings_status_ok">Sleutelback-up is correct ingesteld voor deze sessie.</string>
+    <string name="keys_backup_settings_status_ko">Sleutelback-up is niet actief op deze sessie.</string>
+    <string name="keys_backup_settings_status_not_setup">Uw sleutels worden niet geback-upt vanaf deze sessie.</string>
 
-    <string name="keys_backup_settings_signature_from_unknown_device">De back-up heeft een ondertekening van een onbekend apparaat met ID %s.</string>
-    <string name="keys_backup_settings_valid_signature_from_this_device">De back-up heeft een geldige ondertekening van dit apparaat.</string>
-    <string name="keys_backup_settings_valid_signature_from_verified_device">De back-up heeft een geldige ondertekening van het geverifieerde apparaat %s.</string>
-    <string name="keys_backup_settings_valid_signature_from_unverified_device">De back-up heeft een geldige ondertekening van het ongeverifieerde apparaat %s</string>
-    <string name="keys_backup_settings_invalid_signature_from_verified_device">De back-up heeft een ongeldige ondertekening van het geverifieerde apparaat %s</string>
-    <string name="keys_backup_settings_invalid_signature_from_unverified_device">De back-up heeft een ongeldige ondertekening van het ongeverifieerde apparaat %s</string>
+    <string name="keys_backup_settings_signature_from_unknown_device">De back-up heeft een ondertekening van een onbekende sessie met ID %s.</string>
+    <string name="keys_backup_settings_valid_signature_from_this_device">De back-up heeft een geldige ondertekening van deze sessie.</string>
+    <string name="keys_backup_settings_valid_signature_from_verified_device">De back-up heeft een geldige ondertekening van de geverifieerde sessie %s.</string>
+    <string name="keys_backup_settings_valid_signature_from_unverified_device">De back-up heeft een geldige ondertekening van de ongeverifieerde sessie %s</string>
+    <string name="keys_backup_settings_invalid_signature_from_verified_device">De back-up heeft een ongeldige ondertekening van de geverifieerde sessie %s</string>
+    <string name="keys_backup_settings_invalid_signature_from_unverified_device">De back-up heeft een ongeldige ondertekening van de ongeverifieerde sessie %s</string>
     <string name="keys_backup_get_trust_error">Verkrijgen van vertrouwensinformatie voor back-up mislukt (%s).</string>
 
-    <string name="keys_backup_settings_untrusted_backup">Herstel nu met uw wachtwoord of herstelsleutel om sleutelback-up op dit apparaat te gebruiken.</string>
+    <string name="keys_backup_settings_untrusted_backup">Herstel nu met uw wachtwoord of herstelsleutel om sleutelback-up op deze sessie te gebruiken.</string>
     <string name="keys_backup_settings_deleting_backup">Back-up wordt verwijderd…</string>
     <string name="keys_backup_settings_delete_backup_error">Verwijderen van back-up is mislukt (%s)</string>
 
@@ -1448,17 +1447,17 @@
 
     <string name="error_jitsi_not_supported_on_old_device">Sorry, vergadergesprekken met Jitsi worden nog niet ondersteund op oudere apparaten (met een Android-versie lager dan 5.0)</string>
 
-    <string name="title_activity_verify_device">Apparaat verifiëren</string>
+    <string name="title_activity_verify_device">Sessie verifiëren</string>
 
     <string name="encryption_information_unknown_ip">onbekend IP-adres</string>
-    <string name="you_added_a_new_device_with_info">Een nieuw apparaat vraagt versleutelingssleutels aan.
-\nApparaatnaam: %1$s
-\nLaatst gezien: %2$s
-\nAls u zich niet heeft aangemeld op een ander apparaat, negeer dan dit verzoek.</string>
-    <string name="your_unverified_device_requesting_with_info">Een ongeverifieerd apparaat vraagt versleutelingssleutels aan.
-\nApparaatnaam: %1$s
-\nLaatst gezien: %2$s
-\nAls u zich niet heeft aangemeld op een ander apparaat, negeer dan dit verzoek.</string>
+    <string name="you_added_a_new_device_with_info">Een nieuwe sessie vraagt versleutelingssleutels aan. 
+\nSessienaam: %1$s 
+\nLaatst gezien: %2$s 
+\nAls u zich niet heeft aangemeld op een andere sessie, negeer dan dit verzoek.</string>
+    <string name="your_unverified_device_requesting_with_info">Een ongeverifieerde sessie vraagt versleutelingssleutels aan. 
+\nSessienaam: %1$s 
+\nLaatst gezien: %2$s 
+\nAls u zich niet heeft aangemeld op een andere sessie, negeer dan dit verzoek.</string>
 
     <string name="start_verification_short_label">Verifiëren</string>
     <string name="share_without_verifying_short_label">Delen</string>
@@ -1469,18 +1468,18 @@
     <string name="sas_security_advise">Voor een maximale beveiliging bevelen we aan om dit onder vier ogen te doen, of via een ander vertrouwd communicatiekanaal.</string>
     <string name="sas_verify_start_button_title">Verificatie beginnen</string>
     <string name="sas_incoming_request_title">Inkomend verificatieverzoek</string>
-    <string name="sas_incoming_request_description">Verifieer dit apparaat door het als vertrouwd te markeren. Door de apparaten van uw gesprekspartners te vertrouwen, hoeft u zich nog minder zorgen te maken over het gebruik van eind-tot-eind-versleutelde berichten.</string>
-    <string name="sas_incoming_request_description_2">Dit apparaat verifiëren zal het als vertrouwd markeren, en het ook aan uw gesprekspartner als vertrouwd markeren.</string>
+    <string name="sas_incoming_request_description">Verifieer de sessie door deze als vertrouwd te markeren. Door de sessie van uw gesprekspartners te vertrouwen, hoeft u zich nog minder zorgen te maken over het gebruik van eind-tot-eind-versleutelde berichten.</string>
+    <string name="sas_incoming_request_description_2">De sessie verifiëren zal deze als vertrouwd markeren, en deze ook aan uw gesprekspartner als vertrouwd markeren.</string>
 
-    <string name="sas_emoji_description">Verifieer dit apparaat door te bevestigen dat de volgende emoticons op het scherm van uw gesprekspartner verschijnen</string>
-    <string name="sas_decimal_description">Verifieer dit apparaat door te bevestigen dat de volgende cijfers op het scherm van uw gesprekspartner verschijnen</string>
+    <string name="sas_emoji_description">Verifieer deze sessie door te bevestigen dat de volgende emoticons op het scherm van uw gesprekspartner verschijnen</string>
+    <string name="sas_decimal_description">Verifieer deze sessie door te bevestigen dat de volgende cijfers op het scherm van uw gesprekspartner verschijnen</string>
 
     <string name="sas_incoming_verification_request_dialog">U heeft een inkomend verificatieverzoek ontvangen.</string>
     <string name="sas_view_request_action">Verzoek bekijken</string>
     <string name="sas_waiting_for_partner">Wachten op bevestiging van gesprekspartner…</string>
 
     <string name="sas_verified">Geverifieerd!</string>
-    <string name="sas_verified_successful">U heeft het apparaat geverifieerd.</string>
+    <string name="sas_verified_successful">U heeft de sessie geverifieerd.</string>
     <string name="sas_verified_successful_description">Beveiligde berichten met deze gebruiker worden eind-tot-eind-versleuteld en kunnen niet door derde partijen gelezen worden.</string>
     <string name="sas_got_it">Ik snap het</string>
 
@@ -1494,17 +1493,17 @@
     <string name="sas_cancelled_by_me">De verificatie is geannuleerd.
 \nReden: %s</string>
 
-    <string name="sas_verification_request_notification_channel">Interactieve apparaatsverificatie</string>
+    <string name="sas_verification_request_notification_channel">Interactieve sessieverificatie</string>
     <string name="sas_incoming_request_notif_title">Verificatieverzoek</string>
-    <string name="sas_incoming_request_notif_content">%s wil uw apparaat verifiëren</string>
+    <string name="sas_incoming_request_notif_content">%s wil uw sessie verifiëren</string>
 
     <string name="sas_error_m_user">De gebruiker heeft de verificatie geannuleerd</string>
     <string name="sas_error_m_timeout">Het verificatieproces is verlopen</string>
-    <string name="sas_error_m_unknown_transaction">Het apparaat heeft geen weet van die transactie</string>
-    <string name="sas_error_m_unknown_method">Het apparaat kan geen sleutelovereenkomst-, hash-, MAC- of SAS-methode kiezen</string>
+    <string name="sas_error_m_unknown_transaction">De sessie heeft geen weet van die transactie</string>
+    <string name="sas_error_m_unknown_method">De sessie kan geen sleutelovereenkomst-, hash-, MAC- of SAS-methode kiezen</string>
     <string name="sas_error_m_mismatched_commitment">De hashovereenkomst kwam niet overeen</string>
     <string name="sas_error_m_mismatched_sas">De SAS kwam niet overeen</string>
-    <string name="sas_error_m_unexpected_message">Het apparaat heeft een onverwacht bericht ontvangen</string>
+    <string name="sas_error_m_unexpected_message">De sessie heeft een onverwacht bericht ontvangen</string>
     <string name="sas_error_m_invalid_message">Er is een ongeldig bericht ontvangen</string>
     <string name="sas_error_m_key_mismatch">Sleutels komen niet overeen</string>
     <string name="sas_error_m_user_error">Gebruikers komen niet overeen</string>
@@ -1519,4 +1518,91 @@
     <string name="people_no_identity_server">Geen identiteitsserver geconfigureerd.</string>
 
     <string name="call_failed_no_ice_title">Oproep mislukt door verkeerd geconfigureerde server</string>
+    <string name="call_failed_no_ice_description">Vraag de beheerder van uw thuisserver (%1$s) om een TURN-server te configureren om oproepen betrouwbaar te doen werken.
+\n
+\nAls alternatief kunt u de publieke server op %2$s gebruiken. Dit is minder betrouwbaar en zal tevens uw IP-addres delen met die server. U kunt dit ook configureren in de Instellingen.</string>
+    <string name="call_failed_no_ice_use_alt">Probeer %s te gebruiken</string>
+    <string name="call_failed_dont_ask_again">Vraag het niet opnieuw</string>
+
+    <string name="auth_add_email_message_2">Kies een e-mailadres om te gebruiken voor accountherstel. Later kunt u ervoor kiezen om mensen u te laten vinden via uw e-mailadres.</string>
+    <string name="auth_add_phone_message_2">Kies een telefoonnummer. Later kunt u ervoor kiezen om mensen u te laten vinden via dit nummer.</string>
+    <string name="auth_add_email_phone_message_2">Kies een e-mailadres om te gebruiken voor accountherstel. Later kunt u ervoor kiezen om mensen u te laten vinden via uw e-mailadres of telefoonnummer.</string>
+    <string name="auth_add_email_and_phone_message_2">Kies een e-mailadres om te gebruiken voor accountherstel. Later kunt u ervoor kiezen om mensen u te laten vinden via uw e-mailadres of telefoonnummer.</string>
+    <string name="login_error_no_homeserver_found">Dit is geen geldig Matrix-serveradres</string>
+    <string name="login_error_homeserver_not_found">Kan geen verbinding maken met een thuisserver op deze URL, controleer de URL</string>
+    <string name="settings_call_ringtone_use_default_stun_sum">Zal %s gebruiken om te assisteren in het geval dat uw thuisserver er niet over beschikt (uw IP-adres zal tijdens een oproep gedeeld worden)</string>
+    <string name="invite_no_identity_server_error">Voeg een identiteitsserver toe in de instellingen om dit te doen.</string>
+    <string name="settings_add_3pid_confirm_password_title">Bevestig uw wachtwoord</string>
+    <string name="settings_add_3pid_flow_not_supported">U kunt dit niet doen vanaf de mobiele Riot</string>
+    <string name="settings_background_fdroid_sync_mode">Synchroniseren op de achtergrond (experimenteel)</string>
+    <string name="settings_background_fdroid_sync_mode_battery">Geoptimaliseerd voor batterij</string>
+    <string name="settings_background_fdroid_sync_mode_battery_description">Riot zal op een batterijzuinige manier synchroniseren op de achtergrond.
+\nAfhankelijk van de staat van uw apparaat kan het besturingssysteem de synchronisatie uitstellen.</string>
+    <string name="settings_background_fdroid_sync_mode_real_time">Geoptimaliseerd voor snelheid</string>
+    <string name="settings_background_fdroid_sync_mode_real_time_description">Riot zal periodiek op de achtergrond synchroniseren (configureerbaar).
+\nDit heeft een negatieve impact op uw batterij- en datagebruik. Er zal een melding getoond worden ter informatie.</string>
+    <string name="settings_background_fdroid_sync_mode_disabled">Geen achtergrondssynchronisatie</string>
+    <string name="settings_background_fdroid_sync_mode_disabled_description">U zal geen melding van berichten ontvangen als de app zich in de achtergrond bevindt.</string>
+    <string name="settings_background_sync_update_error">Kon de instellingen niet bijwerken.</string>
+
+
+    <string name="settings_set_workmanager_delay">Voorkeur voor synchronisatie-interval</string>
+    <string name="settings_set_workmanager_delay_summary">%s
+\nDe synchronisatie is mogelijk uitgesteld als gevolg van de batterij of staat van uw apparaat (slaapmodus).</string>
+    <string name="settings_integrations">Integraties</string>
+    <string name="resources_script">Latn</string>
+
+    <string name="settings_call_ringtone_use_default_stun">Terugvaloproepassistentieserver toestaan</string>
+    <string name="settings_add_3pid_authentication_needed">Authenticatie vereist</string>
+
+
+    <string name="settings_integrations_summary">Gebruik een integratiebeheerder om bots, bruggen, widgets en stickerpakketten te beheren.
+\nIntegratiebeheerders ontvangen configuratiedata en kunnen widgets aanpassen, gespreksuitnodigingen versturen en bestuursniveaus instellen namens u.</string>
+    <string name="settings_discovery_category">Ontdekken</string>
+    <string name="settings_discovery_manage">Beheer uw ontdekinstellingen.</string>
+    <string name="settings_integration_allow">Integraties toestaan</string>
+    <string name="settings_integration_manager">Integratiebeheerder</string>
+
+    <string name="encryption_information_device_name_with_warning">Publieke naam (zichtbaar voor mensen met wie u communiceert)</string>
+    <string name="device_name_warning">De publieke naam van een sessie is zichtbaar voor mensen met wie u communiceert</string>
+    <string name="room_widget_activity_title">Widget</string>
+    <string name="room_widget_permission_title">Widget laden</string>
+    <string name="room_widget_permission_added_by">Deze widget is toegevoegd door:</string>
+    <string name="room_widget_permission_webview_shared_info_title">Dit gebruiken kan cookies toevoegen en gegevens delen met %s:</string>
+    <string name="room_widget_permission_shared_info_title">Dit gebruiken kan gegevens delen met %s:</string>
+    <string name="room_widget_failed_to_load">Kon widget niet laden.
+\n%s</string>
+    <string name="room_widget_reload">Widget herladen</string>
+    <string name="room_widget_open_in_browser">Openen in browser</string>
+    <string name="room_widget_revoke_access">Toegang intrekken voor mij</string>
+
+    <string name="room_widget_permission_display_name">Uw weergavenaam</string>
+    <string name="room_widget_permission_avatar_url">Uw profielfoto-URL</string>
+    <string name="room_widget_permission_user_id">Uw gebruikers-ID</string>
+    <string name="room_widget_permission_theme">Uw thema</string>
+    <string name="room_widget_permission_widget_id">Widget-ID</string>
+    <string name="room_widget_permission_room_id">Gespreks-ID</string>
+
+
+    <string name="room_widget_resource_permission_title">Deze widget wil gebruik maken van de volgende bronnen:</string>
+    <string name="room_widget_resource_grant_permission">Toestaan</string>
+    <string name="room_widget_resource_decline_permission">Alles blokkeren</string>
+    <string name="room_widget_webview_access_camera">Camera gebruiken</string>
+    <string name="room_widget_webview_access_microphone">Microfoon gebruiken</string>
+    <string name="room_widget_webview_read_protected_media">DRM-beschermde media lezen</string>
+
+    <string name="integration_manager_not_configured">Geen integratiebeheerder ingesteld.</string>
+    <string name="widget_integration_review_terms">Om verder te gaan dient u de dienstvoorwaarden te aanvaarden.</string>
+
+    <string name="keys_backup_setup_override_backup_prompt_tile">Er bestaat al een back-up op uw thuisserver</string>
+    <string name="keys_backup_setup_override_backup_prompt_description">Het lijkt erop dat u al een back-up van uw herstelsleutel heeft uit een andere sessie. Wilt u deze vervangen door degene die u nu aanmaakt\?</string>
+    <string name="keys_backup_setup_override_replace">Vervangen</string>
+    <string name="keys_backup_setup_override_stop">Stoppen</string>
+
+    <string name="keys_backup_settings_checking_backup_state">Back-upstatus wordt gecontroleerd</string>
+    <string name="invalid_or_expired_credentials">U bent afgemeld vanwege onjuiste of verlopen gebruikersreferenties.</string>
+
+    <string name="identity_server_not_defined">U gebruikt geen identiteitsserver</string>
+    <string name="identity_server_not_defined_for_password_reset">Er is geen identiteitsserver geconfigureerd. Dit is vereist om uw wachtwoord opnieuw in te stellen.</string>
+
 </resources>
diff --git a/vector/src/main/res/values-nn/strings.xml b/vector/src/main/res/values-nn/strings.xml
index 44755a1ef0..aad1451984 100644
--- a/vector/src/main/res/values-nn/strings.xml
+++ b/vector/src/main/res/values-nn/strings.xml
@@ -210,7 +210,7 @@
     <string name="auth_reset_password_error_unauthorized">Fekk ikkje til å stadfesta e-postadressa: sjå til at du klikka på lenken i e-posten</string>
     <string name="auth_reset_password_success_message">Passordet ditt vart nullstilt. Du vart logga ut av alle sesjonar og får ikkje push-varsel lenger. For å skru varsel på att, logg inn att på kvar eining.</string>
 
-    <string name="login_error_must_start_http">URL-en må byrja på http[s]://</string>
+    <string name="login_error_must_start_http">URL-en må starta på http[s]://</string>
     <string name="login_error_network_error">Fekk ikkje til å logga inn: Nettverksfeil</string>
     <string name="login_error_unable_login">Fekk ikkje til å logga inn</string>
     <string name="login_error_registration_network_error">Fekk ikkje til å registrere: Nettverksfeil</string>
@@ -433,7 +433,7 @@
 
 
     <string name="search_hint">Søk</string>
-    <string name="search_members_hint">Filtrer rommedlemer</string>
+    <string name="search_members_hint">Filtrer rommedlemmar</string>
     <string name="search_no_results">Ingi treff</string>
     <string name="tab_title_search_rooms">ROM</string>
     <string name="tab_title_search_messages">MELDINGAR</string>
@@ -446,13 +446,13 @@
     <string name="room_recents_conversations">ROM</string>
     <string name="room_recents_low_priority">LÅGRETT</string>
     <string name="room_recents_invites">INNBJODINGAR</string>
-    <string name="room_recents_start_chat">Byrja samtala</string>
+    <string name="room_recents_start_chat">Start samtale</string>
     <string name="room_recents_create_room">Laga eit rom</string>
     <string name="room_recents_join_room">Vert med i romet</string>
     <string name="room_recents_join_room_title">Vert med i eit rom</string>
     <string name="room_recents_join_room_prompt">Skriv inn ein rom-ID eller eit romalias</string>
 
-    <string name="directory_search_results_title">Sjå gjenom utvalet</string>
+    <string name="directory_search_results_title">Bla gjennom katalog</string>
     <plurals name="directory_search_rooms">
         <item quantity="one">1 rom</item>
         <item quantity="other">%d rom</item>
@@ -511,10 +511,10 @@
     <string name="settings_messages_in_one_to_one">Meldingar i ein-og-ein-samtalar</string>
     <string name="settings_messages_in_group_chat">Meldingar i gruppesamtalar</string>
     <string name="settings_invited_to_room">Når eg blir invitert til eit rom</string>
-    <string name="settings_call_invitations">Røystsamtalainnbjodingar</string>
+    <string name="settings_call_invitations">Invitasjon til anrop</string>
     <string name="settings_messages_sent_by_bot">Meldingar frå botar</string>
 
-    <string name="settings_start_on_boot">Byrja ved uppstarten</string>
+    <string name="settings_start_on_boot">Køyr ved oppstart</string>
     <string name="settings_background_sync">Bakgrunnsamstilling</string>
     <string name="settings_enable_background_sync">Skru på bakgrunnsamstilling</string>
     <string name="settings_set_sync_timeout">Samstillingsfyrespurnaden fekk tidsavbrot</string>
@@ -523,7 +523,7 @@
     <string name="settings_seconds">sekund</string>
 
     <string name="settings_version">Versjon</string>
-    <string name="settings_olm_version">olm-versjon</string>
+    <string name="settings_olm_version">olm versjon</string>
     <string name="settings_app_term_conditions">Vilkår for bruk</string>
     <string name="settings_third_party_notices">Informasjon frå tredjepart</string>
     <string name="settings_copyright">Opphavsrett</string>
@@ -588,7 +588,7 @@ For å gå fram, ver venleg og skriv passordet ditt inn.</string>
     <string name="settings_interface_language">Språk</string>
     <string name="settings_select_language">Vel språk</string>
 
-    <string name="account_email_validation_title">Ventar på Godkjenning</string>
+    <string name="account_email_validation_title">Ventar på verifikasjon</string>
     <string name="account_email_validation_message">Ver venleg og sjekk eposten din og klikk på lenkja han inneheld. Når det er gjort, klikk gå fram.</string>
     <string name="account_email_validation_error">Fekk ikkje til å stadfesta e-postadressa. Ver venleg og sjekk e-posten din og klikk på lenkja han inneheld. Når det er gjort, klikk gå fram</string>
     <string name="account_email_already_used_error">E-postadressa er allereie i bruk</string>
@@ -620,8 +620,8 @@ For å gå fram, ver venleg og skriv passordet ditt inn.</string>
     <string name="settings_phone_number_code">Kode</string>
 
 
-    <string name="settings_flair">Særpreg</string>
-    <string name="settings_without_flair">Du er førebels ikkje med i nokre samfunn.</string>
+    <string name="settings_flair">Etikett</string>
+    <string name="settings_without_flair">Du er førebels ikkje med i nokre fellesskap.</string>
 
     <string name="media_saving_period_3_days">3 dagar</string>
     <string name="media_saving_period_1_week">1 veke</string>
@@ -639,7 +639,7 @@ For å gå fram, ver venleg og skriv passordet ditt inn.</string>
     <string name="room_settings_tag_pref_entry_none">Ingen</string>
 
     <string name="room_settings_category_access_visibility_title">Tilgang og synlegheit</string>
-    <string name="room_settings_directory_visibility">Vis rommet i romutvalet</string>
+    <string name="room_settings_directory_visibility">Vis dette rommet i romkatalogen</string>
     <string name="room_settings_room_notifications_title">Varsel</string>
     <string name="room_settings_room_access_rules_pref_title">Romtilgang</string>
     <string name="room_settings_room_read_history_rules_pref_title">Romhistoria si lesbarheit</string>
@@ -647,9 +647,9 @@ For å gå fram, ver venleg og skriv passordet ditt inn.</string>
     <string name="room_settings_room_access_rules_pref_dialog_title">Kven kan koma inn i rommet?</string>
 
     <string name="room_settings_read_history_entry_anyone">Kven som helst</string>
-    <string name="room_settings_read_history_entry_members_only_option_time_shared">Berre medlemer (frå då innstillinga er vald)</string>
-    <string name="room_settings_read_history_entry_members_only_invited">Berre medlemer (frå då dei vart bodne inn)</string>
-    <string name="room_settings_read_history_entry_members_only_joined">Berre medlemer (frå då dei kom inn)</string>
+    <string name="room_settings_read_history_entry_members_only_option_time_shared">Berre medlemmar (frå då innstillinga er vald)</string>
+    <string name="room_settings_read_history_entry_members_only_invited">Berre medlemmar (frå då dei vart bodne inn)</string>
+    <string name="room_settings_read_history_entry_members_only_joined">Berre medlemmar (frå då dei kom inn)</string>
 
     <string name="room_settings_room_access_warning">For å lenkja eit rom må det ha ei adresse.</string>
     <string name="room_settings_room_access_entry_only_invited">Berre folk som har vorte bodne inn</string>
@@ -658,7 +658,7 @@ For å gå fram, ver venleg og skriv passordet ditt inn.</string>
 
     <string name="room_settings_banned_users_title">Utestengde brukarar</string>
 
-    <string name="room_settings_category_advanced_title">Omfattande</string>
+    <string name="room_settings_category_advanced_title">Avansert</string>
     <string name="room_settings_room_internal_id">Rommet sin interne ID</string>
     <string name="room_settings_addresses_pref_title">Adresser</string>
     <string name="room_settings_labs_pref_title">Eksperimentelle funksjonar</string>
@@ -672,7 +672,7 @@ For å gå fram, ver venleg og skriv passordet ditt inn.</string>
     <string name="room_settings_addresses_no_local_addresses">Dette rommet har ingen lokale adresser</string>
     <string name="room_settings_addresses_add_new_address">Ny adresse (t.d. #foo:matrix.org)</string>
 
-    <string name="room_settings_no_flair">Dette rommet viser ikkje særpreg for nokre samfunn</string>
+    <string name="room_settings_no_flair">Dette rommet viser ikkje etikettar for nokre fellesskap</string>
     <string name="room_settings_add_new_group">Ny fellesskaps-ID (t.d. +foo:matrix.org)</string>
     <string name="room_settings_invalid_group_format_dialog_title">Ugyldig fellesskaps-ID</string>
     <string name="room_settings_invalid_group_format_dialog_body">\'%s\' er ikkje ein gyldig fellesskaps-ID</string>
@@ -696,7 +696,7 @@ For å gå fram, ver venleg og skriv passordet ditt inn.</string>
     <string name="directory_title">Utval</string>
     <string name="settings_theme">Preg</string>
 
-    <string name="failed_to_load_timeline_position">%s prøvde å lasta eit spesifikt punkt i rommet si tidslinje men klarte ikkje å finna det.</string>
+    <string name="failed_to_load_timeline_position">%s prøvde å lasta eit spesifikt punkt i rommet sin historikk men klarte ikkje å finna det.</string>
 
     <string name="encryption_information_title">Ende-til-ende-krypteringsinfo</string>
 
@@ -713,7 +713,7 @@ For å gå fram, ver venleg og skriv passordet ditt inn.</string>
     <string name="encryption_information_name">Offentleg namn</string>
     <string name="encryption_information_device_id">ID</string>
     <string name="encryption_information_device_key">Sesjonsnøkkel</string>
-    <string name="encryption_information_verification">Godkjenning</string>
+    <string name="encryption_information_verification">Verifikasjon</string>
     <string name="encryption_information_ed25519_fingerprint">Ed25519-fingeravtrykk</string>
 
     <string name="encryption_export_e2e_room_keys">Eksporter E2E-romnøkklar</string>
@@ -739,13 +739,13 @@ For å gå fram, ver venleg og skriv passordet ditt inn.</string>
     <string name="encryption_information_none">ingen</string>
 
     <string name="encryption_information_verify">Godkjenn</string>
-    <string name="encryption_information_unverify">Fjern godkjenning</string>
+    <string name="encryption_information_unverify">Fjern verifikasjon</string>
     <string name="encryption_information_block">Set på svartelista</string>
     <string name="encryption_information_unblock">Fjern frå svartelista</string>
 
     <string name="encryption_information_verify_device">Verifiser sesjonen</string>
     <string name="encryption_information_verify_device_warning">For å godkjenna at denne sesjonen er til å stola på, ver venleg og snakk med eigaren på ein anna måte (t.d. ansikt til ansikt eller på telefon) og spør han om nøkkelen han ser i Brukarinnstillingane for denne sesjonen samsvarar med nøkkelen under:</string>
-    <string name="encryption_information_verify_device_warning2">Viss det samsvarer, klikk Verifiser-knappen under. Viss det ikkje gjer det, avlyttar nokon andre denne sesjonen og du bør sannsynlegvis svarteliste den. I framtida vil denne godkjenningsprosessen bli meir forbetra.</string>
+    <string name="encryption_information_verify_device_warning2">Viss det samsvarer, klikk Verifiser-knappen under. Viss det ikkje gjer det, avlyttar nokon andre denne sesjonen og du bør sannsynlegvis svarteliste den. I framtida vil denne verifikasjonsprosessen bli meir forbetra.</string>
     <string name="encryption_information_verify_key_match">Eg stadfestar at nøkklane er like</string>
 
     <string name="e2e_enabling_on_app_update">Riot støttar no ende-til-ende-kryptering men du må logga inn att for å skru det på. Du kan gjera det no eller seinare i App-innstillingane.</string>
@@ -755,7 +755,7 @@ For å gå fram, ver venleg og skriv passordet ditt inn.</string>
 \n
 \nUkjende sesjonar:</string>
 
-    <string name="select_room_directory">Vel eit romutval</string>
+    <string name="select_room_directory">Vel ein romkatalog</string>
     <string name="directory_server_fail_to_retrieve_server">Tenaren er kanskje utilgjengeleg eller overlasta</string>
     <string name="directory_server_type_homeserver">Skriv ein heimtenar inn for å få henta opp offentlege rom frå</string>
     <string name="directory_server_placeholder">Heimtenar-URL</string>
@@ -800,7 +800,7 @@ For å gå fram, ver venleg og skriv passordet ditt inn.</string>
 
     <string name="widget_integration_unable_to_create">Klarte ikkje å laga widget.</string>
     <string name="widget_integration_failed_to_send_request">Fekk ikkje til å senda førespurnad.</string>
-    <string name="widget_integration_positive_power_level">Makthøgda må vere eit positivt heiltal.</string>
+    <string name="widget_integration_positive_power_level">Tilgangsnivået må vere eit positivt heiltal.</string>
     <string name="widget_integration_must_be_in_room">Du er ikkje i dette rommet.</string>
     <string name="widget_integration_no_permission_in_room">Du har ikkje tillating til å gjera det i dette rommet.</string>
     <string name="widget_integration_missing_room_id">Vantande room_id i førespurnaden.</string>
@@ -814,8 +814,8 @@ For å gå fram, ver venleg og skriv passordet ditt inn.</string>
 
     <string name="you_added_a_new_device">Du la til den nye sesjonen \'%s\', som etterspør krypteringsnøkklar.</string>
     <string name="your_unverified_device_requesting">Den ikkje-verifiserte sesjonen din \'%s\' etterspør krypteringsnøkklar.</string>
-    <string name="start_verification">Byrj godkjenning</string>
-    <string name="share_without_verifying">Del utan godkjenning</string>
+    <string name="start_verification">Start verifikasjon</string>
+    <string name="share_without_verifying">Del utan verifikasjon</string>
     <string name="ignore_request">Oversjå førespurnaden</string>
 
     <string name="conference_call_warning_title">Åtvaring!</string>
@@ -826,11 +826,11 @@ For å gå fram, ver venleg og skriv passordet ditt inn.</string>
     <string name="command_description_emote">Viser handling</string>
     <string name="command_description_ban_user">Stengjer brukarar med den gjevne IDen ute</string>
     <string name="command_description_unban_user">Slepp utestengde brukarar med den gjevne IDen inn at</string>
-    <string name="command_description_op_user">Set makthøgda på ein brukar</string>
+    <string name="command_description_op_user">Definer tilgangsnivå for ein brukar</string>
     <string name="command_description_deop_user">AvOPar brukarar med den gjevne IDen</string>
     <string name="command_description_invite_user">Byd brukarar med den gjevne IDen inn til det noverande rommet</string>
     <string name="command_description_join_room">Vert med i rommet med det gjevne aliaset</string>
-    <string name="command_description_part_room">Fer frå rommet</string>
+    <string name="command_description_part_room">Forlat rom</string>
     <string name="command_description_topic">Set romemnet</string>
     <string name="command_description_kick_user">Sparkar brukarar med gjeven ID</string>
     <string name="command_description_nick">Forandrar visingsnamnet ditt</string>
@@ -857,7 +857,7 @@ For å gå fram, ver venleg og skriv passordet ditt inn.</string>
     <string name="rooms">Rom</string>
     <string name="joined">Komne inn</string>
     <string name="invited">Bodne inn</string>
-    <string name="filter_group_members">Filtrer gruppemedlemer</string>
+    <string name="filter_group_members">Filtrer gruppemedlemmar</string>
     <string name="filter_group_rooms">Filtrer grupperom</string>
 
     <string name="group_no_long_description">Fellesskapssadministratoren har ikkje satt ei lang skildring for dette fellesskapet.</string>
@@ -1063,11 +1063,79 @@ Meldingssynlegheit på Matrix liknar på epost. At vi gløymer meldingane dine t
     <string name="settings_integrations_summary">Bruk ein integrasjonshandterar (Integration Manager) for å handtere botar, bruker, tillegg og klistermerkepakker.
 \nIntegrasjonshandterarar hentar konfigurasjonsdata, kan endre tillegg, sende rominvitasjonar og sette tilgangsnivå på vegne av deg.</string>
     <string name="settings_cryptography_manage_keys">Handtering av kryptografiske nøkklar</string>
-    <string name="settings_labs_enable_send_voice_summary">Dette valet krev ein tredjepartsapplikasjon for å registrere meldingane.</string>
+    <string name="settings_labs_enable_send_voice_summary">Dette valet krev eit tredjepartsprogram for å registrere meldingane.</string>
     <string name="settings_lazy_loading_title">Last rom-medlemmar etter behov (lazy-load)</string>
     <string name="error_lazy_loading_not_supported_by_home_server">Heimetenaren din støttar ikkje såklalla lazy-loading av rommelemar endå. Prøv igjen seinare.</string>
 
     <string name="sas_verified_successful_description">Sikre meldingar med denne brukaren er ende-til-ende kryptert, dei kan ikkje bli lesne av tredje partar.</string>
     <string name="settings_other_third_party_notices">Anna informasjon frå tredjepart</string>
     <string name="verification_conclusion_ok_notice">Meldingar med denne brukaren er ende-til-ende kryptert, dei kan ikkje bli lesne av tredje part.</string>
+    <string name="settings_noisy_notifications_preferences">Konfiguer bråkete-varsel</string>
+    <string name="settings_call_notifications_preferences">Konfiguer anrops-varsel</string>
+    <string name="settings_silent_notifications_preferences">Konfiguer stille-varsel</string>
+    <string name="settings_system_preferences_summary">Konfiguer LED-farge, vibrasjon eller lyd…</string>
+
+
+    <string name="settings_show_join_leave_messages">Vis bli-med/forlat hendelsar</string>
+    <string name="settings_show_join_leave_messages_summary">Invitasjonar, utkastingar og utestengingar gjeld ikkje dette.</string>
+    <string name="room_widget_open_in_browser">Opna i nettlesar</string>
+    <string name="store_full_description">Program for nettprat, under din kontroll og med full fleksibilitet. Riot lar deg kommunisere på den måten du vil. Implementert for [matrix] - protokollen for open, desentralisert kommunikasjon.
+\n
+\nOpprett ein gratis matrix.org-konto, sett opp eigen server på https://modular.im, eller ta i bruk ein annan Matrix-server.
+\n
+\nKvifor velje Riot.im\?
+\n
+\n• KOMPLETT KOMMUNIKASJON: Bygg rom rund teamet, venner, fellesskapet - du bestemmer! Send direktemeldingar, del filer, legg til tillegg, start taleanrop og videokonferansar! Alt saman er tilgjengeleg utan kostnad.
+\n
+\n• KRAFTIGE INTEGRASJONAR: Bruk Riot.im saman med verktøya du brukar frå før. Med Riot.Im kan du kommunisere med brukarar på andre plattformar.
+\n
+\n• PRIVAT OG SIKKER: Hald dine samtalar hemmelege. Industristandard ende-til-ende-kryptering sørgjer for at private samtalar forblir private.
+\n
+\n• OPEN, IKKJE LUKKA: Open kjeldekode, på toppen av Matrix-protokollen. Eig dine eigne data ved å drifte eigen server eller hjå nokon du stolar på.
+\n
+\n• OVERALT DER DU ER: Hald kontakten uansett kvar du er; fullstendig synkronisert meldingshistorikk på alle klientar, samt online på https://riot.im.</string>
+
+    <string name="keys_backup_restore_is_getting_backup_version">Hentar sikkerheitskopiversjon…</string>
+    <string name="keys_backup_info_title_version">Versjon</string>
+    <string name="settings_sdk_version">Matrix SDK versjon</string>
+    <string name="settings_preferences">Innstillingar</string>
+    <string name="settings_security_and_privacy">Sikkerheit og personvern</string>
+    <string name="preference_voice_and_video">Tale &amp; Video</string>
+    <string name="preference_root_help_about">Hjelp &amp; Om</string>
+
+
+    <string name="settings_labs_show_hidden_events_in_timeline">Vis skjulte hendelsar i historikken</string>
+
+    <string name="labs_swipe_to_reply_in_timeline">Aktiver swipe-for-å-svare i historikken</string>
+
+    <string name="room_list_quick_actions_leave">Forlat rommet</string>
+    <string name="timeline_unread_messages">Uleste meldingar</string>
+
+    <string name="login_error_outdated_homeserver_content">Denne heime-tenaren køyrer ein gammal versjon, du kan derfor ikkje kopla til. Be administrator om å oppgradere.</string>
+
+    <string name="create_room_encryption_description">Etter aktivering, så kan ikkje kryptering bli deaktivert.</string>
+
+    <string name="room_profile_section_security">Sikkerheit</string>
+    <string name="room_profile_section_security_learn_more">Få meir info</string>
+    <string name="room_profile_section_more_settings">Rominnstillingar</string>
+    <string name="room_profile_section_more_leave">Forlat rom</string>
+    <string name="room_member_power_level_admins">Administratorar</string>
+    <string name="room_member_power_level_moderators">Moderatorar</string>
+    <string name="room_member_power_level_custom">Tilpassa</string>
+    <string name="room_member_power_level_invites">Invitasjonar</string>
+    <string name="room_member_power_level_users">Brukarar</string>
+
+    <string name="room_member_power_level_admin_in">Administrator i %1$s</string>
+    <string name="room_member_power_level_moderator_in">Moderator i %1$s</string>
+    <string name="room_member_power_level_custom_in">Tilpassa (%1$d) i %2$s</string>
+
+    <string name="verify_cannot_cross_sign">Denne økta klarde ikkje å dele denne verifikasjonen med dine andre økter.
+\nVerifikasjonsdata er lagra lokalt, og vil bli delt i ein framtidig versjon av programmet.</string>
+
+    <string name="settings_category_timeline">Historikk</string>
+
+    <string name="room_settings_enable_encryption_warning">Etter aktivering, så kan ikkje kryptering bli deaktivert.</string>
+
+    <string name="complete_security">Fullstendig sikkerheit</string>
+
 </resources>
diff --git a/vector/src/main/res/values-pl/strings.xml b/vector/src/main/res/values-pl/strings.xml
index 37e402911e..b0c1492acb 100644
--- a/vector/src/main/res/values-pl/strings.xml
+++ b/vector/src/main/res/values-pl/strings.xml
@@ -33,7 +33,7 @@
     <string name="missing_permissions_warning">Ze względu na brak pewnych uprawnień, niektóre funkcje mogą nie działać…</string>
     <string name="missing_permissions_to_start_conf_call">Musisz być uprawniony, aby rozpocząć połączenie grupowe</string>
     <string name="missing_permissions_title_to_start_conf_call">Nie można rozpocząć połączenia</string>
-    <string name="device_information">Informacje o urządzeniu</string>
+    <string name="device_information">Informacje o sesji</string>
     <string name="room_no_conference_call_in_encrypted_rooms">Połączenia grupowe nie są obsługiwane w szyfrowanych pokojach</string>
     <string name="send_anyway">Wyślij mimo wszystko</string>
     <string name="or">i</string>
@@ -84,7 +84,6 @@
         <item quantity="one">1 użytkownik</item>
         <item quantity="few">%d użytkowników</item>
         <item quantity="many">%d użytkowników</item>
-        <item quantity="other" />
     </plurals>
 
     <string name="send_bug_report_include_logs">Wyślij dzienniki</string>
@@ -251,7 +250,7 @@ Przyznaj dostęp w następnym oknie.</string>
     <string name="room_participants_header_admin_tools">NARZĘDZIA ADMINISTRACYJNE</string>
     <string name="room_participants_header_call">DZWOŃ</string>
     <string name="room_participants_header_direct_chats">WIADOMOŚCI BEZPOŚREDNIE</string>
-    <string name="room_participants_header_devices">URZĄDZENIA</string>
+    <string name="room_participants_header_devices">SESJE</string>
 
     <string name="room_participants_action_invite">Zaproś</string>
     <string name="room_participants_action_leave">Opuść pokój</string>
@@ -265,7 +264,7 @@ Przyznaj dostęp w następnym oknie.</string>
     <string name="room_participants_action_unignore">Pokaż wszystkie wiadomości od tego użytkownika</string>
     <string name="room_participants_invite_search_another_user">ID, nazwa lub e-mail użytkownika</string>
     <string name="room_participants_action_mention">Wspomnij</string>
-    <string name="room_participants_action_devices_list">Pokaż listę urządzeń</string>
+    <string name="room_participants_action_devices_list">Pokaż listę sesji</string>
     <string name="room_participants_invite_prompt_msg">Czy na pewno chcesz zaprosić %s do tej rozmowy?</string>
 
     <string name="people_search_invite_by_id"><u>Zaproś przez ID</u></string>
@@ -357,7 +356,7 @@ Zauważ, że ta czynność spowoduje ponowne uruchomienie aplikacji i może to t
     <string name="settings_app_info_link_title">Informacje o aplikacji</string>
 
     <string name="settings_enable_all_notif">Włącz powiadomienia dla tego konta</string>
-    <string name="settings_enable_this_device">Włącz powiadomienia dla tego użytkownika</string>
+    <string name="settings_enable_this_device">Włącz powiadomienia dla tej sesji</string>
     <string name="settings_turn_screen_on">Podświetl ekran na 3 sekundy</string>
 
     <string name="settings_messages_in_one_to_one">Wiadomości bezpośrednie</string>
@@ -388,14 +387,14 @@ Zauważ, że ta czynność spowoduje ponowne uruchomienie aplikacji i może to t
     <string name="settings_contacts_app_permission">Uprawnienie do dostępu do kontaktów</string>
     <string name="settings_pin_missed_notifications">Przypnij pokoje z ominiętymi powiadomieniami</string>
     <string name="settings_pin_unread_messages">Przypnij pokoje z nieprzeczytanych wiadomościami</string>
-    <string name="settings_devices_list">Urządzenia</string>
+    <string name="settings_devices_list">Sesje</string>
     <string name="settings_always_show_timestamps">Pokaż czas wysłania dla wszystkich wiadomości</string>
     <string name="settings_data_save_mode">Tryb oszczędzania danych</string>
 
-    <string name="devices_details_dialog_title">Szczegóły o urządzeniu</string>
+    <string name="devices_details_dialog_title">Szczegóły o sesji</string>
     <string name="devices_details_id_title">ID</string>
-    <string name="devices_details_name_title">Nazwa</string>
-    <string name="devices_details_device_name">Nazwa urządzenia</string>
+    <string name="devices_details_name_title">Nazwa publiczna</string>
+    <string name="devices_details_device_name">Zaaktualizuj nazwę publiczną</string>
     <string name="devices_details_last_seen_title">Ostatnio widziany(-a)</string>
     <string name="devices_details_last_seen_format">%1$s @ %2$s</string>
     <string name="devices_delete_dialog_text">To działanie wymaga dodatkowego uwierzytelnienia.
@@ -480,9 +479,9 @@ Zauważ, że ta czynność spowoduje ponowne uruchomienie aplikacji i może to t
     <string name="encryption_information_user_id">ID użytkownika</string>
     <string name="encryption_information_algorithm">Algorytm</string>
     <string name="encryption_information_session_id">ID sesji</string>
-    <string name="encryption_information_device_name">Nazwa urządzenia</string>
-    <string name="encryption_information_name">Nazwa</string>
-    <string name="encryption_information_device_id">ID urządzenia</string>
+    <string name="encryption_information_device_name">Nazwa publiczna</string>
+    <string name="encryption_information_name">Nazwa publiczna</string>
+    <string name="encryption_information_device_id">ID</string>
     <string name="encryption_information_verification">Weryfikacja</string>
     <string name="encryption_information_ed25519_fingerprint">Odcisk palca Ed25519</string>
 
@@ -493,17 +492,17 @@ Zauważ, że ta czynność spowoduje ponowne uruchomienie aplikacji i może to t
     <string name="encryption_information_verified">Zweryfikowano</string>
     <string name="encryption_information_blocked">Na czarnej liście</string>
 
-    <string name="encryption_information_unknown_device">nieznane urządzenie</string>
+    <string name="encryption_information_unknown_device">nieznana sesja</string>
     <string name="encryption_information_none">brak</string>
 
     <string name="encryption_information_verify">Weryfikuj</string>
     <string name="encryption_information_block">Dodaj na czarną listę</string>
     <string name="encryption_information_unblock">Usuń z czarnej listy</string>
 
-    <string name="encryption_information_verify_device">Weryfikuj urządzenie</string>
+    <string name="encryption_information_verify_device">Weryfikuj sesję</string>
     <string name="encryption_information_verify_key_match">Te klucze są ze sobą zgodne</string>
 
-    <string name="unknown_devices_alert_title">Pokój zawiera nieznane urządzenie</string>
+    <string name="unknown_devices_alert_title">Pokój zawiera nieznane sesje</string>
     <string name="select_room_directory">Wybierz katalog pokojów</string>
     <string name="directory_server_fail_to_retrieve_server">Serwer może być wyłączony lub przeciążony</string>
     <string name="directory_server_placeholder">Adres serwera domowego</string>
@@ -575,17 +574,13 @@ Zauważ, że ta czynność spowoduje ponowne uruchomienie aplikacji i może to t
 Możesz dodać adres e-mail do swojego profilu w ustawieniach.</string>
     <string name="auth_home_server">Serwer Domowy:</string>
     <string name="auth_identity_server">Serwer Tożsamości:</string>
-    <string name="auth_reset_password_success_message">Twoje hasło zostało zresetowane.
-
-Zostałeś wylogowany ze wszystkich urządzeń i nie będziesz więcej otrzymywać powiadomień push. Aby ponownie włączyć powiadomienia, zaloguj się ponownie na każdym urządzeniu.</string>
+    <string name="auth_reset_password_success_message">Twoje hasło zostało zresetowane. Zostałeś wylogowany ze wszystkich sesji i nie będziesz więcej otrzymywać powiadomień push. Aby ponownie włączyć powiadomienia, zaloguj się ponownie na każdym urządzeniu.</string>
 
     <string name="login_mobile_device">Numer telefonu</string>
 
     <string name="login_error_unknown_token">Wprowadzony token dostępu nie został rozpoznany</string>
     <string name="login_error_bad_json">Uszkodzony JSON</string>
-    <string name="e2e_need_log_in_again">Należy się ponownie zalogować w celu wygenerowania kluczy szyfrowania end-to-end dla tego urządzenia i wysłania klucza publicznego do Twojego serwera domowego.
-Jest to jednorazowe działanie.
-Przepraszamy za trudności.</string>
+    <string name="e2e_need_log_in_again">Należy się ponownie zalogować w celu wygenerowania kluczy szyfrowania end-to-end dla tej sesji i wysłania klucza publicznego do Twojego serwera domowego. Jest to jednorazowe działanie. Przepraszamy za trudności.</string>
 
     <string name="groups_list">Lista grup</string>
 
@@ -638,7 +633,7 @@ Jesteś pewien?</string>
     <string name="call_error_answered_elsewhere">połączenie odebrane gdzie indziej</string>
 
     <string name="room_unsent_messages_notification">Wiadomość nie została wysłana. Czy %1$s lub %2$s teraz?</string>
-    <string name="room_unknown_devices_messages_notification">Wiadomość niewysłana z powodu obecności nieznanych urządzeń. Czy %1$s lub %2$s teraz?</string>
+    <string name="room_unknown_devices_messages_notification">Wiadomość niewysłana z powodu obecności nieznanych sesji. Czy %1$s lub %2$s teraz\?</string>
     <plurals name="room_new_messages_notification">
         <item quantity="one">Nowa wiadomość</item>
         <item quantity="few">Kilka nowych wiadomości</item>
@@ -677,7 +672,7 @@ Jesteś pewien?</string>
     <string name="settings_containing_my_display_name">Wiadomości zawierające moją wyświetlaną nazwę</string>
     <string name="settings_containing_my_user_name">Wiadomości zawierające moją nazwę użytkownika</string>
     <string name="settings_set_sync_timeout">Żądanie synchronizacji nieudane z powodu przekroczenia limitu czasu</string>
-    <string name="settings_set_sync_delay">Opóźnienie między każdym żądaniem</string>
+    <string name="settings_set_sync_delay">Opóźnienie między każdą synchronizacją</string>
     <string name="settings_olm_version">Wersja olm</string>
     <string name="settings_third_party_notices">Informacje o stronach trzecich</string>
     <string name="settings_keep_media">Zatrzymaj media</string>
@@ -686,7 +681,7 @@ Jesteś pewien?</string>
     <string name="settings_home_display">Ekran domowy</string>
     <string name="settings_inline_url_preview">Podgląd zawartości URL</string>
     <string name="settings_12_24_timestamps">Pokaż czas w formacie 12-godzinnym</string>
-    <string name="settings_vibrate_on_mention">Wibruj gdy ktoś wspomni o tobie</string>
+    <string name="settings_vibrate_on_mention">Wibruj gdy ktoś wspomni o Tobie</string>
 
     <string name="settings_analytics">Analityka</string>
 
@@ -711,8 +706,8 @@ Jesteś pewien?</string>
     <string name="room_settings_room_access_entry_anyone_with_link_including_guest">Każdy kto zna link pokoju, razem z gośćmi</string>
 
     <string name="room_settings_labs_end_to_end_warnings">Musisz się wylogować aby uruchomić szyfrowanie.</string>
-    <string name="room_settings_never_send_to_unverified_devices_title">Szyfruj wiadomości tylko do zaufanych urządzeń</string>
-    <string name="room_settings_never_send_to_unverified_devices_summary">Nigdy nie wysyłaj zaszyfrowanych wiadomości do niezweryfikowanych urządzeń w tym pokoju z tego urządzenia.</string>
+    <string name="room_settings_never_send_to_unverified_devices_title">Szyfruj wiadomości tylko do zaufanych sesji</string>
+    <string name="room_settings_never_send_to_unverified_devices_summary">Nigdy nie wysyłaj zaszyfrowanych wiadomości do niezweryfikowanych sesjiw tym pokoju z tego urządzenia.</string>
 
     <string name="room_settings_addresses_no_local_addresses">Ten pokój nie ma adresu lokalnego</string>
     <string name="room_settings_add_new_group">Nowe ID społęczności (np. +foo:matrix.org)</string>
@@ -728,7 +723,7 @@ Jesteś pewien?</string>
     <string name="room_settings_unset_main_address">NIe ustawiaj jako główny adres</string>
     <string name="encryption_information_decryption_error">Błąd odszyfrowywania</string>
 
-    <string name="encryption_information_device_key">Klucz urządzenia</string>
+    <string name="encryption_information_device_key">Klucz sesji</string>
     <string name="encryption_export_room_keys">Wyeksportuj klucze pokoju</string>
     <string name="encryption_export_room_keys_summary">Eksportuj klucze do pliku lokalnego</string>
     <string name="rejoin">Dołącz ponownie</string>
@@ -737,12 +732,12 @@ Jesteś pewien?</string>
     <string name="download">Pobierz</string>
     <string name="clear">Wyczyść</string>
     <string name="option_send_sticker">Wyślij naklejkę</string>
-    <string name="e2e_re_request_encryption_key"><u>Poproś ponownie o klucze szyfrujące</u> z innych Twoich urządzeń.</string>
+    <string name="e2e_re_request_encryption_key"><u>Poproś ponownie o klucze szyfrujące</u> z innych Twoich sesji.</string>
 
     <string name="e2e_re_request_encryption_key_sent">Prośba o klucz wysłana.</string>
 
     <string name="e2e_re_request_encryption_key_dialog_title">Prośba wysłana</string>
-    <string name="e2e_re_request_encryption_key_dialog_content">Uruchom proszę Riot na innym urządzeniu, które może odszyfrować wiadomość, aby wysłać klucze do tego urządzenia.</string>
+    <string name="e2e_re_request_encryption_key_dialog_content">Uruchom proszę Riot na innym urządzeniu, które może odszyfrować wiadomość, aby wysłać klucze do tej sesji.</string>
 
     <string name="settings_notification_privacy">Prywatność powiadomień</string>
     <string name="settings_notification_privacy_normal">Standardowa</string>
@@ -777,7 +772,7 @@ Jesteś pewien?</string>
     <string name="encryption_information_title">Informacje o szyfrowaniu end-to-end</string>
 
     <string name="encryption_information_device_info">Informacje zdarzenia</string>
-    <string name="encryption_information_sender_device_information">Informacja o urządzeniu nadawcy</string>
+    <string name="encryption_information_sender_device_information">Informacja o sesji nadawcy</string>
     <string name="encryption_export_e2e_room_keys">Eksportuj klucze E2E pokoju</string>
     <string name="encryption_export_saved_as">Klucze pokoju zostały zapisane w \'%s\'
 
@@ -787,21 +782,17 @@ Uwaga: ten plik może zostać usunięty, jeśli aplikacja zostanie odinstalowana
     <string name="encryption_import_room_keys">Importuj klucze pokoju</string>
     <string name="encryption_import_room_keys_summary">Importuj klucze z lokalnego pliku</string>
     <string name="encryption_import_import">Importuj</string>
-    <string name="encryption_never_send_to_unverified_devices_title">Szyfruj wiadomości tylko do zaufanych urządzeń</string>
-    <string name="encryption_never_send_to_unverified_devices_summary">Nigdy nie wysyłaj zaszyfrowanych wiadomości do niezweryfikowanych urządzeń w tym pokoju z tego urządzenia.</string>
+    <string name="encryption_never_send_to_unverified_devices_title">Szyfruj wiadomości tylko do zaufanych sesji</string>
+    <string name="encryption_never_send_to_unverified_devices_summary">Nigdy nie wysyłaj zaszyfrowanych wiadomości do niezweryfikowanych sesji w tym pokoju z tej sesji.</string>
 
     <string name="encryption_information_unverify">Usuń weryfikację</string>
-    <string name="encryption_information_verify_device_warning">Aby sprawdzić czy to urządzenie jest zaufane, skontaktuj się z jego właścicielem używając innych form (np. osobiście lub telefonicznie) i zapytaj ich czy klucz, który widzą w ustawieniach użytkownika dla tego urządzenia pasuje do klucza poniżej:</string>
-    <string name="encryption_information_verify_device_warning2">Jeśli klucz pasuje, potwierdź to przyciskiem poniżej. Jeśli nie, to ktoś inny najprawdopodobniej przejmuje lub podszywa się pod to urządzenie i powinieneś dodać urządzenie do czarnej listy. W przyszłości proces weryfikacji będzie bardziej skomplikowany.</string>
+    <string name="encryption_information_verify_device_warning">Aby sprawdzić czy ta sesja jest zaufana, skontaktuj się z jej właścicielem używając innych form (np. osobiście lub telefonicznie) i zapytaj czy klucz, który widzą w ustawieniach użytkownika dla tego urządzenia pasuje do klucza poniżej:</string>
+    <string name="encryption_information_verify_device_warning2">Jeśli klucz pasuje, potwierdź to przyciskiem poniżej. Jeśli nie, to ktoś inny najprawdopodobniej przejmuje lub podszywa się pod tą sesję i powinieneś dodać tę sesję do czarnej listy. W przyszłości proces weryfikacji będzie bardziej skomplikowany.</string>
     <string name="e2e_enabling_on_app_update">Riot obsługuje już szyfrowanie end-to-end (E2E), ale musisz zalogować się ponownie, aby je włączyć.
 
 Możesz to zrobić teraz lub później z poziomu ustawień aplikacji.</string>
 
-    <string name="unknown_devices_alert_message">Ten pokój zawiera nieznane urządzenia, które nie zostały zweryfikowane.
-Oznacza to brak gwarancji, że urządzenia należą do użytkowników do których twierdzą, że należą.
-Przed kontynuowaniem, zalecamy wykonanie procesu weryfikacji każdego urządzenia, ale możesz ponownie wysłać wiadomość bez weryfikacji, jeśli wolisz.
-
-Nieznane urządzenia:</string>
+    <string name="unknown_devices_alert_message">Ten pokój zawiera nieznane sesje, które nie zostały zweryfikowane. Oznacza to brak gwarancji, że sesje należą do użytkowników do których twierdzą, że należą. Przed kontynuowaniem, zalecamy wykonanie procesu weryfikacji każdego urządzenia, ale możesz ponownie wysłać wiadomość bez weryfikacji, jeśli wolisz. Nieznane sesje:</string>
 
     <string name="title_activity_choose_sticker">Wyślij naklejkę</string>
 
@@ -862,7 +853,7 @@ Czy chcesz dodać teraz kilka?</string>
     <string name="widget_integration_positive_power_level">Poziom uprawnień musi być liczbą dodatnią.</string>
     <string name="widget_integration_must_be_in_room">Nie jesteś w tym pokoju.</string>
     <string name="widget_integration_no_permission_in_room">Nie masz uprawnień, aby zrobić to w tym pokoju.</string>
-    <string name="settings_flair">Nastrój</string>
+    <string name="settings_flair">Wyróżnik społeczności</string>
 
     <string name="room_settings_no_flair">Ten pokój nie wyświetla wyróżników dla żadnych społeczności</string>
     <string name="widget_integration_missing_room_id">Brakujące room_id w żądaniu.</string>
@@ -872,8 +863,8 @@ Czy chcesz dodać teraz kilka?</string>
     <string name="room_add_matrix_apps">Dodaj aplikacje Matrix</string>
     <string name="settings_labs_enable_send_voice">Wyślij wiadomości głosowe</string>
 
-    <string name="you_added_a_new_device">Dodałeś(-aś) nowe urządzenie \'%s\', które żąda kluczy szyfrujących.</string>
-    <string name="your_unverified_device_requesting">Twoje niezweryfikowane urządzenie \'%s\' żąda kluczy szyfrujących.</string>
+    <string name="you_added_a_new_device">Dodałeś(-aś) nową sesję \'%s\', która żąda kluczy szyfrujących.</string>
+    <string name="your_unverified_device_requesting">Twoje niezweryfikowana sesja \'%s\' żąda kluczy szyfrujących.</string>
     <string name="start_verification">Rozpocznij weryfikację</string>
     <string name="share_without_verifying">Współdziel bez weryfikacji</string>
     <string name="ignore_request">Zignoruj żądanie</string>
@@ -932,8 +923,7 @@ Widoczność wiadomości w Matrix jest podobna do wiadomości e-mail. Nasze zapo
     <plurals name="group_members">
         <item quantity="one">1 członek</item>
         <item quantity="few">%d członków</item>
-        <item quantity="many">%d członków</item>
-        <item quantity="other" />
+        <item quantity="many" />
     </plurals>
 
     <plurals name="group_rooms">
@@ -955,26 +945,22 @@ Widoczność wiadomości w Matrix jest podobna do wiadomości e-mail. Nasze zapo
     <plurals name="format_time_s">
         <item quantity="one">1 sekunda</item>
         <item quantity="few">%d sek.</item>
-        <item quantity="many">%d sek.</item>
-        <item quantity="other" />
+        <item quantity="many" />
     </plurals>
     <plurals name="format_time_m">
         <item quantity="one">1 minuta</item>
         <item quantity="few">%d min.</item>
-        <item quantity="many">%d min.</item>
-        <item quantity="other" />
+        <item quantity="many" />
     </plurals>
     <plurals name="format_time_h">
         <item quantity="one">1 godzina</item>
         <item quantity="few">%s godz.</item>
-        <item quantity="many">%s godz.</item>
-        <item quantity="other" />
+        <item quantity="many" />
     </plurals>
     <plurals name="format_time_d">
         <item quantity="one">1 dzień</item>
         <item quantity="few">%d dni</item>
-        <item quantity="many">%d dni</item>
-        <item quantity="other" />
+        <item quantity="many" />
     </plurals>
 
     <string name="room_participants_action_unignore_prompt">Pokazać wszystkie wiadomości od tego użytkownika?
@@ -1052,10 +1038,9 @@ Pamiętaj ta akcja może zresetować aplikacje i potrwać jakiś czas.</string>
     <string name="settings_call_category">Połączenia</string>
     <string name="room_participants_action_kick">Wyrzuć</string>
     <plurals name="room_participants_kick_prompt_msg">
-        <item quantity="one">Czy chcesz wyrzucić tego użytkownika z rozmowy?</item>
-        <item quantity="few">Czy chcesz wyrzucić tych użytkowników z rozmowy?</item>
-        <item quantity="many">Czy chcesz wyrzucić tych użytkowników z rozmowy?</item>
-        <item quantity="other" />
+        <item quantity="one">Czy chcesz wyrzucić tego użytkownika z rozmowy\?</item>
+        <item quantity="few">Czy chcesz wyrzucić tych użytkowników z rozmowy\?</item>
+        <item quantity="many" />
     </plurals>
     <string name="settings_send_markdown">Formatowanie Markdown</string>
     <string name="settings_show_join_leave_messages">Pokaż zdarzenia dołączenia i wyjścia</string>
@@ -1086,8 +1071,8 @@ Pamiętaj ta akcja może zresetować aplikacje i potrwać jakiś czas.</string>
     <string name="settings_troubleshoot_test_account_settings_success">Powiadomienia są właczone dla twojego konta.</string>
     <string name="settings_troubleshoot_test_account_settings_quickfix">Włącz</string>
 
-    <string name="settings_troubleshoot_test_device_settings_title">Ustawienia Urządzenia.</string>
-    <string name="settings_troubleshoot_test_device_settings_success">Powiadomienia są włączone dla tego urządzenia.</string>
+    <string name="settings_troubleshoot_test_device_settings_title">Ustawienia Sesji.</string>
+    <string name="settings_troubleshoot_test_device_settings_success">Powiadomienia są włączone dla tej sesji.</string>
     <string name="settings_troubleshoot_test_device_settings_quickfix">Włącz</string>
 
     <string name="settings_troubleshoot_test_fcm_title">Token Firebase</string>
@@ -1100,8 +1085,7 @@ Pamiętaj ta akcja może zresetować aplikacje i potrwać jakiś czas.</string>
 Sprawdź ustawienia systemowe.</string>
     <string name="settings_troubleshoot_test_account_settings_failed">Powiadomienia są wyłączone dla twojego konta.
 Sprawdź ustawienia konta.</string>
-    <string name="settings_troubleshoot_test_device_settings_failed">Powiadomienia nie są dozwolone dla tego urządzenia.
-Proszę sprawdź ustawienia Riot.</string>
+    <string name="settings_troubleshoot_test_device_settings_failed">Powiadomienia nie są włączone dla tej sesji. Proszę sprawdź ustawienia Riot.</string>
     <string name="store_whats_new">"Zawsze wprowadzamy zmiany i ulepszenia do Riot.im.
 Pełną listę zmian można znaleźć tutaj: %1$s.
 Aby upewnić się, że niczego nie przegapisz, po prostu miej włączone aktualizacje."</string>
@@ -1152,27 +1136,27 @@ Spróbuj uruchomić ponownie aplikację.</string>
 
     <string name="keys_backup_settings_delete_confirm_title">Usuń kopię zapasową</string>
     <string name="keys_backup_info_title_version">Wersja</string>
-    <string name="title_activity_verify_device">Zweryfikuj urządzenie</string>
+    <string name="title_activity_verify_device">Zweryfikuj sesję</string>
 
     <string name="action_mark_room_read">Oznacz jako przeczytane</string>
     <string name="sas_verified">Zweryfikowano!</string>
     <string name="sas_verification_request_notification_channel_title">Weryfikacja klucza</string>
     <string name="sas_incoming_request_notif_title">Żądanie weryfikacji</string>
-    <string name="sas_incoming_request_notif_content">%s chce zweryfikować twoje urządzenie</string>
+    <string name="sas_incoming_request_notif_content">%s chce zweryfikować twoją sesję</string>
 
     <string name="sas_error_unknown">Nieznany błąd</string>
 
     <string name="keys_backup_activate">Użyj kopii zapasowej klucza</string>
     <string name="keys_backup_info_title_signature">Podpis</string>
 
-    <string name="you_added_a_new_device_with_info">Nowe urządzenie żąda kluczy szyfrujących.
-\nNazwa urządzenia: %1$s
-\nOstatnio widziane: %2$s
-\nJeśli to nie Ty zalogowałeś(-aś) się na innym urządzeniu, zignoruj to żądanie.</string>
-    <string name="your_unverified_device_requesting_with_info">Nowe niezweryfikowane urządzenie żąda kluczy szyfrujących.
-\nNazwa urządzenia: %1$s
-\nOstatnio widziane: %2$s
-\nJeśli to nie Ty zalogowałeś(-aś) się na innym urządzeniu, zignoruj to żądanie.</string>
+    <string name="you_added_a_new_device_with_info">Nowa sesja żąda kluczy szyfrujących. 
+\nNazwa sesji: %1$s 
+\nOstatnio widziana: %2$s 
+\nJeśli to nie Ty zalogowałeś(-aś) się na innej sesji, zignoruj to żądanie.</string>
+    <string name="your_unverified_device_requesting_with_info">Nowa niezweryfikowana sesja żąda kluczy szyfrujących. 
+\nNazwa sesji: %1$s 
+\nOstatnio widziana: %2$s 
+\nJeśli to nie Ty zalogowałeś(-aś) się na innej sesji, zignoruj to żądanie.</string>
 
     <string name="start_verification_short_label">Weryfikuj</string>
     <string name="share_without_verifying_short_label">Udostępnij</string>
@@ -1183,7 +1167,7 @@ Spróbuj uruchomić ponownie aplikację.</string>
     <plurals name="keys_backup_restore_success_description_part1">
         <item quantity="one">Przywrócono kopię zapasową z %d kluczem.</item>
         <item quantity="few">Przywrócono kopię zapasową z %d kluczami.</item>
-        <item quantity="many">Przywrócono kopię zapasową z %d kluczami.</item>
+        <item quantity="many" />
     </plurals>
     <string name="title_activity_keys_backup_restore">Użyj kopii zapasowej klucza</string>
     <string name="settings_troubleshoot_diagnostic_running_status">Uruchamianie… (%1$d z %2$d)</string>
@@ -1205,7 +1189,7 @@ Spróbuj uruchomić ponownie aplikację.</string>
     <string name="create_new_room">Utwórz nowy pokój</string>
     <string name="group_all_communities">Wszystkie społeczności</string>
 
-    <string name="fab_menu_create_chat">Rozmowy bezpośrednie</string>
+    <string name="fab_menu_create_chat">Wiadomości Bezpośrednie</string>
 
     <string name="create_room_title">Nowy pokój</string>
     <string name="create_room_action_create">STWÓRZ</string>
@@ -1219,27 +1203,1040 @@ Spróbuj uruchomić ponownie aplikację.</string>
     <string name="fab_menu_create_room">Pokoje</string>
     <string name="create_room_directory_description">Opublikuj pokój do spisu pokojów</string>
 
-    <string name="sign_out_bottom_sheet_warning_backup_not_active">Aby nie utracić dostępu do Twoich zaszyfrowanych wiadomości, powinienieś aktywować kopię zapasową klucza na wszystkich swoich urządzeniach.</string>
+    <string name="sign_out_bottom_sheet_warning_backup_not_active">Aby nie utracić dostępu do Twoich zaszyfrowanych wiadomości, powinienieś aktywować kopię zapasową klucza na wszystkich aktywnych sesjach.</string>
     <string name="sign_out_bottom_sheet_backing_up_keys">Tworzenie kopii zapasowej kluczy…</string>
     <string name="backup">Utwórz kopię zapasową</string>
     <string name="login_error_ssl_handshake">Twoje urządzenie używa przestarzałego protokołu bezpieczeństwa TSL, podatnego na ataki, dlatego dla Twojego bezpieczeństwa nie będziesz mógł się połączyć</string>
-    <string name="keys_backup_settings_status_ok">Kopia zapasowa klucza została prawidłowo skonfigurowana dla tego urządzenia.</string>
+    <string name="keys_backup_settings_status_ok">Kopia zapasowa klucza została prawidłowo skonfigurowana dla tej sesji.</string>
     <string name="notification_sync_init">Inicjalizacja usługi</string>
     <string name="auth_login_sso">Zaloguj się za pomocą logowania jednorazowego</string>
     <string name="settings_notification_advanced_summary">Ustaw ważność powiadomienia za pomocą wydarzeń, skonfiguruj dźwięk, diodę LED, wibracje</string>
     <string name="settings_notification_by_event">Ważność powiadomień ze względu na wydarzenie</string>
 
-    <string name="settings_notification_troubleshoot">Powiadomienia diagnostyczne</string>
+    <string name="settings_notification_troubleshoot">Diagnostyka powiadomień</string>
     <string name="settings_troubleshoot_diagnostic">Rozwiązywanie problemów</string>
     <string name="settings_troubleshoot_diagnostic_success_status">Diagnostyka podstawowa nie wykazała problemów. Jeżeli wciąż nie otrzymujesz powiadomień, prosimy o przesłanie raportu o błędach, w celu ich rozwiązania.</string>
     <string name="settings_notification_privacy_no_background_sync">Aplikacja <b>nie</b> potrzebuje łączyć się z serwerem domowym w tle, powinno to zredukować użycie baterii</string>
     <string name="keys_backup_restore_with_passphrase_helper_with_link">Jeżeli nie pamiętasz swoich danych odzystkiwania, możesz %s.</string>
 
     <string name="keys_backup_restore_with_key_helper">Zgubiłeś (-łaś) swój klucz odzyskiwania\? Możesz ustawić nowy w ustawieniach.</string>
-    <string name="keys_backup_settings_valid_signature_from_unverified_device">Kopia zapasowa posiada poprawną sygnaturę z niezweryfikowanego urządzenia %s</string>
+    <string name="keys_backup_settings_valid_signature_from_unverified_device">Kopia zapasowa posiada poprawną sygnaturę z niezweryfikowanej sesji %s</string>
     <string name="new_recovery_method_popup_description">Wykryto nową, bezpieczną kopię kluczy wiadomości.
 \n
 \nJeżeli nie ustawiałeś nowej metody odzyskiwania, atakujący mogą uzyskać dostęp do Twojego konta. Zmień hasło konta i ustaw nową metodę odzyskiwania jak najszybciej w Ustawieniach.</string>
     <string name="room_list_catchup_empty_title">Jesteś na bieżąco!</string>
     <string name="login_error_unknown_host">Ten adres URL jest nieosiągalny, proszę sprawdź jego poprawność</string>
+    <string name="revoke">Unieważnij</string>
+    <string name="disconnect">Rozłącz</string>
+    <string name="call_failed_dont_ask_again">Nie pytaj ponownie</string>
+
+    <string name="login_error_no_homeserver_found">To nie jest prawidłowy adres serwera Matrix</string>
+    <string name="settings_add_3pid_confirm_password_title">Potwierdź swoje hasło</string>
+    <string name="settings_troubleshoot_test_play_services_quickfix">Napraw Usługi Play</string>
+
+    <string name="settings_troubleshoot_test_fcm_failed_account_missing_quick_fix">Dodaj Konto</string>
+
+    <string name="settings_cryptography_manage_keys">Zarządzanie Kluczami Kryptograficznymi</string>
+    <string name="settings_integration_allow">Zezwól na integracje</string>
+    <string name="settings_integration_manager">Menadżer Integracji</string>
+
+    <string name="settings_fail_to_update_password_invalid_current_password">Hasło jest nieprawidłowe</string>
+    <string name="passwords_do_not_match">Hasła nie pasują do siebie</string>
+
+    <string name="compression_opt_list_choose">Wybierz</string>
+    <string name="media_source_choose">Wybierz</string>
+    <string name="settings_play_shutter_sound">Odtwarzaj dźwięk migawki</string>
+
+    <string name="encryption_information_device_name_with_warning">Nazwa urządzenia (widoczna dla osób, z którymi się komunikujesz)</string>
+    <string name="device_name_warning">Publiczna nazwa urządzenia jest widoczna dla ludzi, z którymi się komunikujesz</string>
+    <string name="encryption_information_unknown_ip">nieznany adres ip</string>
+    <string name="notification_unknown_room_name">Pokój</string>
+    <string name="notification_new_invitation">Nowe Zaproszenie</string>
+    <string name="room_widget_permission_added_by">Ten widget został dodany przez:</string>
+    <string name="room_widget_open_in_browser">Otwórz w przeglądarce</string>
+    <string name="room_widget_permission_theme">Twój motyw</string>
+    <string name="room_widget_permission_room_id">Identyfikator Pokoju</string>
+
+
+    <string name="room_widget_resource_grant_permission">Zezwól</string>
+    <string name="error_empty_field_enter_user_name">Wprowadź nazwę użytkownika.</string>
+    <string name="passphrase_empty_error_message">Wprowadź hasło</string>
+    <string name="keys_backup_setup_step1_advanced">(Zaawansowane)</string>
+    <string name="keys_backup_setup_step2_button_title">Ustaw Hasło</string>
+    <string name="keys_backup_setup_step3_success_title">Sukces !</string>
+    <string name="keys_backup_setup_step3_text_line1">Twoje klucze są archiwizowane.</string>
+    <string name="keys_backup_setup_override_replace">Zastąp</string>
+    <string name="keys_backup_setup_override_stop">Zatrzymaj</string>
+
+    <string name="recovery_key">Klucz Odzyskiwania</string>
+    <string name="unexpected_error">Nieoczekiwany błąd</string>
+    <string name="keys_backup_setup_skip_title">Czy na pewno\?</string>
+    <string name="keys_backup_restore_is_getting_backup_version">Pobieranie wersji kopii zapasowej…</string>
+    <string name="keys_backup_restore_key_enter_hint">Wprowadź Klucz Odzyskiwania</string>
+
+    <string name="keys_backup_restore_setup_recovery_key">Odzyskiwanie Wiadomości</string>
+
+    <string name="network_error_please_check_and_retry">Błąd sieci: sprawdź połączenie i spróbuj ponownie.</string>
+
+    <string name="keys_backup_restoring_computing_key_waiting_message">Obliczanie klucza odzyskiwania…</string>
+    <string name="keys_backup_restoring_downloading_backup_waiting_message">Pobieranie kluczy…</string>
+    <string name="keys_backup_restoring_importing_keys_waiting_message">Importowanie kluczy…</string>
+    <string name="keys_backup_unlock_button">Odblokuj Historię</string>
+    <string name="keys_backup_recovery_code_empty_error_message">Wprowadź klucz odzyskiwania</string>
+    <string name="keys_backup_restore_success_title">Kopia Przywrócona %s !</string>
+    <plurals name="keys_backup_restore_success_description_part2">
+        <item quantity="one">dodano jeden nowy klucz do tej sesji.</item>
+        <item quantity="few">dodano %d nowe klucze do tej sesji.</item>
+        <item quantity="many">dodano %d nowych kluczy do tej sesji.</item>
+    </plurals>
+
+    <string name="keys_backup_get_version_error">Niepowodzenie przy pobieraniu wersji kluczy (%s).</string>
+    <string name="keys_backup_settings_deleting_backup">Usuwanie kopii zapasowej…</string>
+    <string name="keys_backup_settings_checking_backup_state">Sprawdzanie stanu kopii zapasowej</string>
+    <string name="sas_waiting_for_partner">Oczekiwanie na potwierdzenie partnera…</string>
+
+    <string name="sas_verified_successful">Sesja została z powodzeniem zweryfikowana.</string>
+    <string name="sas_cancelled_by_other">Druga strona odrzuciła weryfikację.
+\n%s</string>
+    <string name="reactions">Reakcje</string>
+
+    <string name="last_edited_info_message">Ostatnio zmieniony %2$s przez %1$s</string>
+
+
+    <string name="error_no_network">Brak sieci. Sprawdź swoje połączenie z Internetem.</string>
+    <string name="please_wait">Proszę czekać…</string>
+    <string name="room_preview_no_preview">Tego pokoju nie można podejrzeć</string>
+    <string name="alpha_disclaimer_title">Witaj w programie beta!</string>
+    <string name="settings_security_and_privacy">Bezpieczeństwo i Prywatność</string>
+    <string name="settings_expert">Ekspert</string>
+    <string name="settings_push_rules_no_rules">Brak reguł push</string>
+    <string name="send_file_step_idle">Oczekiwanie…</string>
+    <string name="send_file_step_sending_thumbnail">Wysyłanie miniatury (%1$s / %2$s)</string>
+    <string name="send_file_step_encrypting_file">Szyfrowanie pliku…</string>
+    <string name="send_file_step_sending_file">Wysyłanie pliku (%1$s / %2$s)</string>
+
+    <string name="downloading_file">Pobieranie pliku %1$s…</string>
+    <string name="downloaded_file">Plik %1$s został pobrany!</string>
+
+    <string name="creating_direct_room">Tworzę pokój…</string>
+    <string name="terms_of_service">Warunki Usługi</string>
+    <string name="send_attachment">Wyśli załącznik</string>
+
+    <string name="a11y_create_room">Utwórz nowy pokój</string>
+    <string name="a11y_show_password">Pokaż hasło</string>
+    <string name="a11y_hide_password">Ukryj hasło</string>
+    <string name="a11y_jump_to_bottom">Przewiń do dołu</string>
+
+    <string name="error_file_too_big">Plik \'%1$s\' (%2$s) jest zbyt duży do przesłania. Limit wynosi %3$s.</string>
+
+    <string name="attachment_type_file">Plik</string>
+    <string name="attachment_type_contact">Kontakt</string>
+    <string name="attachment_type_gallery">Galeria</string>
+    <string name="attachment_type_sticker">Naklejka</string>
+    <string name="report_content_spam">To jest spam</string>
+    <string name="report_content_inappropriate">Nieodpowiednia treść</string>
+    <string name="report_content_custom">Inny powód…</string>
+    <string name="report_content_custom_title">Zgłoś tę treść</string>
+    <string name="report_content_custom_hint">Powód zgłoszenia treści</string>
+    <string name="report_content_custom_submit">ZGŁOŚ</string>
+    <string name="block_user">ZABLOKUJ UŻYTKOWNIKA</string>
+
+    <string name="content_reported_title">Treść zgłoszona</string>
+    <string name="content_reported_as_spam_title">Zgłoszone jako spam</string>
+    <string name="sas_cancelled_by_me">Weyfikacja zostaje anulowana.
+\nPowód: %s</string>
+
+    <string name="send_suggestion_content">Proszę napisz swoją sugestię poniżej.</string>
+    <string name="send_suggestion_report_placeholder">Opisz swoją sugestię tutaj</string>
+    <string name="a11y_create_direct_message">Utwórz nową rozmowę bezpośrednią</string>
+    <string name="no_connectivity_to_the_server_indicator">Połączenie z serwerem zostało utracone</string>
+
+    <string name="keys_backup_setup_step3_please_make_copy">Proszę wykonać kopię</string>
+    <string name="settings_preferences">Preferencje</string>
+    <string name="preference_voice_and_video">Głos i wideo</string>
+    <string name="bottom_action_people_x">Wiadomości Bezpośrednie</string>
+
+    <string name="room_filtering_filter_hint">Filtruj rozmowy…</string>
+    <string name="room_filtering_footer_create_new_direct_message">Wyślij nową wiadomość bezpośrednią</string>
+    <string name="add_by_matrix_id">Dodaj przez matrix ID</string>
+    <string name="direct_room_filter_hint">Filtruj wg nazwy użytkownika lub ID…</string>
+
+    <string name="settings_sdk_version">Wersja Matrix SDK</string>
+    <string name="preference_root_help_about">Pomoc i o aplikacji</string>
+
+
+    <string name="room_list_quick_actions_notifications_all_noisy">Wszystkie wiadomości (hałaśliwy)</string>
+    <string name="room_list_quick_actions_notifications_all">Wszystkie wiadomości</string>
+    <string name="room_list_quick_actions_notifications_mentions">Tylko wspomnienia</string>
+    <string name="room_list_quick_actions_notifications_mute">Wycisz</string>
+    <string name="room_list_quick_actions_settings">Ustawienia</string>
+    <string name="no_ignored_users">Nie ignorujesz żadnych użytkowników</string>
+
+    <string name="seen_by">Widziany przez</string>
+
+    <string name="settings_advanced_settings">Zaawansowane ustawienia</string>
+    <string name="settings_developer_mode">Tryb programisty</string>
+    <string name="settings">Ustawienia</string>
+    <string name="room_profile_section_security">Bezpieczeństwo</string>
+    <string name="room_profile_section_more">Więcej</string>
+    <string name="room_profile_section_more_settings">Ustawienia pokoju</string>
+    <string name="room_profile_section_more_notifications">Powiadomienia</string>
+    <string name="room_profile_section_more_leave">Opuść pokój</string>
+    <string name="room_settings_enable_encryption">Włącz szyfrowanie end-to-end</string>
+    <string name="none">Brak</string>
+    <string name="people_no_identity_server">Brak skonfigurowanego serwera tożsamości.</string>
+
+    <string name="call_failed_no_ice_description">Poproś administratora serwera (%1$s) o skonfigurowanie usługi TURN, aby połączenia mogły działać prawidłowo.
+\n
+\nMożesz także użyć publicznego serwera %2$s, choć nie będzie on tak niezawodny i pozna twój adres IP. Wybór możesz zmienić w Ustawieniach.</string>
+    <string name="call_failed_no_ice_use_alt">Spróbuj użyć %s</string>
+    <string name="auth_add_email_message_2">Wprowadź adres email, aby możliwe było odzyskiwanie konta. W przyszłości pozwoli on także odnaleźć Cię Twoim znajomym.</string>
+    <string name="auth_add_phone_message_2">Wprowadź numer telefonu, później pozwoli on Cię odnaleźć Twoim znajomym.</string>
+    <string name="login_error_homeserver_not_found">Nie udało się połączyć z serwerem o podanym adresie URL, upewnij się, że wpisano go poprawnie</string>
+    <string name="invite_no_identity_server_error">Dodaj serwer tożsamości w ustawieniach, aby móc wykonać tę akcję.</string>
+    <string name="settings_add_3pid_authentication_needed">Wymagane jest uwierzytelnienie</string>
+
+
+    <string name="settings_troubleshoot_test_bing_settings_success_with_warn">Niektóre rodzaje wiadomości będą ciche (wygenerują powiadomienie bez dźwięku).</string>
+    <string name="settings_troubleshoot_test_bing_settings_failed_to_load_rules">Nie udało się wczytać niestandardowych reguł, spróbuj ponowić.</string>
+    <string name="settings_troubleshoot_test_play_services_title">Weryfikacja Usług Google</string>
+    <string name="settings_troubleshoot_test_play_services_failed">Riot używa Usług Google Play do dostarczania wiadomości push. Konfiguracja usług nie wydaje się być prawidłowa:
+\n%1$s</string>
+    <string name="settings_troubleshoot_test_fcm_success">Otrzymano token FCM:
+\n%1$s</string>
+    <string name="settings_troubleshoot_test_fcm_failed">Niepowodzenie przy pobieraniu tokena FCM:
+\n%1$s</string>
+    <string name="settings_troubleshoot_test_fcm_failed_account_missing">[%1$s]
+\nRiot nie ma wpływu na wystąpienie tego problemu. Na tym urządzeniu nie ma konta Google. Otwórz menadżer kont i dodaj konto Google.</string>
+    <string name="settings_troubleshoot_test_token_registration_success">Token FCM z powodzeniem zarejestrowany na serwerze domowym.</string>
+    <string name="settings_troubleshoot_test_token_registration_failed">Niepowodzenie przy rejestracji tokena FCM na serwerze domowym:
+\n%1$s</string>
+
+    <string name="settings_troubleshoot_test_service_restart_success">Usługa została zatrzymana i automatycznie uruchomiona ponownie.</string>
+    <string name="settings_troubleshoot_test_service_restart_failed">Usługa nie uruchomiła się ponownie</string>
+
+    <string name="settings_troubleshoot_test_service_boot_success">Usługa zostanie uruchomiona przy starcie urządzenia.</string>
+    <string name="settings_troubleshoot_test_service_boot_failed">Usługa nie zostanie uruchomiona przy starcie urządzenia, nie otrzymasz żadnych powiadomień, dopóki Riot nie zostanie uruchomiony.</string>
+    <string name="sas_security_advise">Dla zwiększenia bezpieczeństwa, zalecamy aby wykonać ten krok osobiście lub przez inne zaufane środki komunikacji.</string>
+    <string name="content_reported_content">Treść została zgłoszona.
+\n
+\nJeśli nie chcesz więcej otrzymywać wiadomości od tego użytkownika, możesz go zablokować by ukryć jego wiadomości</string>
+    <string name="content_reported_as_spam_content">Treść została zgłoszona jako spam.
+\n
+\nJeśli nie chcesz więcej widzieć treści tego użytkownika,możesz go zablokować by ukryć jego wiadomości</string>
+    <string name="settings_troubleshoot_test_bg_restricted_title">Sprawdź ograniczenia pracy w tle</string>
+    <string name="settings_troubleshoot_test_bg_restricted_quickfix">Wyłącz ograniczenia</string>
+
+    <string name="settings_call_notifications_preferences">Konfiguruj powiadomienia połączeń</string>
+    <string name="settings_system_preferences_summary">Wybierz kolor diody LED, wibrację, dźwięk…</string>
+
+
+    <string name="settings_integrations">Integracje</string>
+    <string name="resources_script">Latn</string>
+
+    <string name="auth_add_email_phone_message_2">Wprowadź adres e-mail, aby możliwe było odzyskiwanie konta. Opcjonalnie użyj adresu e-mail lub numeru telefonu aby móc zostać odkrytym przez znajomych.</string>
+    <string name="auth_add_email_and_phone_message_2">Wprowadź adres e-mail, aby możliwe było odzyskiwanie konta. Opcjonalnie użyj adresu e-mail lub numeru telefonu aby móc zostać odkrytym przez znajomych.</string>
+    <string name="settings_call_ringtone_use_default_stun">Pozwól na awaryjny serwer wspomagania połączeń</string>
+    <string name="settings_call_ringtone_use_default_stun_sum">Użyje %s aby wspomagać gdy Twój serwer domowy takiego nie ofertuje (Twój adres IP będzie udostępniony podczas połączenia)</string>
+    <string name="settings_troubleshoot_test_fcm_failed_too_many_registration">[%1$s]
+\nBłąd jest poza kontrolą Riot i nawiązując do Google sygnalizuje on, iż urządzenie posiada zbyt wiele aplikacji zarejestrowanych z FCM. Błąd występuje jedynie w przypadku posiadania skrajnie wielu aplikacji, w związku z czym nie powinno dotknąć to normalnego użytkownika.</string>
+    <string name="settings_troubleshoot_test_fcm_failed_service_not_available">[%1$s]
+\nBłąd jest poza kontrolą Riot. Może on występować z wielu powodów. Przypuszczalnie aplikacja powróci do normalnego stanu po spróbowaniu ponownie, chociaż można sprawdzić także w ustawieniach systemu uprawnienia Usług Google Play dotyczące dostępu do sieci, sprawdzić prawidłowość zegaru urządzenia lub też, może być to błąd niestandardowego oprogramowania systemowego.</string>
+    <string name="settings_troubleshoot_test_service_boot_quickfix">Aktywuj uruchamianie przy starcie systemu</string>
+
+    <string name="settings_troubleshoot_test_bg_restricted_success">Restrykcje dotyczące działania aplikacji w tle są wyłączone dla Riot. Test powinen zostać uruchomiony używając danych komórkowych (bez WIFI).
+\n%1$s</string>
+    <string name="settings_troubleshoot_test_bg_restricted_failed">"Restrykcje dotyczące działania aplikacji w tle są włączone dla Riot.
+\nPraca którą aplikacja próbuje wykonać  będzie agresywnie ograniczona podczas działania w tle i może wpłynąć na wyświetlanie powiadomień.
+\n%1$s"</string>
+    <string name="settings_troubleshoot_test_battery_success">Na Riot nie ma wpływu Optymalizacja Baterii.</string>
+    <string name="settings_troubleshoot_test_battery_failed">Jeżeli użytkownik pozostawi urządzenie odłączone od zasilania oraz nieużywane przez określony okres, z wyłączonym ekranem, urządzenie przejdzie w tryb Doze. Uniemożliwia to aplikacjom dostęp do sieci i opóźnia ich zadania, synchonizację oraz standardowe alarmy.</string>
+    <string name="settings_background_fdroid_sync_mode">Tryb synchronizacji w tle (eksperymentalny)</string>
+    <string name="settings_background_fdroid_sync_mode_battery">Zoptymalizowano dla baterii</string>
+    <string name="settings_background_fdroid_sync_mode_battery_description">Riot będzie synchronizował się w tle w sposób który oszczędza limitowane zasoby urządzenia (baterię).
+\nW zależności od stanu zasobów urządzenia, synchronizacja może być opóźniania przez system operacyjny.</string>
+    <string name="settings_background_fdroid_sync_mode_real_time">Zopytmalizowano dla działania w czasie rzeczywistym</string>
+    <string name="settings_background_fdroid_sync_mode_real_time_description">Riot będzie synchornizował się okresowo o ściśle określonym czasie (konfigurowalne).
+\nWpłynie to na użycie baterii i sieci, na panelu powiadomień pozostanie wyświetlone stałe powiadomiene o nasłuchiwaniu zdarzeń.</string>
+    <string name="settings_background_fdroid_sync_mode_disabled">Brak synchronizacji w tle</string>
+    <string name="settings_background_fdroid_sync_mode_disabled_description">Nie będziesz otrzymywać powiadomień o przychodzących wiadomościach gdy aplikacja będzie działać w tle.</string>
+    <string name="settings_background_sync_update_error">Niepowodzenie przy aktualizacji ustawień.</string>
+
+
+    <string name="settings_set_workmanager_delay">Preferowany interwał synchronizacji</string>
+    <string name="settings_set_workmanager_delay_summary">%s
+\nSynchronizacja może zostać opóźniona w zależności od zasobów (bateria) lub stanu urządzenia (hibernacja).</string>
+    <string name="settings_integrations_summary">Użyj Menedżera Integracji aby zarządzać botami, mostami, widżetami oraz pakietami naklejek.
+\nMenadżerowie Integracji odbierają dane konfiguracji, mogą zmieniać widżety, wysyłać zaproszenia do pokoi oraz ustawiać poziomy uprawnień na Twoje żądanie.</string>
+    <string name="settings_inline_url_preview_summary">Pokaż podgląd linków wewnątrz czatu jeśli twój serwer wspiera tę funkcję.</string>
+    <string name="settings_send_markdown_summary">Formatuj wiadomości używając składni Markdown zanim zostaną wysłane. Pozwala to na zaawansowane formatowanie takie jak używanie asterysków do wyświetlania tekstu w kursywie.</string>
+    <string name="settings_show_join_leave_messages_summary">Nie wpływa to na zaproszenia, wyrzucenia oraz bany.</string>
+    <string name="settings_send_message_with_enter">Wysyłaj wiadomości za pomocą klawisza enter</string>
+    <string name="settings_send_message_with_enter_summary">Przycisk enter na klawiaturze programowej wyśle wiadomość zamiast wprowadzania łamanania linii</string>
+
+    <string name="settings_discovery_category">Znajdź</string>
+    <string name="settings_discovery_manage">Zarządzaj ustawieniami wyszukiwania.</string>
+    <string name="startup_notification_fdroid_battery_optim_message">Riot potrzebuje utrzymać mało wpływowe połączenie w tle, w celu otrzymywania wiarygodnych powiadomień.
+\nNa następnym ekranie zostanie się poproszonym o pozwolenie działania w tle dla Riot, proszę zaakceptować.</string>
+    <string name="settings_data_save_mode_summary">Tryb oszczędzania danych użyje filtra szczegółowego, w związku z czym aktualizacje o obecności i powiadomienia o pisaniu zostaną przefiltrowane.</string>
+
+    <string name="settings_media">Media</string>
+    <string name="settings_default_media_source">Domyślne źródło mediów</string>
+    <string name="encryption_message_recovery">Odzyskiwanie zaszyforwanych wiadomości</string>
+    <plurals name="notification_compat_summary_line_for_room">
+        <item quantity="one">%1$s: 1 wiadomość</item>
+        <item quantity="few">%1$s: %2$d wiadomości</item>
+        <item quantity="many" />
+    </plurals>
+    <plurals name="notification_compat_summary_title">
+        <item quantity="one">%d powiadomienie</item>
+        <item quantity="few">%d powiadomień</item>
+        <item quantity="many" />
+    </plurals>
+
+    <string name="notification_unknown_new_event">Nowe wydarzenie</string>
+    <string name="notification_new_messages">Nowe wiadomości</string>
+    <string name="notification_sender_me">Ja</string>
+    <string name="notification_inline_reply_failed">** Nie udało się wysłać - proszę otworzyć pokój</string>
+
+    <string name="room_widget_activity_title">Widżet</string>
+    <string name="room_widget_permission_title">Załaduj widżet</string>
+    <string name="room_widget_permission_webview_shared_info_title">Używając tego pliki cookies mogą zostać ustawione i dane wspóldzielone z %s:</string>
+    <string name="room_widget_permission_shared_info_title">Używając tego dane mogą być współdzielone z %s:</string>
+    <string name="room_widget_failed_to_load">Uruchomienie widżetu nie powiodło się.
+\n%s</string>
+    <string name="room_widget_reload">Przeładuj widżet</string>
+    <string name="room_widget_revoke_access">Cofnij dostęp dla mnie</string>
+
+    <string name="room_widget_permission_display_name">Wyświetlana nazwa</string>
+    <string name="room_widget_permission_avatar_url">Adres URL awatara</string>
+    <string name="room_widget_permission_user_id">Twój ID użytkownika</string>
+    <string name="room_widget_permission_widget_id">ID Widżetu</string>
+    <string name="error_jitsi_not_supported_on_old_device">Przepraszamy, połączenia konferencyjne za pomocą Jitsi nie są wspierane na starszych urządzeniach (urządzenia z systemem Android poniżej wersji 5.0)</string>
+    <string name="room_widget_resource_permission_title">Widżet chce użyć następujących zasobów:</string>
+    <string name="room_widget_resource_decline_permission">Zablokuj wszystko</string>
+    <string name="room_widget_webview_access_camera">Użyj aparatu</string>
+    <string name="room_widget_webview_access_microphone">Użyj mikrofonu</string>
+    <string name="room_widget_webview_read_protected_media">Odczytaj media zabezpieczone DRM</string>
+
+    <string name="integration_manager_not_configured">Nie skonfigurowano menedżera integracji.</string>
+    <string name="settings_labs_native_camera_summary">Uruchom systemową kamerę zamiast niestandardowego ekranu kamery w aplikacji.</string>
+    <string name="widget_integration_review_terms">Aby kontynuować, musisz zaakceptować Warunki użytkowania dla tej usługi.</string>
+
+    <string name="no_valid_google_play_services_apk">Nie znaleziono prawidłowej aplikacji Usługi Google Play. Powiadomienia mogą nie działać prawidłowo.</string>
+
+    <string name="store_title">Riot.im - Rozmawiaj, we własny sposób</string>
+    <string name="store_short_description">Bezpieczna aplikacja czatu całkowicie pod Twoją kontrolą.</string>
+    <string name="store_full_description">Aplikacja czatu, całkowicie pod twoją kontrolą i całkowicie dopasowująca się. Riot pozwala na komunikowanie się w jakikolwiek sposób chcesz. Stworzony dla [Matrix] - standardu otwartej, zdecentralizowanej komunikacji.
+\n
+\nStwórz darmowe konto matrix.org, zdobądź swój własny serwer na https://modular.im, lub użyj innego serwera Matrix.
+\n
+\nDlaczego warto wybrać Riot.im\?
+\n
+\n• KOMPLETNA KOMUNIKACJA: Stwórz pokoje dla twojego zespołu, przyjaciół, społeczności - tak, jak lubisz! Czatuj, udostępniaj pliki, dodawaj widżety i wykonuj połączenia głosowe lub wideo - wszystko za darmo.
+\n
+\n• SILNA INTEGRACJA: Używaj Riot.im z narzędziami które znasz i kochasz. Z Riot.im możesz pisać z użytkownikami i grupami na innych aplikacjach do czatu.
+\n
+\n• PRYWATNE I BEZPIECZNE: Utrzymuj twoje konwersacje w sekrecie. Nowoczesne szyfrowanie typu \"end-to-end\" zapewnia, że to co jest prywatne, pozostaje prywatne
+\n
+\n• OTWARTE, NIE ZAMKNIĘTE: Otwartoźródłowe i oparte o Matrix. Bądź w posiadaniu swoich danych posiadając swój własny serwer, lub wybierając taki, któremu ufasz.
+\n
+\n•GDZIEKOLWIEK JESTEŚ: Bądź w kontakcie gdziekolwiek jesteś wraz z w pełni synchronizowaną historią wiadomości na wszystkich twoich urządzeniach lub na https://riot.im.</string>
+
+    <string name="passphrase_passphrase_too_weak">Hasło jest zbyt słabe</string>
+
+    <string name="keys_backup_passphrase_not_empty_error_message">Proszę usunąć hasło, jeżeli chcesz aby Riot wygenerował klucz odzyskiwania.</string>
+    <string name="keys_backup_no_session_error">Brak dostępnych sesji Matrix</string>
+
+    <string name="keys_backup_setup_step1_title">Nie utrać zaszyfrowanych wiadomości</string>
+    <string name="keys_backup_setup_step1_description">Wiadomości w pokojach zaszyfrowanych są bezpieczne dzięki szyfrowaniu end-to-end. Jedynie Ty i Twój odbiorca posiadają klucze dla tych wiadomości.
+\n
+\nBezpiecznie utwórz kopię zapasową, aby ich nie utracić.</string>
+    <string name="keys_backup_setup">Zacznij używać Kopii Zapasowej Kluczy</string>
+    <string name="keys_backup_setup_step1_manual_export">Wyeksportuj klucze ręcznie</string>
+
+    <string name="keys_backup_setup_step2_text_title">Zabezpiecz swoją kopię zapasową używając hasła.</string>
+    <string name="keys_backup_setup_step2_text_description">Będziemy przechowywać zaszyfrowaną kopię Twoich kluczy na serwerze domowym. Chroń swoją kopię zapasową hasłem, aby pozostała bezpieczna.
+\n
+\nDla pełni bezpieczeństwa, powinno być ono inne niż hasło konta.</string>
+    <string name="keys_backup_setup_creating_backup">Tworzenie kopii zapasowej</string>
+    <string name="keys_backup_setup_step1_recovery_key_alternative">Lub, zabezpiecz swoją kopię zapasową z Kluczem Odzyskiwania i zachowaj w bezpiecznym miejscu.</string>
+    <string name="keys_backup_setup_step2_skip_button_title">(Zaawansowane) Ustaw za pomocą Klucza Odzyskiwania</string>
+    <string name="keys_backup_setup_step3_text_line2">Twój klucz odzyskiwania jest siatką bezpieczeństwa - możesz użyć go, aby odzyskać dostęp do zaszyfrowanych wiadomości jeżeli zapomnisz hasła.
+\nPrzechowuj swój klucz odzyskiwania w bardzo bezpiecznym miejscu, takim jak menedżer haseł (lub sejf)</string>
+    <string name="keys_backup_setup_step3_text_line2_no_passphrase">Przechowuj swój klucz odzyskiwania w bardzo bezpiecznym miejscu, takim jak menedżer haseł (lub sejf)</string>
+    <string name="keys_backup_setup_step3_button_title_no_passphrase">Zrobiłem kopię</string>
+    <string name="keys_backup_setup_step3_copy_button_title">Zapisz Klucz Odzyskiwania</string>
+    <string name="keys_backup_setup_step3_save_button_title">Zapisz jako plik</string>
+    <string name="recovery_key_export_saved_as_warning">"Klucz odzyskiwania został zapisany do  \'%s\'.
+\n
+\nUwaga: plik może zostać usunięty, jeżeli aplikacja jest odinstalowana."</string>
+
+    <string name="keys_backup_setup_override_backup_prompt_tile">Kopia zapasowa już istnieje na Twoim serwerze domowym</string>
+    <string name="keys_backup_setup_override_backup_prompt_description">Wygląda na to, iż kopia zapasowa kluczy została skonfigurowana za pomocą innej sesji. Czy chcesz zastąpić ją tą, którą tworzysz\?</string>
+    <string name="keys_backup_setup_step3_generating_key_status">Generowanie Klucza Odzyskiwania używając hasła, proces może zająć kilka sekund.</string>
+    <string name="keys_backup_setup_backup_started_title">Kopia zapasowa uruchomiona</string>
+    <string name="keys_backup_setup_backup_started_message">Twoje klucze szyfrujące będą kopiowane do kopii zapasowej w tle przez Twój serwer domowy. Wstępna kopia zapasowa może zająć kilka minut.</string>
+
+
+    <string name="keys_backup_setup_skip_msg">Utracisz dostęp do swoich wiadomości jeżeli wylogujesz się lub utracisz to urządzenie.</string>
+
+    <string name="keys_backup_restore_with_passphrase">Użyj kopii zapasowej klucza aby odblokować historię zaszyfrowanych wiadomości</string>
+    <string name="keys_backup_restore_use_recovery_key">użyj klucza odzyskiwania</string>
+    <string name="keys_backup_restore_with_recovery_key">Użyj Klucza Odzyskiwania aby odblokować historię zaszyfrowanych wiadomości</string>
+    <string name="keys_backup_passphrase_error_decrypt">Kopia zapasowa nie może zostać zdeszyfrowana za pomocą tego hasła: proszę upewnij się, czy wprowadzone hasło jest poprawne.</string>
+    <string name="keys_backup_restoring_waiting_message">Przywracanie kopii zapasowej:</string>
+    <string name="keys_backup_recovery_code_error_decrypt">Kopia zapasowa nie może zostać zdeszyfrowana za pomocą tego klucza odzyskiwania: proszę upewnij się, czy wprowadzony klucz odzyskiwania jest poprawny.</string>
+
+    <string name="keys_backup_restore_success_description">Przywrócono %1$d kluczy sesji, i dodano %2$d nowych kluczy które nie były znane tej sesji</string>
+    <string name="keys_backup_no_keysbackup_sdk_error">Szyfrowanie sesji nie jest aktywowane</string>
+
+
+    <string name="keys_backup_settings_status_ko">Kopia zapasowa klucza nie jest aktywna dla tej sesji.</string>
+    <string name="keys_backup_settings_status_not_setup">Twoje klucze nie są będą zapisywane w kopii zapasowej od tej sesji.</string>
+
+    <string name="keys_backup_settings_signature_from_unknown_device">Kopia zapasowa posiada sygnaturę od nieznanej sesji z ID %s.</string>
+    <string name="keys_backup_settings_valid_signature_from_this_device">Kopia zapasowa posiada prawidłową sygnaturę dla tej sesji.</string>
+    <string name="keys_backup_settings_valid_signature_from_verified_device">Kopia zapasowa posiada prawidłową sygnaturę z zweryfikowanej sesji %s.</string>
+    <string name="keys_backup_settings_invalid_signature_from_verified_device">Kopia zapasowa posiada nieprawidłową sygnaturę ze zweryfikowej sesji %s</string>
+    <string name="keys_backup_settings_invalid_signature_from_unverified_device">Kopia zapasowa posiada niezweryfikową sygnaturę z nieznanej sesji %s</string>
+    <string name="keys_backup_get_trust_error">Nie udało się uzyskać zaufanych informacji dla kopii zapasowej (%s).</string>
+
+    <string name="keys_backup_settings_untrusted_backup">Aby użyć Kopii Zapasowej Kluczy dla tej sesji, przywróć ją za pomocą hasła lub klucza odzyskiwania.</string>
+    <string name="keys_backup_settings_delete_backup_error">Usuwanie kopii zapasowej nie powiodło się (%s)</string>
+
+    <string name="new_recovery_method_popup_title">Nowa kopia zapasowa kluczy</string>
+    <string name="new_recovery_method_popup_was_me">To byłem(-łam) ja</string>
+    <string name="keys_backup_banner_setup_line1">Nigdy nie utrać zaszyfrowanych wiadomości</string>
+    <string name="keys_backup_banner_setup_line2">Zacznij korzystać z Kopii Zapasowej Kluczy</string>
+
+    <string name="keys_backup_banner_recover_line1">Nigdy nie utrać zaszyfrowanych wiadomości</string>
+    <string name="keys_backup_banner_recover_line2">Użyj Kopii Zapasowej Kluczy</string>
+
+    <string name="keys_backup_banner_update_line1">Nowe klucze szyfrowanych wiadomości</string>
+    <string name="keys_backup_banner_update_line2">Zarządzaj w Kopii Zapasowej Kluczy</string>
+
+    <string name="keys_backup_banner_in_progress">Tworzenei kopii zapasowej kluczy…</string>
+
+    <plurals name="keys_backup_info_keys_backing_up">
+        <item quantity="one">Kopiowanie %d klucza…</item>
+        <item quantity="few">Kopiowanie %d kluczy…</item>
+        <item quantity="many" />
+    </plurals>
+
+    <string name="autodiscover_invalid_response">Nieprawidłowa odpowiedź funkcji autoodkrywania serwera domowego</string>
+    <string name="autodiscover_well_known_autofill_dialog_title">Opcje automatycznego uzupełniania serwerów</string>
+    <string name="autodiscover_well_known_autofill_dialog_message">Riot wykryło niestandardową konfigurację serwera dla Twojej domeny userID \"%1$s\":
+\n%2$s</string>
+    <string name="autodiscover_well_known_autofill_confirm">Użyj Konfiguracji</string>
+
+    <string name="invalid_or_expired_credentials">Zostałeś(-łaś) wylogowana ze względu na nieprawidłowe lub wygasłe dane logowania.</string>
+
+    <string name="sas_verify_title">Zweryfikuj porównując krótki ciąg tekstowy.</string>
+    <string name="sas_verify_start_button_title">Rozpocznij weryfikację</string>
+    <string name="sas_incoming_request_title">Przychodzące żądanie weryfikacji</string>
+    <string name="sas_incoming_request_description">Zweryfikuj tą sesję poprzez oznaczenie jej jako zaufanej. Zaufanie sesji innych osób przynosi spokój na umyśle gdy są to szyfrowane wiadomości end-to-end.</string>
+    <string name="sas_incoming_request_description_2">Werfikacja tej sesji oznaczy ją jako zaufaną, a także oznaczy Twoją sesję jako zaufaną dla rozmówcy.</string>
+
+    <string name="sas_view_request_action">Wyświetl żądanie</string>
+    <string name="sas_verified_successful_description">Bezpieczne wiadomości od tego użytkownika są zabezpeiczone za pomocą szyfrowania end-to-end i są nie do odczytania przez osoby trzecie.</string>
+    <string name="call_failed_no_ice_title">Połączenie nie powiodło się z powodu niewłaściwie skonfigurowanego serwera</string>
+    <string name="settings_add_3pid_flow_not_supported">Nie możesz tego zrobić z mobilnej aplikacji Riot</string>
+    <string name="settings_troubleshoot_test_bing_settings_failed">Niektóre powiadomienia są wyłączone w osobistej konfiguracji.</string>
+    <string name="settings_troubleshoot_test_play_services_success">Usługi Google Play są aktualne.</string>
+    <string name="settings_troubleshoot_test_service_restart_title">Automatycznie uruchom ponownie usługę powiadomień</string>
+    <string name="sas_emoji_description">Potwierdź, że następujące emoji pojawiły się na ekranie partnera</string>
+    <string name="sas_decimal_description">Potwierdź, że następujące liczby pojawiły się na ekranie partnera</string>
+
+    <string name="sas_incoming_verification_request_dialog">Otrzymano przychodzące żądanie weryfikacji.</string>
+    <string name="sas_got_it">Rozumiem</string>
+
+    <string name="sas_verifying_keys">Nic się nie pojawiło\? Nie wszystkie aplikacje obsługują już interaktywną weryfikację. Spróbuj weryfikacji starszego typu.</string>
+    <string name="sas_legacy_verification_button_title">Użyj weryfikacji starszego typu.</string>
+
+    <string name="sas_cancelled_dialog_title">Weryfikacja Anulowana</string>
+    <string name="sas_verification_request_notification_channel">Interaktywna Weryfikacja Sesji</string>
+    <string name="sas_error_m_user">Użytkownik anulował weryfikację</string>
+    <string name="sas_error_m_timeout">Upłynął limit czasu weryfikacji</string>
+    <string name="sas_error_m_unknown_transaction">Sesja nie rozpoznała tej transakcji</string>
+    <string name="sas_error_m_unknown_method">Sesje nie mogą porozumieć się w sprawie wykorzystania metody szyfrowania (wymiana kluczy, hasz, MAC lub SAS)</string>
+    <string name="sas_error_m_mismatched_commitment">Zobowiązanie bitowe nie zgadza się</string>
+    <string name="sas_error_m_mismatched_sas">SAS nie zgadza się</string>
+    <string name="sas_error_m_unexpected_message">Sesja otrzymała niespodziewaną wiadomość</string>
+    <string name="sas_error_m_invalid_message">Otrzymano nieprawidłową wiadomość</string>
+    <string name="security_warning_identity_server">Poprzednie wersje Riot posiadały błąd bezpieczeństwa, który umożliwiał Twojemu serwerowi tożsamości (%1$s) dostęp do Twojego konta. Jeżeli ufasz %2$s, możesz to zignorować; w przeciwnym wypadku wyloguj się i zaloguj ponownie.
+\n
+\nInformacje o szczegółach tutaj:
+\nhttps://medium.com/@RiotChat/36b4792ea0d6</string>
+
+    <string name="room_list_empty">Dołącz do pokoju, aby rozpocząć korzystanie z aplikacji.</string>
+    <string name="room_list_catchup_welcome_body">Zapoznaj się z nieprzeczytanymi wiadomościami tutaj</string>
+    <string name="room_list_people_empty_body">Twoje rozmowy bezpośrednie będą wyświetlane tutaj</string>
+    <string name="room_list_rooms_empty_body">Twoje pokoje będą wyświetlane tutaj</string>
+
+    <string name="malformed_message">Nieprawidłowe zdarzenie, nie można wyświetlić</string>
+    <string name="room_preview_world_readable_room_not_supported_yet">Podgląd globalnego, publicznego pokoju nie jest wciąż wspierany w RiotX</string>
+
+    <string name="keys_backup_unable_to_get_trust_info">Wystąpił błąd podczas otrzymywania zaufanych informacji</string>
+    <string name="keys_backup_unable_to_get_keys_backup_data">Wystąpił błąd podczas uzyskiwania danych kluczy kopii zapasowej</string>
+
+    <string name="alpha_disclaimer_content_line_1">Jako że RiotX jest we wczesnej fazie rozwoju, niektóre funkcje mogą być niedostępne i możesz doświadczyć błędów.</string>
+    <string name="alpha_disclaimer_content_line_2_gplay">Najnowsza lista funkcji jest zawsze na %1$s, i jeżeli znajdziesz błąd, proszę wyślij raport w lewym górnym menu poprzez \"Ekran domowy\", postaramy załatać się go tak szybko, jak tylko się da.</string>
+    <string name="alpha_disclaimer_content_line_2_gplay_colored_part">Opis w Sklepie Play</string>
+    <string name="alpha_disclaimer_content_line_2_fdroid">Jeżeli znajdziesz błędy, proszę wyślij raport za pomocą menu w lewym górnym rogu \"Ekranu domowego\", postaramy się je naprawić tak szybko, jak tylko się da.</string>
+
+    <string name="import_e2e_keys_from_file">Importowanie kluczy E2E z pliku \"%1$s\".</string>
+
+    <string name="settings_other_third_party_notices">Informacje o stronach trzecich</string>
+    <string name="navigate_to_room_when_already_in_the_room">Już wyświetlasz ten pokój!</string>
+
+    <string name="push_gateway_item_app_id">id_aplikacji:</string>
+    <string name="push_gateway_item_push_key">klucz_push:</string>
+    <string name="push_gateway_item_app_display_name">wyświetlana_nazwa_aplikacji:</string>
+    <string name="push_gateway_item_device_name">nazwa_sesji:</string>
+    <string name="push_gateway_item_url">Url:</string>
+    <string name="push_gateway_item_format">Format:</string>
+
+    <string name="settings_troubleshoot_test_token_registration_quick_fix">Zarejestruj token</string>
+
+    <string name="send_suggestion_sent">Dziękujemy, sugestia została szczęśliwie wysłana</string>
+    <string name="send_suggestion_failed">Wysłanie sugestii nie powiodło się (%s)</string>
+
+    <string name="settings_labs_show_hidden_events_in_timeline">Wyświetl ukryte wydarzenia na linii czasowej</string>
+
+    <string name="store_riotx_title">RiotX - Klient Matrix następnej generacji</string>
+    <string name="store_riotx_short_description">Szybszy i lżejszy klient Matrix używający najnowszych frameworków Androida</string>
+    <string name="store_riotx_full_description">RiotX jest nowym klientem dla protokołu Matrix (Matrix.org): otwarta sieć dla bezpiecznej, zdecentralizowej komunikacji. RiotX jest całkowicie przepisanym klientem Riot, opartym na nowym SDK Matrix dla systemu Android.
+\n
+\nUwaga: Jest to wersja beta. RiotX jest obecnie w fazie aktywnego rozwoju i posiada ograniczenia oraz (mamy nadzieje że niewiele) błędy. Wszystkie opinie są mile widziane!
+\n
+\nRiotX wspiera: • Logowanie do istniejącego konta • Tworzenie pokoi oraz dołączanie do pokoi publicznych • Akceptowanie i odrzucanie zaproszeń • Wyświetlanie listy pokoi użytkowników • Wyświetlanie informacji o pokoju • Wysyłanie wiadomości tekstowych • Wysyłanie załączników • Odczytywanie i pisanie wiadomości w zaszyfrowanych pokojach • Kryptografia: Kopię zapasową kluczy E2E, zaawansowaną weryfikację urządzeń, żądanie udostępniania kluczy i odpowiedzi na nie • Powiadomienia push • Jasne, Ciemne oraz Czarne motywy
+\n
+\nNie wszystkie funkcje Riot są wdrożone w RiotX. Główne niedostępne (pojawią się już wkrótce!) funkcje: • Ustawienia pokoi (wyświetl listę członków pokoi) • Rozmowy • Widżety • …</string>
+
+    <string name="edited_suffix">(edytowano)</string>
+
+    <string name="riotx_no_registration_notice">%1$s aby utworzyć konto.</string>
+    <string name="riotx_no_registration_notice_colored_part">Użyj starszej aplikacji</string>
+
+
+    <string name="message_edits">Edycje wiadomości</string>
+    <string name="no_message_edits_found">Nie znaleziono edycji</string>
+
+    <string name="labs_swipe_to_reply_in_timeline">Aktywuj gest przesunięcia, aby odpowiedzieć na osi czasu</string>
+
+    <string name="link_copied_to_clipboard">Link skopiowany do schowka</string>
+
+    <string name="direct_room_no_known_users">Nie znaleziono, użyj Dodaj poprzez ID Matrix aby wyszukać na serwerze.</string>
+    <string name="direct_room_start_search">Zacznij pisać, aby uzyskać rezultaty</string>
+    <string name="joining_room">Dołączanie do pokoju…</string>
+
+    <string name="message_view_edit_history">Wyświetl historię edycji</string>
+
+    <string name="review_terms">Sprawdź Warunki</string>
+    <string name="terms_description_for_identity_server">Bądź odkryty przez innych</string>
+    <string name="terms_description_for_integration_manager">Używaj Botów, mostów, widżetów i paczek naklejek</string>
+
+    <string name="read_at">Czytaj na</string>
+
+
+    <string name="settings_discovery_identity_server_info">Obecnie używasz %1$s aby odkrywać i być odkrytym przez kontakty, które znasz.</string>
+    <string name="settings_discovery_identity_server_info_none">Nie używasz serwera tożsamości. Aby odkrywać i być odkrywanym przez kontakty, które znasz, skonfiguruj jeden poniżej.</string>
+    <string name="settings_discovery_emails_title">Rozpoznawalny adres e-mail</string>
+    <string name="settings_discovery_no_mails">Opcje odkrywania pojawią się w momencie gdy dodasz adres e-mail.</string>
+    <string name="settings_discovery_no_msisdn">Opcje odkrywania pojawią się w momencie gdy dodasz numer telefonu.</string>
+    <string name="settings_discovery_disconnect_identity_server_info">Odłączenie od serwera tożsamości oznacza, iż nie będziesz mógł(-ła) zostać odkryty(-ta) przez innych użytkowników i nie będziesz mógł(-ła) zapraszać innych za pomocą adresu e-mail oraz numeru telefonu.</string>
+    <string name="settings_discovery_msisdn_title">Rozpoznawalne numery telefonu</string>
+    <string name="settings_discovery_confirm_mail">Wysłaliśmy e-mail potwierdzający do %s, sprawdź swoją skrzynkę i naciśnij link potwierdzający</string>
+    <string name="settings_discovery_mail_pending">Oczekiwanie</string>
+
+    <string name="settings_discovery_enter_identity_server">Wprowadź nowy serwer tożsamości</string>
+    <string name="settings_discovery_bad_identity_server">Nie można połączyć z serwerem tożsamości</string>
+    <string name="settings_discovery_please_enter_server">Wprowadź adres serwera tożsamości</string>
+    <string name="settings_discovery_no_terms_title">Serwer tożsamości nie posiada warunków usługi</string>
+    <string name="settings_discovery_no_terms">Wybrany system tożsamości nie posiada jakichkolwiek warunków usługi. Kontynuuj jedynie, gdy ufasz właścicielowi usługi</string>
+    <string name="settings_text_message_sent">Wiadomość tekstowa wysłana do %s. Proszę wprowadzić kod weryfikacyjny w niej zawarty.</string>
+
+    <string name="settings_discovery_disconnect_with_bound_pid">Udostępniasz adres e-mail lub numer telefonu serwerowi tożsamości %1$s. Musisz ponownie połączyć się z %2$s aby ich nie udostępniać.</string>
+    <string name="settings_agree_to_terms">Akceptuj Warunki Usługi serwera tożsamości (%s) aby pozwolić na bycie odkrytym za pomocą adresu e-mail lub numeru telefonu.</string>
+
+    <string name="labs_allow_extended_logging">Aktywuj szczegółowe dzienniki.</string>
+    <string name="labs_allow_extended_logging_summary">Dzienniki szczegółowe pomogą twórcom poprzez udostępnianie większej ilości danych, które zostaną wysłane, gdy potrząśniesz wściekle. Nawet jeżeli zostaną aktywowane, aplikacja nie zapisuje szczegółów wiadomości oraz innych danych prywatnych.</string>
+
+
+    <string name="error_terms_not_accepted">Spróbuj ponownie, gdy zaakceptujesz warunki usługi oraz warunki ogólne serwera domowego.</string>
+
+    <string name="error_network_timeout">Wygląda na to, iż serwer potrzebuje wiele czasu aby odpowiedzieć i może być to spowodowane zarówno słabą łącznością jak i problemem z serwerem. Spróbuj ponownie za chwilę.</string>
+
+    <string name="a11y_open_drawer">Otwórz panel nawigacji</string>
+    <string name="a11y_create_menu_open">Otwórz menu tworzenia pokoju</string>
+    <string name="a11y_create_menu_close">Zamknij menu tworzenia pokoju…</string>
+    <string name="a11y_close_keys_backup_banner">Zamknij baner kopii zapasowej kluczy</string>
+    <string name="two_and_some_others_read">odczytano przez %1$s, %2$s oraz %3$d</string>
+    <string name="three_users_read">odczytano przez %1$s, %2$s oraz %3$s</string>
+    <string name="two_users_read">odczytano przez %1$s oraz %2$s</string>
+    <string name="one_user_read">%s odczytał</string>
+    <plurals name="fallback_users_read">
+        <item quantity="one">1 użytkownik odczytał</item>
+        <item quantity="few">%d użytkowników odczytało</item>
+        <item quantity="many" />
+    </plurals>
+
+    <string name="error_attachment">Wystąpił błąd poczas otrzymywania załącznika.</string>
+    <string name="attachment_type_audio">Audio</string>
+    <string name="error_handling_incoming_share">Nie można obsłużyć otrzymanych danych</string>
+
+    <string name="content_reported_as_inappropriate_title">Zgłoszono jako nieodpowiedni</string>
+    <string name="content_reported_as_inappropriate_content">Zawartość została zgłoszona jako niewłaścwa.
+\n
+\nJeżeli nie chcesz widzieć treści od tego użytkownika, możesz go zablokować aby ukryć jego wiadomości</string>
+
+    <string name="permissions_rationale_msg_keys_backup_export">Riot potrzebuje uprawnień aby zapisywać klucze E2E na dysku.
+\n
+\nPozwól na dostęp w następnym oknie aby móc eksportować klucze ręcznie.</string>
+
+    <string name="room_list_quick_actions_leave">Opuść pokój</string>
+    <string name="notice_member_no_changes">%1$s nie dokona(-ła) zmian</string>
+    <string name="command_description_spoiler">Wysyła wiadomość jako spoiler</string>
+    <string name="spoiler">Spoiler</string>
+    <string name="reaction_search_type_hint">Wprowadź słowa kluczowe aby znaleźć reakcję.</string>
+
+    <string name="help_long_click_on_room_for_more_options">Naciśnij długo na pokój aby wyświetlić więcej opcji</string>
+
+
+    <string name="room_join_rules_public">%1$s ustawił(-a) pokój dostępnym publicznie dla każdego, kto zna link.</string>
+    <string name="room_join_rules_invite">%1$s ustawił(-a) pokój tylko dla zaproszonych.</string>
+    <string name="timeline_unread_messages">Nieprztane wiadomości</string>
+
+    <string name="login_splash_title">Wyzwól swoją komunikację</string>
+    <string name="login_splash_text1">Czatuj z osobami bezpośrednio lub w grupach</string>
+    <string name="login_splash_text2">Pozostaw konwersacje prywatnymi za pomocą szyfrowania</string>
+    <string name="login_splash_text3">Rozszerz i dopasuj swoje doświadczenie</string>
+    <string name="login_splash_submit">Rozpocznij</string>
+
+    <string name="login_server_title">Wybierz serwer</string>
+    <string name="login_server_text">Tak jak adres e-mail, konta mają jeden dom, aczkolwiek możesz rozmawiać ze wszystkimi</string>
+    <string name="login_server_matrix_org_text">Dołącz do milionów, za darmo, na największym publicznym serwerze</string>
+    <string name="login_server_modular_text">Hosting premium dla organizacji</string>
+    <string name="login_server_modular_learn_more">Dowiedz się więcej</string>
+    <string name="login_server_other_title">Inne</string>
+    <string name="login_server_other_text">Ustawienia niestandardowe i zaawansowane</string>
+
+    <string name="login_continue">Kontynuuj</string>
+    <string name="login_connect_to">Połącz z %1$s</string>
+    <string name="login_connect_to_modular">Połącz z Modular</string>
+    <string name="login_connect_to_a_custom_server">Połącz z serwerem niestandardowym</string>
+    <string name="login_signin_to">Zaloguj się do %1$s</string>
+    <string name="login_signup">Zarejestruj</string>
+    <string name="login_signin">Zaloguj się</string>
+    <string name="login_signin_sso">Kontynuuj za pomocą logowania jednostopniowego</string>
+
+    <string name="login_server_url_form_modular_hint">Adres Modular</string>
+    <string name="login_server_url_form_other_hint">Adres</string>
+    <string name="login_server_url_form_modular_text">Hosting premium dla organizacji</string>
+    <string name="login_server_url_form_modular_notice">Wprowadź adres Riot Modular lub serwera którego chcesz użyć</string>
+    <string name="login_server_url_form_other_notice">Wprowadź adres serwera lub Riot z którym chcesz się połączyć</string>
+
+    <string name="login_sso_error_message">Wystąpił błąd podczas ładowania strony: %1$s (%2$d)</string>
+    <string name="login_mode_not_supported">Aplikacja nie jest w stanie zalogować się do tego serwera domowego. Serwer domowy obsluguje następujące metody logowania: %1$s.
+\n
+\nCzy chcesz zalogować się używając klienta sieciowego\?</string>
+    <string name="login_registration_disabled">Przepraszamy, serwer nie obsługuje tworzenia nowych kont.</string>
+    <string name="login_registration_not_supported">Aplikacja nie jest w stanie utworzyć konta na tym serwerze domowym.
+\n
+\nCzy chcesz zarejestrować się używając klienta sieciowego\?</string>
+
+    <string name="login_login_with_email_error">E-mail nie jest powiązany z kontem.</string>
+
+    <string name="login_reset_password_on">Zresetuj hasło na %1$s</string>
+    <string name="login_reset_password_notice">Wiadomość weryfikacyjna zostanie wysłana na adres e-mail aby potwierdzić ustawienie nowego hasła.</string>
+    <string name="login_reset_password_submit">Dalej</string>
+    <string name="login_reset_password_email_hint">E-mail</string>
+    <string name="login_reset_password_password_hint">Nowe hasło</string>
+
+    <string name="login_reset_password_warning_title">Uwaga!</string>
+    <string name="login_reset_password_warning_content">Zmiana hasła zresetuje wszystkie klucze szyfrowania end-to-end dla wszystkich twoich sesji, czyniąc zaszyfrowaną historię czasu nie do odczytania. Ustaw Kopię Zapasową Kluczy lub wyeksportuj klucze pokoju do innej sesji przed resetowaniem hasła.</string>
+    <string name="login_reset_password_warning_submit">Kontynuuj</string>
+
+    <string name="login_reset_password_error_not_found">Adres e-mail nie został połączony z kontem</string>
+
+    <string name="login_reset_password_mail_confirmation_title">Sprawdź swoją skrzynkę</string>
+    <string name="login_reset_password_mail_confirmation_notice">E-mail weryfikacyjny został wysłany do %1$s.</string>
+    <string name="login_reset_password_mail_confirmation_notice_2">Naciśnij na link aby potwierdzić nowe hasło. Po naciśnięciu na link, który je zawiera, naciśnij poniżej.</string>
+    <string name="login_reset_password_mail_confirmation_submit">Zweryfikowałem(-łam) swój adres e-mail</string>
+
+    <string name="login_reset_password_success_title">Sukces!</string>
+    <string name="login_reset_password_success_notice">Hasło zostało zresetowane.</string>
+    <string name="login_reset_password_success_notice_2">Zostałeś(-łaś) wylogowany(-na) ze wszystkich sesji i nie będziesz otrzymywać powiadomień push. Aby re-aktywować powiadomienia, zaloguj się ponownie na każdym z urządzeń.</string>
+    <string name="login_reset_password_success_submit">Powróć do logowania</string>
+
+    <string name="login_reset_password_cancel_confirmation_title">Ostrzeżenie</string>
+    <string name="login_reset_password_cancel_confirmation_content">Hasło wciąż nie zostało zmienione.
+\n
+\nZatrzymać proces zmiany hasła\?</string>
+
+    <string name="login_set_email_title">Ustaw adres e-mail</string>
+    <string name="login_set_email_notice">Ustaw e-mail aby odzyskać konto. Później, opcjonalnie, będziesz w stanie pozwolić na odkrycie Ciebie za pomocą Twojego adresu e-mail.</string>
+    <string name="login_set_email_mandatory_hint">E-mail</string>
+    <string name="login_set_email_optional_hint">E-mail (nieobowiązkowy)</string>
+    <string name="login_set_email_submit">Dalej</string>
+
+    <string name="login_set_msisdn_title">Ustaw numer telefonu</string>
+    <string name="login_set_msisdn_notice">Ustaw numer telefonu, aby pozwolić innym na odkrycie Ciebie za pomocą numeru telefonu.</string>
+    <string name="login_set_msisdn_notice2">Użyj formatu międzynarodowego.</string>
+    <string name="login_set_msisdn_mandatory_hint">Numer telefonu</string>
+    <string name="login_set_msisdn_optional_hint">Numer telefonu (nieobowiązkowy)</string>
+    <string name="login_set_msisdn_submit">Dalej</string>
+
+    <string name="login_msisdn_confirm_title">Potwierdź numer telefonu</string>
+    <string name="login_msisdn_confirm_notice">Wysłaliśmy kod do %1$s. Wprowadź go poniżej, aby potwierdzić, że to Ty.</string>
+    <string name="login_msisdn_confirm_hint">Wprowadź kod</string>
+    <string name="login_msisdn_confirm_send_again">Wyślij ponownie</string>
+    <string name="login_msisdn_confirm_submit">Dalej</string>
+
+    <string name="login_msisdn_error_not_international">Międzynarodowe numery telefonów muszą zaczynać się od \'+\'</string>
+    <string name="login_msisdn_error_other">Numer telefonu wydaje się być nieprawidłowy. Sprawdź</string>
+
+    <string name="login_signup_to">Zaloguj się do %1$s</string>
+    <string name="login_signin_username_hint">Nazwa użytkownika lub e-mail</string>
+    <string name="login_signup_username_hint">Nazwa użytkownika</string>
+    <string name="login_signup_password_hint">Hasło</string>
+    <string name="login_signup_submit">Dalej</string>
+    <string name="login_signup_error_user_in_use">Nazwa użytkownika zajęta</string>
+    <string name="login_signup_cancel_confirmation_title">Ostrzeżenie</string>
+    <string name="login_signup_cancel_confirmation_content">Twoje konto wciąż nie zostalo utworzone.
+\n
+\nZatrzymać proces rejestracji\?</string>
+
+    <string name="login_a11y_choose_matrix_org">Wybierz matrix.org</string>
+    <string name="login_a11y_choose_modular">Wybierz modular</string>
+    <string name="login_a11y_choose_other">Wybierz niestandardowy serwer domowy</string>
+    <string name="login_a11y_captcha_container">Wypełnij zadanie Captcha</string>
+    <string name="login_terms_title">Zaakceptuj warunki aby kontynuować</string>
+
+    <string name="login_wait_for_email_title">Sprawdź swój e-mail</string>
+    <string name="login_wait_for_email_notice">Wysłaliśmy e-mail do %1$s.
+\nProszę nacisnąć na link który zawiera aby kontynuować tworzenie konta.</string>
+    <string name="login_validation_code_is_not_correct">Wprowadzony kod jest nieprawidłowy. Sprawdź.</string>
+    <string name="login_error_outdated_homeserver_title">Nieaktualny serwer domowy</string>
+    <string name="login_error_outdated_homeserver_content">Ten serwer domowy pracuje pod kontrolą zbyt starej wersji, aby się z nim połączyć. Zapytaj administratora serwera domowego o aktualizację.</string>
+
+    <plurals name="login_error_limit_exceeded_retry_after">
+        <item quantity="one">Zostało wysłane zbyt wiele żądań. Możesz spróbować ponownie za %1$d sekundę…</item>
+        <item quantity="few">Zostało wysłane zbyt wiele żądań. Możesz spróbować ponownie za %1$d sekundy…</item>
+        <item quantity="many" />
+    </plurals>
+
+    <string name="signed_out_title">Wylogowałeś(-łaś) się</string>
+    <string name="signed_out_notice">Mogło to się stać z wielu powodów:
+\n
+\n• Zmieniłeś(-łaś) swoje hasło na innej sesji.
+\n
+\n• Usunęłaś swoją sesję z innej sesji.
+\n
+\n• Administrator Twojego serwera unieważnił dostęp ze względów bezpieczeństwa.</string>
+    <string name="signed_out_submit">Zaloguj ponownie</string>
+
+    <string name="soft_logout_title">Wylogowałeś(-łaś) się</string>
+    <string name="soft_logout_signin_title">Zaloguj się</string>
+    <string name="soft_logout_signin_notice">Administaror twojego serwera domowego (%1$s) wylogował cię z konta %2$s (%3$s).</string>
+    <string name="soft_logout_signin_e2e_warning_notice">Zaloguj się aby odzyskać klucze szyfrowania przechowywane wyłącznie na tym urządzeniu. Będziesz ich potrzebował aby odczytać zaszyfrowane wiadomości na każdym z urządzeń.</string>
+    <string name="soft_logout_signin_submit">Zaloguj się</string>
+    <string name="soft_logout_signin_password_hint">Hasło</string>
+    <string name="soft_logout_clear_data_title">Wyczyść dane osobowe</string>
+    <string name="soft_logout_clear_data_notice">Ostrzeżenie: Twoje dane osobowe (włączając w to klucze szyfrujące) są wciąż przechowywane na tym urządzeniu.
+\n
+\nWyczyść je, jeżeli skończyłeś(-łaś) używać tego urządzenia, lub chcesz zalogować się na inne konto.</string>
+    <string name="soft_logout_clear_data_submit">Wyczyść wszystkie dane</string>
+
+    <string name="soft_logout_clear_data_dialog_title">Wyczyść dane</string>
+    <string name="soft_logout_clear_data_dialog_content">Wyczyścić wszystkie dane przechowywane na tym urządzeniu\?
+\nZaloguj się ponownie aby uzyskać dostęp do danych konta i wiadomości.</string>
+    <string name="soft_logout_clear_data_dialog_e2e_warning_content">Utracisz dostęp do zaszyfrowanych wiadomości do czasu, aż zalogujesz się aby odzyskać Twoje klucze szyfrujące.</string>
+    <string name="soft_logout_clear_data_dialog_submit">Wyczyść dane</string>
+    <string name="soft_logout_sso_not_same_user_error">Aktualna sesja jest dla użytkownika %1$s, podajesz natomiast dane dla użytkownika %2$s. Nie jest to wspierane przez RiotX.
+\nNa początku usuń dane, następnie zaloguj ponownie na innym koncie.</string>
+
+    <string name="permalink_malformed">Link matrix.to został zdeformowany</string>
+    <string name="bug_report_error_too_short">Opis zbyt krótki</string>
+
+    <string name="notification_initial_sync">Synchronizacja wstępna…</string>
+
+    <string name="settings_show_devices_list">Zobacz wszystkie sesje</string>
+    <string name="settings_rageshake">Wściekłe potrząśnięcie</string>
+    <string name="settings_rageshake_detection_threshold">Próg detekcji</string>
+    <string name="settings_rageshake_detection_threshold_summary">Potrząśnij telefonem aby wypróbować próg detekcji</string>
+    <string name="rageshake_detected">Potrząśnięcie wykryte!</string>
+    <string name="devices_current_device">Aktualna sesja</string>
+    <string name="devices_other_devices">Inne sesje</string>
+
+    <string name="autocomplete_limited_results">Wyświetlanie jedynie początkowych wyników, wprowadź więcej znaków…</string>
+
+    <string name="settings_developer_mode_fail_fast_title">Bezproblemowy</string>
+    <string name="settings_developer_mode_fail_fast_summary">RiotX może zawieszać się częściej gdy napotka na niespodziewany błąd</string>
+
+    <string name="command_description_verify">Żądanie weryfikujące podany userID</string>
+    <string name="command_description_shrug">Preparuje ¯\\_(ツ)_/¯ dla zwykłej wiadomości tekstowej</string>
+
+    <string name="create_room_encryption_title">Aktywuj szyfrowanie</string>
+    <string name="create_room_encryption_description">Odkąd zostanie włączone, szyfrowanie nie może zostać wyłączone.</string>
+
+    <string name="login_error_threepid_denied">Twoja domena adresu e-mail nie została dopuszczona do rejestracji na tym serwerze</string>
+
+    <string name="verification_conclusion_warning">Niezaufane logowanie</string>
+    <string name="verification_sas_match">Zgadzają się</string>
+    <string name="verification_sas_do_not_match">Nie zgadzają się</string>
+    <string name="verify_user_sas_emoji_help_text">Zweryfikuj użytkownika poprzez potwierdzenie unikalnego ciągu emoji, w tym samym porządku na jego ekranie.</string>
+    <string name="verify_user_sas_emoji_security_tip">Dla najlepszego bezpieczeństwa, użyj innych zaufanych form komunikacji lub zrób to osobiście.</string>
+    <string name="verification_green_shield">Patrz na zieloną tarczę, aby upewnić się czy użytkownik jest zaufany. Zaufaj wszystkim użytkownikom w pokoju, aby upewnić się, że pokój jest bezpieczny.</string>
+
+    <string name="verification_conclusion_not_secure">Nie jest bezpieczny</string>
+    <string name="verification_conclusion_compromised">Jeden z poniższych mogł zostać narażony:
+\n
+\n- Serwer domowy
+\n- Serwer domowy użytkownika, z którym jest on połączony
+\n- Połączenie z Internetem Twoje lub innych użytkowników
+\n- Urządzenie Twoje lub innych użytkowników</string>
+
+    <string name="sent_a_video">Wideo.</string>
+    <string name="sent_an_image">Zdjęcie.</string>
+    <string name="sent_an_audio_file">Dźwięk</string>
+    <string name="sent_a_file">Plik</string>
+
+    <string name="verification_request_waiting">Oczekiwanie…</string>
+    <string name="verification_request_other_cancelled">%s anulowana</string>
+    <string name="verification_request_you_cancelled">Anulowałeś(-łaś)</string>
+    <string name="verification_request_other_accepted">%s zaakceptowana</string>
+    <string name="verification_request_you_accepted">Zaakceptowałeś(-łaś)</string>
+    <string name="verification_sent">Żądanie weryfikacji wysłane</string>
+    <string name="verification_request">Żądanie weryfikacji</string>
+
+
+    <string name="verification_verify_device">Zweryfikuj tą sesję</string>
+    <string name="verification_verify_device_manually">Zweryfikuj ręcznie</string>
+
+    <string name="you">Ty</string>
+
+    <string name="verification_scan_notice">Zeskanuj kod z urządzenia innego użytkownika aby bezpiecznie zweryfikować siebie nawzajem</string>
+    <string name="verification_scan_their_code">Zeskanuj ich kod</string>
+    <string name="verification_scan_emoji_title">Nie można zeskanować</string>
+    <string name="verification_scan_emoji_subtitle">Jeżeli nie jesteś z tą osobą, zamiast tego porównaj emoji</string>
+
+    <string name="verification_no_scan_emoji_title">Zweryfikuj porównując emoji</string>
+
+    <string name="verify_by_emoji_title">Zweryfikuj za pomocą Emoji</string>
+    <string name="verify_by_emoji_description">Jeżeli nie możesz zeskanować kodu powyżej, zweryfikuj porównując krótki, unikalny ciąg emoji.</string>
+
+    <string name="a13n_qr_code_description">Obraz kodu QR</string>
+
+    <string name="verification_verify_user">Zweryfikuj %s</string>
+    <string name="verification_verified_user">Zweryfikowano %s</string>
+    <string name="verification_request_waiting_for">Oczekiwanie na %s…</string>
+    <string name="verification_request_alert_description">Dla wyższego poziomu bezpieczeństwa, zweryfikuj %s poprzez sprawdzenie jednorazowego kodu na obu urządzeniach.
+\n
+\nDla najwyższego bezpieczeństwa, zrób to osobiście.</string>
+    <string name="room_profile_encrypted_subtitle">Wiadomości w tym pokoju są zaszyfrowane end-to-end.
+\n
+\nTwoje wiadomości są zabezpieczone zamkami i jedynie Ty oraz Twój odbiorca posiadacie klucze, aby je odblokować.</string>
+    <string name="room_profile_section_security_learn_more">Dowiedz się więcej</string>
+    <plurals name="room_profile_section_more_member_list">
+        <item quantity="one">Jedna osoba</item>
+        <item quantity="few">%1$d osób</item>
+        <item quantity="many" />
+    </plurals>
+    <string name="room_profile_leaving_room">Opuszczanie pokoju…</string>
+
+    <string name="room_member_power_level_admins">Administratorzy</string>
+    <string name="room_member_power_level_moderators">Moderatorzy</string>
+    <string name="room_member_power_level_custom">Niestandardowy</string>
+    <string name="room_member_power_level_invites">Zaproszenia</string>
+    <string name="room_member_power_level_users">Użytkownicy</string>
+
+    <string name="room_member_power_level_admin_in">Administrator w %1$s</string>
+    <string name="room_member_power_level_moderator_in">Moderator w %1$s</string>
+    <string name="room_member_power_level_custom_in">Niestandardowy (%1$d) w %2$s</string>
+
+    <string name="room_member_jump_to_read_receipt">Przeskocz do znacznika odczytania</string>
+
+    <string name="rendering_event_error_type_of_event_not_handled">RiotX nie obsługuje wydarzeń typu \'%1$s\'</string>
+    <string name="rendering_event_error_type_of_message_not_handled">RiotX nie obsługuje wiadomości typu \'%1$s\'</string>
+    <string name="rendering_event_error_exception">RiotX napotkał problem przy wyświetlaniu zawartości wydarzenia z ID \'%1$s\'</string>
+
+    <string name="unignore">Nie ignoruj</string>
+
+    <string name="verify_cannot_cross_sign">Sesja nie jest w stanie podzielić się weryfikacją z innymi sesjami.
+\nWeryfikacja zostanie zapisana lokalnie i udostępniona w przyszłych wersjach aplikacji.</string>
+
+    <string name="room_list_sharing_header_recent_rooms">Ostatnie pokoje</string>
+    <string name="room_list_sharing_header_other_rooms">Inne pokoje</string>
+
+    <string name="command_description_rainbow">Wysyła wiadomość w odcieniach tęczy</string>
+    <string name="command_description_rainbow_emote">Wysyła emoji w odcieniach tęczy</string>
+
+    <string name="settings_category_timeline">Oś czasu</string>
+
+    <string name="settings_category_composer">Edycja wiadomości</string>
+
+    <string name="room_settings_enable_encryption_warning">Odkąd zostanie włączone, szyfrowanie nie może zostać wyłączone.</string>
+
+    <string name="room_settings_enable_encryption_dialog_title">Aktywować szyfrowanie\?</string>
+    <string name="room_settings_enable_encryption_dialog_content">Odkąd zostanie włączone, szyfrowanie w pokoju nie może zostać wyłączone. Wiadomości wysłane w zaszyfrowanym pokoju nie są widzane przez serwer, a jedynie przez uczestników w pokoju.
+\nAktywowanie szyfrowania może uniemożliwić wielu botom i mostom prawidłowe działanie.</string>
+    <string name="room_settings_enable_encryption_dialog_submit">Aktywuj szyfrowanie</string>
+
+    <string name="verification_request_notice">Aby być bezpiecznym, zweryfikuj %s poprzez sprawdzenie jednorazowego kodu.</string>
+    <string name="verification_request_start_notice">Aby być bezpiecznym, zrób to osobiście lub użyj innej metody komunikacji.</string>
+
+    <string name="verification_emoji_notice">Porównaj unikalny ciąg emoji, upewniając się, że pojawiają się w identycznym porządku.</string>
+    <string name="verification_code_notice">Porównaj kod wyświetlany na ekranie innego użytkownika.</string>
+    <string name="verification_conclusion_ok_notice">Wiadomości z użytkownikiem są szyfrowane end-to-end i nie mogą zostać odczytane przez osoby trzecie.</string>
+    <string name="verification_conclusion_ok_self_notice">Nowa sesja została zweryfikowana. Posiadasz dostęp do zaszyfrowanych wiadomości, a inni użytkownicy będą ją widzieć jako zaufaną.</string>
+
+
+    <string name="encryption_information_cross_signing_state">Podpis krzyżowy</string>
+    <string name="encryption_information_dg_xsigning_complete">Podpis krzyżowy jest aktywowany.
+\nKlucze Prywatne znajdują się na urządzeniu.</string>
+    <string name="encryption_information_dg_xsigning_trusted">Podpis krzyżowy aktywowany.
+\nKlucze są zaufane.
+\nKlucze prywatne nie są znane</string>
+    <string name="encryption_information_dg_xsigning_not_trusted">Podpis krzyżowy jest aktywowany.
+\nKlucze nie są zaufane</string>
+    <string name="encryption_information_dg_xsigning_disabled">Podpis krzyżowy nie jest aktywowany</string>
+
+
+    <string name="settings_active_sessions_list">Aktywne Sesje</string>
+    <string name="settings_active_sessions_show_all">Pokaż wszystkie Sesje</string>
+    <string name="settings_active_sessions_manage">Zarządzaj Sesjami</string>
+    <string name="settings_active_sessions_signout_device">Wyloguj z tej sesji</string>
+
+    <string name="settings_failed_to_get_crypto_device_info">Brak dostępnej informacji o kryptografii</string>
+
+    <string name="settings_active_sessions_verified_device_desc">Ta sesja jest zaufana dla bezpiecznej wymiany wiadomości, ponieważ ją zweryfikowałeś(-łaś):</string>
+    <string name="settings_active_sessions_unverified_device_desc">Zweryfikuj tą sesję aby oznaczyć ją jako zaufaną i przyznać jej dostęp do zaszyfrowanych wiadomości. Jeżeli nie logowałeś(-łaś) się do tej sesji, twoje konto mogło zostać naruszone:</string>
+
+    <plurals name="settings_active_sessions_count">
+        <item quantity="one">%d aktywna sesja</item>
+        <item quantity="few">%d aktywnych sesji</item>
+        <item quantity="many" />
+    </plurals>
+
+    <string name="crosssigning_verify_this_session">Zweryfikuj tą sesję</string>
+    <string name="crosssigning_other_user_not_trust">Inni użytkownicy mogą jemu nie ufać</string>
+    <string name="complete_security">Całkowite Bezpieczeństwo</string>
+
+    <string name="verification_open_other_to_verify">Otwórz obecną sesję i użyj jej do zweryfikowania obecnej, przyznając jej dostęp do zaszyfrowanych wiadomości.</string>
+
+
+    <string name="verification_profile_verify">Zweryfkuj</string>
+    <string name="verification_profile_verified">Zweryfikowano</string>
+    <string name="verification_profile_warning">Ostrzeżenie</string>
+
+    <string name="room_member_profile_failed_to_get_devices">Uzyskanie sesji nie powiodło się</string>
+    <string name="room_member_profile_sessions_section_title">Sesje</string>
+    <string name="trusted">Zaufany</string>
+    <string name="not_trusted">Niezaufany</string>
+
+    <string name="verification_profile_device_verified_because">Sesja jest zaufana dla bezpiecznej wymiany wiadomości ponieważ %1$s (%2$s) zweryfikował(-a) ją:</string>
+    <string name="verification_profile_device_new_signing">%1$s (%2$s) zalogował(-a) się używając nowej sesji:</string>
+    <string name="verification_profile_device_untrust_info">Dopóki użytkownik ufa tej sesji, wiadomości wysłane do oraz od niej będą oznaczone ostrzeżeniami. Ewentualnie, możesz zweryfikować je ręcznie.</string>
+
+
+    <string name="initialize_cross_signing">Inicjalizacja podpisu krzyżowego</string>
+    <string name="reset_cross_signing">Zresetuj Klucze</string>
+
+    <string name="a11y_qr_code_for_verification">Kod QR</string>
+
+    <string name="qr_code_scanned_by_other_yes">Tak</string>
+    <string name="qr_code_scanned_by_other_no">Nie</string>
+
+    <string name="settings_dev_tools">Narzędzia programistyczne</string>
+    <string name="settings_account_data">Dane konta</string>
+    <plurals name="poll_info">
+        <item quantity="one">%d głos</item>
+        <item quantity="few">%d głosów</item>
+        <item quantity="many" />
+    </plurals>
+    <plurals name="poll_info_final">
+        <item quantity="one">%d głos - wyniki końcowe</item>
+        <item quantity="few">%d głosów - wyniki końcowe</item>
+        <item quantity="many" />
+    </plurals>
+    <string name="poll_item_selected_aria">Wybrana Opcja</string>
+    <string name="command_description_poll">Tworzy prostą ankietę</string>
+    <string name="verification_cannot_access_other_session">Nie masz dostępu do instniejącej sesji\?</string>
+    <string name="verification_use_passphrase">Użyj klucza odzyskiwania lub hasła</string>
+
+    <string name="new_signin">Nowa rejestracja</string>
+
+    <string name="enter_secret_storage_invalid">Nie można odnaleźć tajemnej przestrzeni w pamięci</string>
+    <string name="enter_secret_storage_passphrase">Wprowadź hasło tajemnej przestrzeni</string>
+    <string name="enter_secret_storage_passphrase_warning">Ostrzeżenie:</string>
+    <string name="enter_secret_storage_passphrase_warning_text">Powinieneś(-nnaś) uzyskać dostęp do tajnej przestrzeni jedynie z zaufanego urządzenia</string>
+
+    <string name="message_action_item_redact">Usuń…</string>
+    <string name="share_confirm_room">Czy chcesz wysłać załącznik do %1$s\?</string>
+    <plurals name="send_images_with_original_size">
+        <item quantity="one">Wyślij obraz w oryginalnym rozmiarze</item>
+        <item quantity="few">Wyślij obrazy w oryginalnym rozmiarze</item>
+        <item quantity="many" />
+    </plurals>
+
+    <string name="delete_event_dialog_title">Potwierdź Usunięcie</string>
+    <string name="delete_event_dialog_content">Jesteś pewny(-na), że chcesz usunąć to wydarzenie\? Jeżeli usuniesz nazwę pokoju lub zmienisz temat, wciąż będzie możliwe cofnięcie zmiany.</string>
+    <string name="delete_event_dialog_reason_checkbox">Podaj przyczynę</string>
+    <string name="delete_event_dialog_reason_hint">Przyczyna reakcji</string>
+
+    <string name="event_redacted_by_user_reason_with_reason">Wydarzenie usunięte przez użytkownika, przyczyna: %1$s</string>
+    <string name="event_redacted_by_admin_reason_with_reason">Wydarzenie moderowane przez administratora pokoju, przyczyna: %1$s</string>
+
+    <string name="keys_backup_restore_success_title_already_up_to_date">Klucze są już aktualne!</string>
+
+    <string name="review">Sprawdź</string>
+    <string name="decline">Zrezygnuj</string>
+
+    <string name="sas_error_m_key_mismatch">Niezgodność klucza</string>
+    <string name="sas_error_m_user_error">Niezgodność użytkowników</string>
+    <string name="identity_server_not_defined">Nie używasz Serwera Tożsamości</string>
+    <string name="identity_server_not_defined_for_password_reset">Nie skonfigurowano serwera toższamości, który jest wymagany do resetowania hasła.</string>
+
+    <string name="error_user_already_logged_in">Wygląda na to, że próbujesz podłączyć się do innego serwera domowego. Czy chcesz się wylogować\?</string>
+
+    <string name="send_you_invite">Przysyła zaproszenie</string>
+    <string name="invited_by">Zaproszono przez %s</string>
+
+    <string name="room_list_catchup_empty_body">Nie masz więcej nieprzeczytanych wiadomości</string>
+    <string name="room_list_catchup_welcome_title">Witaj w domu!</string>
+    <string name="title_activity_emoji_reaction_picker">Reakcje</string>
+    <string name="reactions_agree">Zgoda</string>
+    <string name="reactions_like">Lubię to</string>
+    <string name="message_view_reaction">Zobacz Reakcje</string>
+    <string name="event_redacted_by_user_reason">Zdarzenie usunięte przez użytkownika</string>
+    <string name="event_redacted_by_admin_reason">Zdarzenie moderowane przez administratora pokoju</string>
+    <string name="create_room_directory_title">Katalog Pokoi</string>
+    <string name="quick_reactions">Szybkie Reakcje</string>
+
+    <string name="settings_general_title">Ogólne</string>
+    <string name="settings_push_rules">Zasady push</string>
+    <string name="settings_push_gateway_no_pushers">Brak zarejestrowanych bramek push</string>
+
+    <string name="send_file_step_encrypting_thumbnail">Szyfrowanie miniatury…</string>
+    <string name="room_filtering_footer_title">Nie możesz czegoś odnaleźć\?</string>
+    <string name="room_filtering_footer_create_new_room">Utwórz nowy pokój</string>
+    <string name="room_filtering_footer_open_room_directory">Otwórz katalog pokoi</string>
+
+    <string name="room_directory_search_hint">Nazwa lub ID (#przykład:matrix.org)</string>
+
+    <string name="identity_server">Serwer toższamości</string>
+    <string name="disconnect_identity_server">Odłącz od serwera tożsamości</string>
+    <string name="add_identity_server">Skonfiguruj serwer tożsamości</string>
+    <string name="change_identity_server">Zmień serwer tożsamości</string>
+    <string name="attachment_type_camera">Aparat</string>
+    <string name="no_network_indicator">Obecnie nie ma połączenia z siecią</string>
+
+    <string name="message_ignore_user">Zablokuj użytkownika</string>
+
+    <string name="send_suggestion">Złóż sugestię</string>
+    <string name="settings_developer_mode_summary">Tryb programisty aktywuje ukryte funkcje i może również spowodować, że aplikacja będzie mniej stabilna. Tylko dla programistów!</string>
+    <string name="room_profile_not_encrypted_subtitle">Wiadomości w tym pokoju nie są szyfrowane end-to-end.</string>
+    <string name="room_profile_section_more_uploads">Przesłane pliki</string>
 </resources>
diff --git a/vector/src/main/res/values-pt/strings.xml b/vector/src/main/res/values-pt/strings.xml
index 3508d1fd9b..56417b9a36 100755
--- a/vector/src/main/res/values-pt/strings.xml
+++ b/vector/src/main/res/values-pt/strings.xml
@@ -1065,17 +1065,17 @@ A visibilidade das mensagens no Matrix é parecida com a dos emails. O nosso esq
 
     <string name="title_activity_keys_backup_setup">backup de chaves</string>
     <string name="keys_backup_is_not_finished_please_wait">Backup de chaves, imcompleto. Por favor, Aguarde.</string>
-    <string name="sign_out_bottom_sheet_warning_backing_up">Backup de chaves, em progresso. Caso pagina seja fechada, irá perder acesso as suas mensagens encriptadas.</string>
+    <string name="sign_out_bottom_sheet_warning_backing_up">Backup de chaves, em progresso. Caso página seja fechada, irá perder acesso as suas mensagens encriptadas.</string>
     <string name="sign_out_bottom_sheet_backing_up_keys">Backup de chaves, em progresso …</string>
     <string name="keys_backup_activate">Utilize Backup de chaves.</string>
     <string name="are_you_sure">Tem a certeza?</string>
     <string name="backup">Fazer Backup</string>
-    <string name="sign_out_bottom_sheet_will_lose_secure_messages">Irá perder acesso as suas mensagens encriptadas, se não fizer backup de suas chaves, antes de abandonar esta pagina.</string>
+    <string name="sign_out_bottom_sheet_will_lose_secure_messages">Irá perder acesso as suas mensagens encriptadas, se não fizer backup de suas chaves, antes de abandonar esta página.</string>
 
     <string name="stay">Ficar</string>
     <string name="title_activity_keys_backup_restore">Utilize Backup de chaves</string>
 
-    <string name="sign_out_bottom_sheet_warning_no_backup">Se sair desta pagina, irá perder as suas mensagens encriptadas</string>
+    <string name="sign_out_bottom_sheet_warning_no_backup">Se sair desta página, irá perder as suas mensagens encriptadas</string>
     <string name="sign_out_bottom_sheet_dont_want_secure_messages">Não quero as minhas mensagens encriptadas</string>
     <string name="keys_backup_banner_in_progress">Backup de chaves, em progresso …</string>
 
@@ -1120,7 +1120,7 @@ A visibilidade das mensagens no Matrix é parecida com a dos emails. O nosso esq
     <string name="reason_hint">Razão</string>
 
     <string name="settings_notification_advanced">Configurações avançadas para notificações</string>
-    <string name="settings_notification_by_event">Importancia de notificações por evento</string>
+    <string name="settings_notification_by_event">Importância de notificações por evento</string>
 
     <string name="settings_notification_troubleshoot">Diagnóstico de Notificações</string>
     <string name="settings_troubleshoot_diagnostic">Diagnóstico de falhas</string>
diff --git a/vector/src/main/res/values-ru/strings.xml b/vector/src/main/res/values-ru/strings.xml
index 9fbcc509be..014a8ae65c 100644
--- a/vector/src/main/res/values-ru/strings.xml
+++ b/vector/src/main/res/values-ru/strings.xml
@@ -128,7 +128,7 @@
     <string name="start_voice_call">Начать голосовой вызов</string>
     <string name="start_video_call">Начать видеовызов</string>
 
-    <string name="option_send_files">Отправка файлов</string>
+    <string name="option_send_files">Отправить файлы</string>
     <string name="option_take_photo_video">Камера</string>
 
     <!-- Authentication -->
@@ -632,7 +632,7 @@
     <string name="encryption_never_send_to_unverified_devices_title">Шифровать только для проверенных сессий</string>
     <string name="encryption_never_send_to_unverified_devices_summary">Не отправлять зашифрованные сообщения непроверенным сессиям с этой сессии.</string>
 
-    <string name="encryption_information_not_verified">НЕ проверено</string>
+    <string name="encryption_information_not_verified">Не проверено</string>
     <string name="encryption_information_verified">Проверено</string>
     <string name="encryption_information_blocked">В черном списке</string>
 
@@ -957,7 +957,7 @@
     <string name="download">Скачать</string>
     <string name="speak">Говорить</string>
     <string name="clear">Очистить</string>
-    <string name="e2e_re_request_encryption_key"><u>Повторно запросить ключи шифрования</u> с других ваших сессий.</string>
+    <string name="e2e_re_request_encryption_key">Перезапросить ключи шифрования у других ваших сессий.</string>
 
     <string name="e2e_re_request_encryption_key_sent">Отправлен запрос ключа.</string>
 
@@ -1007,21 +1007,19 @@
 
     <string name="missing_permissions_error">Из-за отсутствия разрешений это действие невозможно.</string>
     <plurals name="format_time_s">
-        <item quantity="one">%d сек.</item>
-        <item quantity="few">%d сек.</item>
-        <item quantity="many">%d сек.</item>
+        <item quantity="one">%d секунда</item>
+        <item quantity="few">%d секунды</item>
+        <item quantity="many">%d секунд</item>
     </plurals>
     <plurals name="format_time_m">
-        <item quantity="one">%dm</item>
-        <item quantity="few">%dm</item>
-        <item quantity="many">%dm</item>
-        <item quantity="other" />
+        <item quantity="one">%d минута</item>
+        <item quantity="few">%d минуты</item>
+        <item quantity="many">%d минут</item>
     </plurals>
     <plurals name="format_time_h">
-        <item quantity="one">%dh</item>
-        <item quantity="few">%dh</item>
-        <item quantity="many">%dh</item>
-        <item quantity="other" />
+        <item quantity="one">%d час</item>
+        <item quantity="few">%d часа</item>
+        <item quantity="many">%d часов</item>
     </plurals>
     <plurals name="format_time_d">
         <item quantity="one">%d день</item>
@@ -1136,7 +1134,7 @@
     <string name="settings_troubleshoot_diagnostic">Результаты диагностики</string>
     <string name="settings_troubleshoot_diagnostic_run_button_title">Запустить тесты</string>
     <string name="settings_troubleshoot_diagnostic_running_status">Выполняется… (%1$d из %2$d)</string>
-    <string name="settings_troubleshoot_diagnostic_success_status">В основном всё в порядке. Если вы по-прежнему не получаете уведомления, пожалуйста, отправьте отчет об ошибке, чтобы помочь нам исследовать проблему.</string>
+    <string name="settings_troubleshoot_diagnostic_success_status">В основном, всё в порядке. Если вы по-прежнему не получаете уведомления, пожалуйста, отправьте отчет об ошибке, чтобы помочь нам разобраться.</string>
     <string name="settings_troubleshoot_diagnostic_failure_status_with_quickfix">Один или несколько тестов не пройдены, попробуйте предлагаемые решения.</string>
     <string name="settings_troubleshoot_diagnostic_failure_status_no_quickfix">Один или несколько тестов не пройдены, пожалуйста, отправьте отчет об ошибке, чтобы помочь нам исследовать проблему.</string>
 
@@ -1297,17 +1295,17 @@
     <string name="keys_backup_settings_delete_backup_error">Не удалось удалить резервную копию (%s)</string>
 
     <string name="keys_backup_settings_deleting_backup">Удаление резервной копии…</string>
-    <string name="keys_backup_settings_untrusted_backup">Для Безопасного Восстановления Сообщений на этом устройстве, требуется пароль или ключ восстановления.</string>
-    <string name="keys_backup_settings_invalid_signature_from_verified_device">Резервная копия имеет невалидную подпись верифицированного устройства %s</string>
-    <string name="keys_backup_settings_valid_signature_from_unverified_device">Резервная копия имеет валидную подпись неверифицированного устройства %s</string>
-    <string name="keys_backup_settings_valid_signature_from_verified_device">Резервная копия имеет валидную подпись верифицированного устройства %s.</string>
-    <string name="keys_backup_settings_valid_signature_from_this_device">Резервная копия имеет валидную подпись этого устройства.</string>
-    <string name="keys_backup_settings_signature_from_unknown_device">Резервная копия подписана устройством с идентификатором: %s.</string>
-    <string name="keys_backup_settings_status_not_setup">Ваши ключи не сохраняются с этого устройства.</string>
+    <string name="keys_backup_settings_untrusted_backup">Для Восстановления Сообщений в этой сессии, требуется пароль или ключ восстановления.</string>
+    <string name="keys_backup_settings_invalid_signature_from_verified_device">Резервная копия имеет недействительную подпись из подтвержденной сессии %s</string>
+    <string name="keys_backup_settings_valid_signature_from_unverified_device">"Резервная копия имеет  действительную подпись из неподтвержденной сессии %s"</string>
+    <string name="keys_backup_settings_valid_signature_from_verified_device">Резервная копия имеет действительно подпись из подтверждённой сессии %s.</string>
+    <string name="keys_backup_settings_valid_signature_from_this_device">Резервная копия имеет действительную подпись с этой сессии.</string>
+    <string name="keys_backup_settings_signature_from_unknown_device">Резервная копия подписана сессией с идентификатором %s.</string>
+    <string name="keys_backup_settings_status_not_setup">Резервные копии ключей этой сессии не сохраняются.</string>
 
 
-    <string name="keys_backup_settings_status_ko">Резервное копирование ключей не активно на этом устройстве.</string>
-    <string name="keys_backup_settings_status_ok">Резервное копирование ключей успешно настроено для этого устройства.</string>
+    <string name="keys_backup_settings_status_ko">Резервное копирование ключей не активировано в этой сессии.</string>
+    <string name="keys_backup_settings_status_ok">Резервное копирование ключей успешно настроено для этой сессии.</string>
     <string name="keys_backup_settings_delete_backup_button">Удалить резервную копию</string>
 
     <string name="keys_backup_settings_restore_backup_button">Восстановить из резервной копии</string>
@@ -1335,7 +1333,7 @@
     <string name="keys_backup_restore_success_title">Резервная копия восстановлена %s !</string>
     <string name="keys_backup_get_trust_error">Ошибка получения информации о доверии для резервной копии (%s).</string>
 
-    <string name="keys_backup_settings_invalid_signature_from_unverified_device">Резервная копия имеет невалиндую подпись неверифицированного устройства %s</string>
+    <string name="keys_backup_settings_invalid_signature_from_unverified_device">Резервная копия имеет недействительную подпись из неподтвержденной сессии %s</string>
     <string name="keys_backup_get_version_error">Не удалось получить последнюю версию ключей восстановления (%s).</string>
     <plurals name="keys_backup_restore_success_description_part2">
         <item quantity="one">%d новый ключ был добавлен к этому устройству.</item>
@@ -1349,7 +1347,7 @@
         <item quantity="few">Восстановлены резервные копии с %d ключами.</item>
         <item quantity="many">Восстановлены резервные копии с %d ключами.</item>
     </plurals>
-    <string name="keys_backup_restore_success_description">Восстановлены %1$d сеансовые ключи и добавлены %2$d новые ключи, которые не были известны этому устройству</string>
+    <string name="keys_backup_restore_success_description">Восстановлены %1$d сессионные ключи и добавлены %2$d новые ключи, которые не были известны этой сессии</string>
     <string name="keys_backup_recovery_code_error_decrypt">Невозможно расшифровать резервную копию с помощью этого ключа восстановления: убедитесь, что вы ввели правильный ключ.</string>
 
     <string name="keys_backup_passphrase_error_decrypt">Невозможно расшифровать резервную копию с помощью этой парольной фразы: убедитесь, что вы ввели верную фразу.</string>
@@ -1452,12 +1450,12 @@
     <plurals name="notification_compat_summary_line_for_room">
         <item quantity="one">%1$s: 1 сообщение</item>
         <item quantity="few">%1$s: %2$d сообщения</item>
-        <item quantity="many">%1$s: %2$d сообщения</item>
+        <item quantity="many">%1$s: %2$d сообщений</item>
     </plurals>
     <plurals name="notification_compat_summary_title">
         <item quantity="one">%d оповещение</item>
         <item quantity="few">%d оповещения</item>
-        <item quantity="many">%d оповещения</item>
+        <item quantity="many">%d оповещений</item>
     </plurals>
 
     <string name="notification_unknown_new_event">Новое событие</string>
@@ -1484,10 +1482,10 @@
 \nИмя сессии: %1$s 
 \nПоследний раз в сети: %2$s 
 \nЕсли вы не вошли с другой сессии, проигнорируйте этот запрос.</string>
-    <string name="your_unverified_device_requesting_with_info">Непроверенное устройство запрашивает ключи шифрования.
-\nИмя устройства: %1$s
-\nПоследний раз в сети: %2$s
-\nЕсли вы не вошли с другого устройства, проигнорируйте этот запрос.</string>
+    <string name="your_unverified_device_requesting_with_info">Непроверенная сессия запрашивает ключи шифрования. 
+\nИмя сессии: %1$s 
+\nПоследний раз в сети: %2$s 
+\nЕсли вы не открывали новую сессию - проигнорируйте этот запрос.</string>
 
     <string name="start_verification_short_label">Подтвердить</string>
     <string name="share_without_verifying_short_label">Поделиться</string>
@@ -1502,18 +1500,18 @@
     <string name="sas_security_advise">Для обеспечения максимальной безопасности мы рекомендуем делать это лично или использовать другие надежные средства связи.</string>
     <string name="sas_verify_start_button_title">Начать проверку</string>
     <string name="sas_incoming_request_title">Входящий запрос о проверке</string>
-    <string name="sas_incoming_request_description">Проверьте это устройство, чтобы отметить его как доверенное. Доверенные устройства партнеров дают вам дополнительное спокойствие при использовании сквозного шифрования сообщений.</string>
-    <string name="sas_incoming_request_description_2">Убедитесь, что данное устройство является доверенным, а также проверьте, что оно доверено вашему партнеру.</string>
+    <string name="sas_incoming_request_description">Проверьте эту сессию, чтобы отметить её как доверенную. Доверие сессиям партнеров позволяет быть уверенным в надёжности сквозного шифрования сообщений.</string>
+    <string name="sas_incoming_request_description_2">Потдверждение этой сессии пометит её доверенной для вас и вашего партнёра.</string>
 
-    <string name="sas_emoji_description">Проверьте это устройство, убедившись, что следующие смайлики появляются на экране партнера</string>
-    <string name="sas_decimal_description">Проверьте это устройство, убедившись, что следующие цифры появляются на экране партнера</string>
+    <string name="sas_emoji_description">Подтвердите эту сессию, убедившись, что следующие смайлики появляются на экране партнера</string>
+    <string name="sas_decimal_description">Подтвердите эту сессию, убедившись, что следующие цифры появляются на экране партнера</string>
 
     <string name="sas_incoming_verification_request_dialog">Вы получили входящий запрос на подтверждение.</string>
     <string name="sas_view_request_action">Посмотреть запрос</string>
     <string name="sas_waiting_for_partner">В ожидании партнера, чтобы подтвердить …</string>
 
     <string name="sas_verified">Проверено!</string>
-    <string name="sas_verified_successful">Вы успешно проверили это устройство.</string>
+    <string name="sas_verified_successful">Вы успешно подтвердили эту сессию.</string>
     <string name="sas_verified_successful_description">Защищенные сообщения от этого пользователя шифруются end-to-end и не могут быть прочитаны третьими лицами.</string>
     <string name="sas_got_it">Понял</string>
 
@@ -1527,24 +1525,24 @@
     <string name="sas_cancelled_by_me">Проверка отменена.
 \nПричина: %s</string>
 
-    <string name="sas_verification_request_notification_channel">Интерактивная проверка устройства</string>
+    <string name="sas_verification_request_notification_channel">Интерактивное подтверждение сессии</string>
     <string name="sas_incoming_request_notif_title">Запрос на подтверждение</string>
-    <string name="sas_incoming_request_notif_content">%s хочет проверить ваше устройство</string>
+    <string name="sas_incoming_request_notif_content">%s желает подтвердить ваше устройство</string>
 
     <string name="sas_error_m_user">Пользователь отменил проверку</string>
     <string name="sas_error_m_timeout">Время проверки истекло</string>
-    <string name="sas_error_m_unknown_transaction">Устройство не знает об этой транзакции</string>
-    <string name="sas_error_m_unknown_method">Устройство не может договориться о соглашении по ключе, хэше, MAC или методе SAS</string>
+    <string name="sas_error_m_unknown_transaction">Сессия не знает об этой транзакции</string>
+    <string name="sas_error_m_unknown_method">Сессия не может договориться о выработке общего ключе, хэше, MAC или методе SAS</string>
     <string name="sas_error_m_mismatched_commitment">Полученный хеш не соответствует</string>
     <string name="sas_error_m_mismatched_sas">SAS не соответствует</string>
-    <string name="sas_error_m_unexpected_message">Устройство получило нежданное сообщение</string>
+    <string name="sas_error_m_unexpected_message">Сессия получила неожиданное сообщение</string>
     <string name="sas_error_m_invalid_message">Было получено недопустимое сообщение</string>
     <string name="sas_error_m_key_mismatch">Несоответствие ключей</string>
     <string name="sas_error_m_user_error">Несоответствие пользователя</string>
     <string name="sas_error_unknown">Неизвестная ошибка</string>
 
     <string name="keys_backup_setup_override_backup_prompt_tile">Резервная копия существует на домашнем сервере</string>
-    <string name="keys_backup_setup_override_backup_prompt_description">Похоже, что у вас уже есть резервное копирование ключа настройки с другого устройства. Вы хотите заменить его на тот, который вы создаете\?</string>
+    <string name="keys_backup_setup_override_backup_prompt_description">"Похоже, у вас уже есть резервная копия  ключа настройки из другой сессии. Хотите заменить его новым\?"</string>
     <string name="keys_backup_setup_override_replace">Заменить</string>
     <string name="keys_backup_setup_override_stop">Стоп</string>
 
@@ -1564,7 +1562,7 @@
     <string name="room_list_catchup_welcome_title">Добро пожаловать домой!</string>
     <string name="room_list_catchup_welcome_body">Узнайте больше о непрочитанных сообщениях здесь</string>
     <string name="room_list_people_empty_title">Беседа</string>
-    <string name="room_list_people_empty_body">Ваше прямое сообщение будет отображаться здесь</string>
+    <string name="room_list_people_empty_body">Здесь будут отображаться ваши диалоги</string>
     <string name="room_list_rooms_empty_title">Комнаты</string>
     <string name="room_list_rooms_empty_body">Ваши комнаты будут отображаться здесь</string>
 
@@ -1628,7 +1626,7 @@
     <string name="push_gateway_item_app_id">app_id:</string>
     <string name="push_gateway_item_push_key">push_key:</string>
     <string name="push_gateway_item_app_display_name">app_display_name:</string>
-    <string name="push_gateway_item_device_name">device_name:</string>
+    <string name="push_gateway_item_device_name">session_name:</string>
     <string name="push_gateway_item_url">Url:</string>
     <string name="push_gateway_item_format">Формат:</string>
 
@@ -1787,7 +1785,7 @@
 
     <string name="settings_discovery_disconnect_with_bound_pid">В настоящее время вы делитесь адресами электронной почты или телефонными номерами на сервере идентификации %1$s. Вам нужно повторно подключиться к %2$s, чтобы прекратить делиться ими.</string>
     <string name="settings_agree_to_terms">Примите Условия обслуживания сервера идентификации (%s), чтобы разрешить обнаружение по адресу электронной почты или номеру телефона.</string>
-    <string name="labs_allow_extended_logging">Включить подробное журнал.</string>
+    <string name="labs_allow_extended_logging">Включить подробные логи.</string>
     <string name="send_attachment">Отправить вложенное</string>
 
     <string name="a11y_open_drawer">Откройте навигационный ящик</string>
@@ -1811,4 +1809,42 @@
     <string name="room_widget_permission_room_id">ID комнаты</string>
 
 
+    <string name="resources_script">Cyrl</string>
+
+    <string name="settings_integrations_summary">Используйте менеджер интеграций чтобы управлять ботами, мостами, виджетами и наборами стикеров.
+\nМенеджеры интеграций получают данные о конфигурации, могут изменять виджеты, отправлять приглашения в комнаты и устанавливать права от вашего имени.</string>
+    <string name="room_widget_permission_webview_shared_info_title">"Использование может оставить cookie на вашем устройстве и отправить данные в  %s:"</string>
+    <string name="room_widget_permission_shared_info_title">Использование может отправить данные в %s:</string>
+    <string name="room_widget_failed_to_load">Не удалось загрузить виджет.
+\n%s</string>
+    <string name="room_widget_revoke_access">Отозвать доступ для меня</string>
+
+    <string name="room_widget_permission_display_name">Ваше отображаемое имя</string>
+    <string name="room_widget_permission_avatar_url">URL вашего аватара</string>
+    <string name="room_widget_permission_user_id">Ваш ID</string>
+    <string name="room_widget_resource_permission_title">Данный виджет запрашивает доступ к следующим ресурсам:</string>
+    <string name="room_widget_resource_decline_permission">Запретить все</string>
+    <string name="room_widget_webview_access_camera">Использовать камеру</string>
+    <string name="room_widget_webview_access_microphone">Использовать микрофон</string>
+    <string name="room_widget_webview_read_protected_media">Получать доступ к медиа, защищённым DRM</string>
+
+    <string name="a11y_create_room">Создать новую комнату</string>
+    <string name="a11y_show_password">Показать пароль</string>
+    <string name="a11y_hide_password">Скрыть пароль</string>
+    <string name="attachment_type_file">Файл</string>
+    <string name="attachment_type_camera">Камера</string>
+    <string name="attachment_type_audio">Звук</string>
+    <string name="attachment_type_gallery">Галерея</string>
+    <string name="report_content_spam">Это спам</string>
+    <string name="message_ignore_user">Заблокировать пользователя</string>
+
+    <string name="room_list_quick_actions_notifications_all">Все сообщения</string>
+    <string name="room_list_quick_actions_notifications_mentions">Только упоминания</string>
+    <string name="room_list_quick_actions_settings">Настройки</string>
+    <string name="room_list_quick_actions_leave">Покинуть комнату</string>
+    <string name="room_join_rules_public">%1$s сделал комнату доступной для всех, у кого есть ссылка.</string>
+    <string name="room_join_rules_invite">%1$s сделал комнату доступной только по приглашению.</string>
+    <string name="labs_allow_extended_logging_summary">Подробные логи помогут разработчикам, предоставив больше информации, когда вы отправляете RageShake. Даже когда они разрешены, приложение не логирует ваши сообщения и другие приватные данные.</string>
+
+
 </resources>
diff --git a/vector/src/main/res/values-sk/strings.xml b/vector/src/main/res/values-sk/strings.xml
index 5dd0fcc0da..9fc9bb8ffe 100644
--- a/vector/src/main/res/values-sk/strings.xml
+++ b/vector/src/main/res/values-sk/strings.xml
@@ -7,7 +7,7 @@
     <string name="dark_theme">Tmavý vzhľad</string>
     <string name="black_them">Čierny vzhľad</string>
 
-    <string name="notification_sync_in_progress">Synchronizácia…</string>
+    <string name="notification_sync_in_progress">Prebieha synchronizácia…</string>
     <string name="notification_listening_for_events">Spracovanie udalostí</string>
 
     <string name="title_activity_home">Správy</string>
@@ -1306,4 +1306,27 @@ Objavte skutočne výkonné možnosti otvorenej spolupráce s Riot.im!</string>
     <string name="error_empty_field_enter_user_name">Prosím zadajte meno používateľa.</string>
     <string name="title_activity_verify_device">Overiť zariadenie</string>
 
+    <string name="resources_script">Latn</string>
+
+    <string name="none">Žiadny</string>
+    <string name="revoke">Zrušiť</string>
+    <string name="disconnect">Odpojiť sa</string>
+    <string name="review">Náhlad</string>
+    <string name="decline">Odmietnuť</string>
+
+    <string name="people_no_identity_server">Nebol nakonfigurovaný overovací server.</string>
+
+    <string name="call_failed_no_ice_title">Hovor zlyhal kvôli zle nakonfigurovanému serveru</string>
+    <string name="call_failed_no_ice_description">Prosím, požiadajte administrátora vášho homeserveru (%1$s) o konfiguráciu TURN serveru, aby hovory fungovali spoľahlivo. 
+\n 
+\nPrípadně môžete skúsiť použiť verejný server %2$s, ale nebude tak spoľahlivý a bude zdielať vašu IP adresu s týmto serverom. V nastaveniach sa to dá zmeniť.</string>
+    <string name="call_failed_no_ice_use_alt">Skúste použiť %s</string>
+    <string name="call_failed_dont_ask_again">Viac sa nepýtať</string>
+
+    <string name="auth_add_email_message_2">Nastavte e-mail na obnovenie účtu a voliteľne aby ho neskôr ľudia, ktorí vás poznajú, mohli nájsť.</string>
+    <string name="auth_add_phone_message_2">Nastavte telefónne číslo, aby neskôr bolo voliteľne k nájdeniu ľuďmi, ktorí Vás poznajú.</string>
+    <string name="auth_add_email_phone_message_2">Nastavte e-mail na obnovenie účtu. Použite e-mail alebo telefónne číslo voliteľne neskôr, aby ich našli ľudia, ktorí vás poznajú.</string>
+    <string name="auth_add_email_and_phone_message_2">Nastavte e-mail na obnovenie účtu. Použite e-mail alebo telefónne číslo voliteľne neskôr, aby ich našli ľudia, ktorí vás poznajú.</string>
+    <string name="login_error_no_homeserver_found">Toto nie je platná adresa Matrix serveru</string>
+    <string name="login_error_homeserver_not_found">Homeserver nie je dostupný na tomto URL, prosím, preverte</string>
 </resources>
diff --git a/vector/src/main/res/values-sq/strings.xml b/vector/src/main/res/values-sq/strings.xml
index 96e0e1201a..970587e702 100644
--- a/vector/src/main/res/values-sq/strings.xml
+++ b/vector/src/main/res/values-sq/strings.xml
@@ -831,7 +831,7 @@
     <string name="login_error_limit_exceeded">Janë dërguar shumë kërkesa</string>
     <string name="login_error_login_email_not_yet">Lidhja email që s’është klikuar ende</string>
 
-    <string name="e2e_re_request_encryption_key"><u>Rikërkoni kyçe fshehtëzimi</u> prej sesionesh tuaj të tjerë.</string>
+    <string name="e2e_re_request_encryption_key">Rikërkoni kyçe fshehtëzimi prej sesionesh tuaj të tjerë.</string>
 
     <plurals name="membership_changes">
         <item quantity="one">1 ndryshim anëtarësie</item>
@@ -1283,7 +1283,7 @@ Që të garantoni se s’ju shpëton gjë, thjesht mbajeni të aktivizuar mekani
     <string name="keys_backup_banner_recover_line1">Mos humbni kurrë mesazhe të fshehtëzuar</string>
     <string name="keys_backup_banner_recover_line2">Përdor Kopjeruajtje Kyçesh</string>
 
-    <string name="keys_backup_banner_update_line1">Kyçe të rinj mesazhesh të fshehtëzuar</string>
+    <string name="keys_backup_banner_update_line1">Kyçe të rinj mesazhesh të sigurt</string>
     <string name="keys_backup_banner_update_line2">Administroni Kopjeruajtje Kyçesh</string>
 
     <string name="keys_backup_banner_in_progress">Po kopjeruhen kyçet…</string>
@@ -1313,7 +1313,7 @@ Që të garantoni se s’ju shpëton gjë, thjesht mbajeni të aktivizuar mekani
     <string name="keys_backup_restoring_computing_key_waiting_message">Po përllogariten kyçe rimarrjesh…</string>
     <string name="keys_backup_restoring_downloading_backup_waiting_message">Po shkarkohen kyçe…</string>
     <string name="keys_backup_restoring_importing_keys_waiting_message">Po importohen kyçe…</string>
-    <string name="keys_backup_settings_untrusted_backup">Që të përdorni Kopjeruajtje Kyçesh në këtë sesion, rikthejeni tani përmes frazëkalimit tuaj ose kyçit të rikthimeve.</string>
+    <string name="keys_backup_settings_untrusted_backup">Që të përdorni Kopjeruajtje Kyçesh në këtë sesion, rikthejeni tani përmes frazëkalimit tuaj ose kyçi rimarrjesh.</string>
     <string name="new_recovery_method_popup_title">Kopjeruajtje e Re Kyçesh</string>
     <string name="new_recovery_method_popup_description">U pikas një kopjeruajtje e re kyçesh mesazhesh të sigurt. 
 \n 
@@ -2103,8 +2103,8 @@ Që të garantoni se s’ju shpëton gjë, thjesht mbajeni të aktivizuar mekani
     <string name="verification_request_alert_description">Për siguri ekstra, verifikojeni %s duke parë kontrolluar në të dy pajisjet tuaja një kod njëpërdorimsh.
 \n
 \nPër sigurinë maksimale, bëjeni këtë ju vetë.</string>
-    <string name="rendering_event_error_type_of_event_not_handled">RiotX (ende) nuk trajton akte të llojit \'%1$s\'</string>
-    <string name="rendering_event_error_type_of_message_not_handled">RiotX (ende) nuk trajton mesazhe të llojit \'%1$s\'</string>
+    <string name="rendering_event_error_type_of_event_not_handled">RiotX nuk trajton akte të llojit \'%1$s\'</string>
+    <string name="rendering_event_error_type_of_message_not_handled">RiotX nuk trajton mesazhe të llojit \'%1$s\'</string>
     <string name="rendering_event_error_exception">RiotX ndeshi një problem kur vizatohej lëndë e aktit me ID \'%1$s\'</string>
 
     <string name="verify_cannot_cross_sign">Ky sesion s’është në gjendje të ndajë këtë verifikim me sesionet tuaj të tjerë.
@@ -2120,7 +2120,7 @@ Që të garantoni se s’ju shpëton gjë, thjesht mbajeni të aktivizuar mekani
 \nKyçet privatë nuk njihen</string>
     <string name="settings_active_sessions_unverified_device_desc">Verifikojeni këtë sesion që t’i vihet shenjë si i besuar &amp; dhe t’i akordohet hyrje te mesazhe të fshehtëzuar. Nëse s’keni bërë hyrjen në këtë sesion, llogaria juaj mund të jetë komprometuar:</string>
 
-    <string name="verification_open_other_to_verify">Hapni një sesion ekzistues &amp; përdoreni për të verifikuar këtë, duke i akorduar hyrje te mesazhe të fshehtëzuar. Nëse s’hyni dot te një, përdorni kyçin ose fjalëkalimin tuaj për rimarrje.</string>
+    <string name="verification_open_other_to_verify">Përdorni një sesion ekzistues që të verifikoni këtë këtu, duke i akorduar hyrje te mesazhe të fshehtëzuar.</string>
 
 
     <string name="not_trusted">Jo i Besuar</string>
@@ -2129,7 +2129,153 @@ Që të garantoni se s’ju shpëton gjë, thjesht mbajeni të aktivizuar mekani
     <string name="initialize_cross_signing">Gatit <em>CrossSigning</em></string>
     <string name="reset_cross_signing">Zeroji Kyçet</string>
 
+    <string name="qr_code_scanned_by_other_notice">Thuaje mbërritëm! A shfaq %s të njëjtën mburojë\?</string>
     <string name="qr_code_scanned_by_other_no">Jo</string>
 
     <string name="no_connectivity_to_the_server_indicator">Humbi lidhja me shërbyesin</string>
+    <string name="login_signup_username_hint">Emër përdoruesi</string>
+    <string name="verification_verified_user">%s i verifikuar</string>
+    <string name="settings_dev_tools">Mjete Zhvilluesi</string>
+    <string name="settings_account_data">Të dhëna Llogarie</string>
+    <plurals name="poll_info">
+        <item quantity="one">%d votë</item>
+        <item quantity="other">%d vota</item>
+    </plurals>
+    <plurals name="poll_info_final">
+        <item quantity="one">%d votë - Përfundimet finale</item>
+        <item quantity="other">%d vota - Përfundimet finale</item>
+    </plurals>
+    <string name="poll_item_selected_aria">Mundësi e Përzgjedhur</string>
+    <string name="command_description_poll">Krijoni një pyetësor të thjeshtë</string>
+    <string name="verification_cannot_access_other_session">Përdorni metodë rimarrjesh</string>
+    <string name="verification_use_passphrase">Nëse s’hyni dot në një sesion ekzistues</string>
+
+    <string name="new_signin">Hyrje e Re</string>
+
+    <string name="enter_secret_storage_invalid">S’gjenden dot të fshehta në depozitim</string>
+    <string name="enter_secret_storage_passphrase">Jepni frazëkalimin e fshehtë për në depozitim</string>
+    <string name="enter_secret_storage_passphrase_warning">Kujdes:</string>
+    <string name="enter_secret_storage_passphrase_warning_text">Duhet të hyni në depozitim të fshehtë vetëm nga një pajisje e besuar</string>
+
+    <string name="message_action_item_redact">Hiqni…</string>
+    <string name="share_confirm_room">Doni të dërgohet kjo bashkëngjitje te %1$s\?</string>
+    <plurals name="send_images_with_original_size">
+        <item quantity="one">Dërgoje figurën në madhësinë origjinale</item>
+        <item quantity="other">Dërgoji figurat në madhësinë origjinale</item>
+    </plurals>
+
+    <string name="delete_event_dialog_title">Ripohoni Heqjen</string>
+    <string name="delete_event_dialog_content">Jeni i sigurt se doni të hiqet (fshihet) kjo veprimtari\? Kini parasysh se, nëse fshini emrin ose ndryshimin e temës së një dhome, ndryshimi mund të zhbëhet.</string>
+    <string name="delete_event_dialog_reason_checkbox">Përfshini një arsye</string>
+    <string name="delete_event_dialog_reason_hint">Arsye për redaktimin</string>
+
+    <string name="event_redacted_by_user_reason_with_reason">Veprimtari e fshirë nga përdorues, arsye: %1$s</string>
+    <string name="event_redacted_by_admin_reason_with_reason">Veprimtari e moderuar nga përgjegjësi i dhomës, arsye: %1$s</string>
+
+    <string name="keys_backup_restore_success_title_already_up_to_date">Kyçet janë tashmë të përditësuar!</string>
+
+    <string name="login_mobile_device_riotx">RiotX Android</string>
+
+    <string name="settings_key_requests">Kërkesa Kyçi</string>
+
+    <string name="e2e_use_keybackup">Shkyçni historik mesazhesh të fshehtëzuar</string>
+
+    <string name="refresh">Rifreskoje</string>
+
+    <string name="new_session">Sesion i Ri</string>
+    <string name="new_session_review">Prekeni, që ta shqyrtoni &amp; verifikoni</string>
+    <string name="verify_new_session_notice">Përdoreni këtë sesion që të verifikoni atë të riun tuaj, duke i akorduar hyrje te mesazhe të fshehtëzuar.</string>
+    <string name="verify_new_session_was_not_me">Ky s’qeshë unë</string>
+    <string name="verify_new_session_compromized">Llogaria juaj mund të jetë komprometuar</string>
+
+    <string name="verify_cancel_self_verification_from_untrusted">Nëse e anuloni, s’do të jeni në gjendje të lexoni mesazhe të fshehtëzuar në këtë pajisje, dhe përdoruesit e tjerë s’do ta besojnë</string>
+    <string name="verify_cancel_self_verification_from_trusted">Nëse e anuloni, s’do të jeni në gjendje të lexoni mesazhe të fshehtëzuar në pajisjen tuaj të re, dhe përdoruesit e tjerë s’do ta besojnë</string>
+    <string name="verify_cancel_other">S’do ta verifikoni %1$s (%2$s), nëse e anuloni tani. Fillojani sërish te profili i tij i përdoruesit.</string>
+
+    <string name="verify_not_me_self_verification">Një nga sa vijon mund të jetë komprometuar:
+\n
+\n- Fjalëkalimi juaj
+\n- Shërbyesi juaj Home
+\n- Kjo pajisje, ose pajisja tjetër
+\n- Lidhja internet që përdor njëra pajisje, ose tjetra
+\n
+\nKëshillojmë të ndryshoni menjëherë fjalëkalimin &amp; kyçin tuaj të rimarrjeve te Rregullimet.</string>
+
+    <string name="verify_cancelled_notice">Verifikoni pajisjet tuaja që prej Rregullimeve.</string>
+    <string name="verification_cancelled">Verifikimi u Anulua</string>
+
+    <string name="recovery_passphrase">Fjalëkalim Mesazhesh</string>
+    <string name="message_key">Kyç Mesazhesh</string>
+    <string name="account_password">Fjalëkalim Llogarie</string>
+
+    <string name="set_recovery_passphrase">Caktoni një %s</string>
+    <string name="generate_message_key">Prodhoni një Kyç Mesazhesh</string>
+
+    <string name="confirm_recovery_passphrase">Ripohoni %s</string>
+
+    <string name="enter_account_password">Që të vazhdohet, jepni % tuaj.</string>
+
+    <string name="bootstrap_info_text">Siguroni &amp; shkyçni mesazhet tuaj të fshehtëzuar dhe besim me një %s.</string>
+    <string name="bootstrap_info_confirm_text">Për ta ripohuar, rijepni %s tuaj.</string>
+    <string name="bootstrap_dont_reuse_pwd">Mos ripërdorni fjalëkalimin e llogarisë tuaj.</string>
+
+
+    <string name="bootstrap_loading_text">Kjo mund dojë disa sekonda, ju lutemi, jini i durueshëm.</string>
+    <string name="bootstrap_loading_title">Po ujdiset rimarrje.</string>
+    <string name="your_recovery_key">Kyçi juaj i rimarrjeve</string>
+    <string name="bootstrap_finish_title">Mbaruat!</string>
+    <string name="keep_it_safe">Mbajeni të sigurt</string>
+    <string name="finish">Përfundoje</string>
+
+    <string name="bootstrap_save_key_description">Përdoreni këtë %1$s si një rrjetë sigurie, në rast se harroni %2$s tuaj.</string>
+
+    <string name="bootstrap_crosssigning_progress_pbkdf2">Po prodhohet kyç i sigurt prej frazëkalimi</string>
+    <string name="bootstrap_crosssigning_progress_default_key">Po përcaktohet Kyç parazgjedhje SSSS</string>
+    <string name="bootstrap_crosssigning_progress_save_msk">Po njëkohësohet kyçi i Përgjithshëm</string>
+    <string name="bootstrap_crosssigning_progress_save_usk">Po njëkohësohet kyç Përdoruesi</string>
+    <string name="bootstrap_crosssigning_progress_save_ssk">Po njëkohësohet kyç Vetënënshkrues</string>
+    <string name="bootstrap_crosssigning_progress_key_backup">Po Ujdiset Kopjeruajtje Kyçesh</string>
+
+
+    <string name="bootstrap_cross_signing_success">%2$s &amp; %1$s tani janë ujdisur.
+\n
+\nMbajini të parrezikuar! Do t’ju duhen për të shkyçur mesazhe të fshehtëzuar dhe informacione të sigurta, nëse humbni krejt sesionet tuaja aktive.</string>
+
+    <string name="bootstrap_crosssigning_print_it">Shtypeni dhe ruajeni diku në një vend të parrezik</string>
+    <string name="bootstrap_crosssigning_save_usb">Ruajeni në një diskth USB ose pajisje kopjeruajtjesh</string>
+    <string name="bootstrap_crosssigning_save_cloud">Kopjojeni te depozita juaj personale në re</string>
+
+    <string name="auth_flow_not_supported">Këtë s’e bëni dot prej celulari</string>
+
+    <string name="bootstrap_skip_text">Ujdisja e një Fjalëkalimi Mesazhesh ju lejon të siguroni &amp; shkyçni mesazhe të fshehtëzuar dhe besim.
+\n
+\nNëse s’doni të ujdisni një Fjalëkalim Mesazhesh, prodhoni atëherë një Kyç Mesazhesh.</string>
+    <string name="bootstrap_skip_text_no_gen_key">Ujdisja e një Fjalëkalimi Mesazhesh ju lejon të siguroni &amp; shkyçni mesazhe të fshehtëzuar dhe besim.</string>
+
+
+    <string name="encryption_enabled">Fshehtëzimi u aktivizua</string>
+    <string name="encryption_enabled_tile_description">Mesazhet në këtë dhomë janë të fshehtëzuara skaj-më-skaj. Mësoni më tepër &amp; verifikoni përdorues te profilet e tyre.</string>
+    <string name="encryption_not_enabled">Fshehtëzim jo i aktivizuar</string>
+    <string name="encryption_unknown_algorithm_tile_description">Fshehtëzimi i përdorur nga kjo dhomë nuk mbulohet</string>
+
+    <string name="room_created_summary_item">%s krijoi dhe formësoi dhomën.</string>
+
+    <string name="qr_code_scanned_self_verif_notice">Thuajse mbërritëm! A shfaq pajisja juaj tjetër të njëjtën mburojë\?</string>
+    <string name="qr_code_scanned_verif_waiting_notice">Thuajse mbërritëm! Po pritet për ripohim…</string>
+    <string name="qr_code_scanned_verif_waiting">Po pritet për %s…</string>
+
+    <string name="error_failed_to_import_keys">S’u arrit të importohen kyçe</string>
+
+    <string name="settings_notification_configuration">Formësim njoftimesh</string>
+    <string name="settings_messages_at_room">Mesazhe që përmbajnë @room</string>
+    <string name="settings_messages_in_e2e_one_to_one">Mesazhe të fshehtëzuar në biseda tek-për-tek</string>
+    <string name="settings_messages_in_e2e_group_chat">Mesazhe të fshehtëzuar te biseda në grup</string>
+    <string name="settings_when_rooms_are_upgraded">Kur dhomat përditësohen</string>
+    <string name="settings_troubleshoot_title">Diagnostikoje</string>
+    <string name="settings_notification_advanced_summary_riotx">Caktoni rëndësi njoftimi sipas aktesh</string>
+
+    <string name="command_description_plain">E dërgon një mesazh si tekst të thjeshtë, pa interpretuar elementët Markdown</string>
+
+    <string name="auth_invalid_login_param_space_in_password">Emër përdoruesi dhe/ose fjalëkalim i pasaktë. Fjalëkalimi i dhënë fillon ose mbaron me hapësirë, ju lutemi, kontrollojeni.</string>
+
 </resources>
diff --git a/vector/src/main/res/values-tr/strings.xml b/vector/src/main/res/values-tr/strings.xml
index 53a5264879..c4e2105154 100644
--- a/vector/src/main/res/values-tr/strings.xml
+++ b/vector/src/main/res/values-tr/strings.xml
@@ -7,8 +7,8 @@
     <string name="dark_theme">Koyu Tema</string>
     <string name="black_them">Siyah Tema</string>
 
-    <string name="notification_sync_in_progress">Eşzamanlama (senkronizasyon)</string>
-    <string name="notification_listening_for_events">Olaylar dinleniyor</string>
+    <string name="notification_sync_in_progress">Senkronize ediliyor…</string>
+    <string name="notification_listening_for_events">Etkinlikler dinleniyor</string>
     <string name="notification_noisy_notifications">Sesli bildirimler</string>
     <string name="notification_silent_notifications">Sessiz bildirimler</string>
 
@@ -50,15 +50,15 @@
     <string name="rename">Yeniden Adlandır</string>
     <string name="report_content">İçeriği bildir</string>
     <string name="active_call">Şu anki görüşme</string>
-    <string name="ongoing_conference_call">Devam eden konferans görüşmesi.
-\n%1$s veya %2$s olarak katıl.</string>
-    <string name="ongoing_conference_call_voice">Sesli</string>
+    <string name="ongoing_conference_call">Devam eden konferans görüşmesi. 
+\n%1$s veya %2$s olarak katıl</string>
+    <string name="ongoing_conference_call_voice">Sesli arama</string>
     <string name="ongoing_conference_call_video">Görüntülü</string>
     <string name="cannot_start_call">Görüşme başlatılamıyor, lütfen sonra tekrar deneyin</string>
     <string name="missing_permissions_warning">Eksik izinler nedeni ile bazı özellikler eksik olabilir…</string>
     <string name="missing_permissions_to_start_conf_call">Bu odada bir konferans başlatma davetiyesi göndermek için izniniz olması gerekmektedir</string>
     <string name="missing_permissions_title_to_start_conf_call">Arama gerçekleştirilemiyor</string>
-    <string name="device_information">Cihaz ayrıntıları</string>
+    <string name="device_information">Oturum bilgileri</string>
     <string name="room_no_conference_call_in_encrypted_rooms">Konferans görüşmeleri şifreli (encrypted) odalarda desteklenmiyor</string>
     <string name="send_anyway">Ne olursa olsun gönder</string>
     <string name="or">veya</string>
@@ -88,7 +88,7 @@
     <string name="bottom_action_rooms">Odalar</string>
     <string name="bottom_action_groups">Topluluklar</string>
 
-    <string name="home_filter_placeholder_home">Odaları ara</string>
+    <string name="home_filter_placeholder_home">Oda adlarını filtrele</string>
     <string name="home_filter_placeholder_favorites">Favorileri filtrele</string>
     <string name="home_filter_placeholder_people">Kişileri filtrele</string>
     <string name="home_filter_placeholder_rooms">Oda adlarını filtrele</string>
@@ -185,7 +185,7 @@
     <string name="keys_backup_is_not_finished_please_wait">Anahtar yedekleme tamamlanmadı, lütfen bekleyiniz…</string>
     <string name="sign_out_bottom_sheet_warning_no_backup">Oturumu şimdi kapatırsanız şifrelenmiş mesajlarınızı kaybedeceksiniz</string>
     <string name="sign_out_bottom_sheet_warning_backing_up">Anahtar yedekleme işlemi sürüyor. Şimdi oturumu kapatırsanız tüm şifrelenmiş mesajlarınıza erişiminizi kaybedeceksiniz.</string>
-    <string name="sign_out_bottom_sheet_warning_backup_not_active">Şifrelenmiş mesajlarınızı kaybetmeyi önlemek için Güvenli Anahtar Yedekleme\'nin tüm cihazlarınızda aktif olması gerekmektedir.</string>
+    <string name="sign_out_bottom_sheet_warning_backup_not_active">Şifrelenmiş mesajlarınıza erişimi kaybetmemek için Güvenli Anahtar Yedekleme\'nin tüm oturumlarınızda etkin olması gerekir.</string>
     <string name="sign_out_bottom_sheet_dont_want_secure_messages">Şifrelenmiş mesajlarımı istemiyorum</string>
     <string name="sign_out_bottom_sheet_backing_up_keys">Anahtarlar yedekleniyor…</string>
     <string name="keys_backup_activate">Anahtar Yedekleme Kullan</string>
@@ -225,7 +225,7 @@ Eğer yeni kurtarma yöntemini siz ayarlamadıysanız, bir saldırgan hesabını
     <string name="keys_backup_settings_delete_confirm_title">Yedeği Sil</string>
     <string name="keys_backup_settings_delete_confirm_message">Yedeklenmiş şifreleme anahtarlarınız sunucudan silinsin mi? Bundan sonra şifrelenmiş mesaj geçmişini okumak için kurtarma anahtarınızı kullanamayacaksınız.</string>
 
-    <string name="keys_backup_settings_untrusted_backup">Bu cihazda Anahtar Yedekleme özelliğini kullanmak için şimdi parolanızla veya kurtarma anahtarınızla geri yükleyin.</string>
+    <string name="keys_backup_settings_untrusted_backup">Bu oturumda Anahtar Yedekleme özelliğini kullanmak için şimdi parolanızla veya kurtarma anahtarınızla geri yükleyin.</string>
     <string name="dialog_title_error">Hata</string>
 
     <string name="system_alerts_header">Sistem Uyarıları</string>
@@ -266,9 +266,9 @@ Eğer yeni kurtarma yöntemini siz ayarlamadıysanız, bir saldırgan hesabını
     <string name="auth_reset_password_missing_password">Yeni şifre mutlaka girilmeli.</string>
     <string name="auth_reset_password_email_validation_message">Eposta %s adresine gönderildi. Epostadaki yönergeleri takip ettikten sonra, aşağıdaki tuşa tıklayın.</string>
     <string name="auth_reset_password_error_unauthorized">Eposta doğrulaması başarısız: epostanızdaki bağlantıya tıkladığınızdan emin olun</string>
-    <string name="auth_reset_password_success_message">Şifreniz sıfırlandı.
-\n
-\nTüm cihazlarınızdan çıkış yaptınız ve mesaj bildirimleri almayacaksınız. Tekrar bildirimleri alabilmek için her cihazda tekrar giriş yapmalısınız.</string>
+    <string name="auth_reset_password_success_message">Şifreniz sıfırlandı. 
+\n 
+\nTüm oturumlardan çıkış yaptınız ve mesaj bildirimleri almayacaksınız. Tekrar bildirimleri alabilmek için her cihazda tekrar giriş yapmalısınız.</string>
     <string name="auth_accept_policies">Lütfen anamakinenin ilkelerini gözden geçirin ve kabul edin:</string>
 
     <string name="login_error_must_start_http">URL http[s]:// ile başlamalıdır</string>
@@ -288,16 +288,16 @@ Eğer yeni kurtarma yöntemini siz ayarlamadıysanız, bir saldırgan hesabını
     <string name="login_error_user_in_use">Kullanıcı adı zaten kullanımda</string>
     <string name="login_error_login_email_not_yet">Eposta bağlantısına hala tıklanmadı</string>
 
-    <string name="e2e_need_log_in_again">Bu cihaza özel uçtan uca şifreleme anahtarı oluşturup, herkese açık anahtarı anamakineye yüklemek için giriş yapmanız gerekli.
-\nBu bir kereye mahsus.
+    <string name="e2e_need_log_in_again">Bu oturuma özel uçtan uca şifreleme anahtarı oluşturup, herkese açık anahtarı anamakineye yüklemek için giriş yapmanız gerekli. 
+\nBu bir kereye mahsus. 
 \nRahatsızlık için üzgünüz.</string>
 
-    <string name="e2e_re_request_encryption_key">Diğer cihazlarından <u>şifreleme anahtarlarını tekrar iste</u>.</string>
+    <string name="e2e_re_request_encryption_key">Diğer oturumlardan <u>şifreleme anahtarlarını tekrar iste</u>.</string>
 
     <string name="e2e_re_request_encryption_key_sent">Anahtar isteği gönderildi.</string>
 
     <string name="e2e_re_request_encryption_key_dialog_title">İstek gönderildi</string>
-    <string name="e2e_re_request_encryption_key_dialog_content">Riot\'u mesajları çözebilen farklı bir cihazda açarsanız ordan anahtarları bu cihaza gönderebilirsiniz.</string>
+    <string name="e2e_re_request_encryption_key_dialog_content">Riot\'u mesajları çözebilen farklı bir cihazda açarsanız ordan anahtarları bu oturuma gönderebilirsiniz.</string>
 
     <string name="read_receipts_list">Makbuz Listesini Oku</string>
 
@@ -309,7 +309,7 @@ Eğer yeni kurtarma yöntemini siz ayarlamadıysanız, bir saldırgan hesabını
     </plurals>
 
     <string name="compression_options">Farklı gönder</string>
-    <string name="compression_opt_list_original">Orjinal</string>
+    <string name="compression_opt_list_original">Orijinal</string>
     <string name="compression_opt_list_large">Büyük</string>
     <string name="compression_opt_list_medium">Orta</string>
     <string name="compression_opt_list_small">Küçük</string>
@@ -364,12 +364,10 @@ Eğer yeni kurtarma yöntemini siz ayarlamadıysanız, bir saldırgan hesabını
     <string name="permissions_rationale_msg_camera_and_audio">Riot\'un görüntülü arama yapması için kameranıza ve mikrofonunuza erişmeye ihtiyacı var.
 \n
 \nLütfen çıkacak ekranda kamera ve mikrofona erişebilmesine izin verin.</string>
-    <string name="permissions_rationale_msg_contacts">Riot\'un eposta ve telefon numaralarına göre diğer Matrix kullanıcılarını bulmak için rehberinize erişmeye ihtiyacı var.
-\n
-\nLütfen çıkacak ekranda rehberinize erişebilmesine izin verin.</string>
-    <string name="permissions_msg_contacts_warning_other_androids">Riot\'un eposta ve telefon numaralarına göre diğer Matrix kullanıcılarını bulmak için rehberinize erişmeye ihtiyacı var.
-\n
-\nRiot rehberinize erişebilsin mi\?</string>
+    <string name="permissions_rationale_msg_contacts">Riot eposta ve telefon numaralarına göre diğer Matrix kullanıcılarını bulmak için rehberinizi kontrol edebilir. Eğer bu nedenle rehberinizi paylaşmak istiyorsanız, lütfen açılan ekranda erişime izin verin.</string>
+    <string name="permissions_msg_contacts_warning_other_androids">Riot\'un eposta ve telefon numaralarına göre diğer Matrix kullanıcılarını bulmak için rehberinizi kontrol edebilir. 
+\n 
+\nRehberinizi bu sebeple paylaşmayı kabul ediyor musunuz\?</string>
 
     <string name="permissions_action_not_performed_missing_permissions">Üzgünüz. İsteğiniz, yetersiz izinlerden dolayı gerçekleştirilemedi</string>
 
@@ -437,7 +435,7 @@ Eğer yeni kurtarma yöntemini siz ayarlamadıysanız, bir saldırgan hesabını
     <string name="room_participants_header_admin_tools">YÖNETİCİ ARAÇLARI</string>
     <string name="room_participants_header_call">ARAMA</string>
     <string name="room_participants_header_direct_chats">DİREKT SOHBETLER</string>
-    <string name="room_participants_header_devices">CİHAZLAR</string>
+    <string name="room_participants_header_devices">OTURUMLAR</string>
 
     <string name="room_participants_action_invite">Davet</string>
     <string name="room_participants_action_leave">Odadan ayrıl</string>
@@ -455,7 +453,7 @@ Eğer yeni kurtarma yöntemini siz ayarlamadıysanız, bir saldırgan hesabını
 \nBu işlem uygulamayı yeniden başlatak ve biraz zaman alacak.</string>
     <string name="room_participants_invite_search_another_user">Kullanıcı ID, Ad ya da eposta</string>
     <string name="room_participants_action_mention">Bahset</string>
-    <string name="room_participants_action_devices_list">Cihaz Listesini Göster</string>
+    <string name="room_participants_action_devices_list">Oturum Listesini Göster</string>
     <string name="room_participants_power_level_prompt">Bu işlemin geri dönüşü yok kullanıcıyı sen ile aynı erişim seviyesine getiriyorsun.
 \nEmin misin\?</string>
 
@@ -490,7 +488,7 @@ Eğer yeni kurtarma yöntemini siz ayarlamadıysanız, bir saldırgan hesabını
     <string name="room_message_placeholder_reply_to_not_encrypted">Cevap gönder (şifrelenmemiş)…</string>
     <string name="room_offline_notification">Sunucuya olan bağlantı koptu.</string>
     <string name="room_unsent_messages_notification">Mesaj gönderilemedi. %1$s ya da %2$s yapılsın mı\?</string>
-    <string name="room_unknown_devices_messages_notification">Mesaj gönderilemedi çünkü bilinmeyen bir cihaz belirlendi. %1$s ya da %2$s yapalım mı\?</string>
+    <string name="room_unknown_devices_messages_notification">Mesaj gönderilemedi çünkü bilinmeyen bir oturum belirlendi. %1$s ya da %2$s yapalım mı\?</string>
     <string name="room_prompt_resend">Hepsini tekrar gönder</string>
     <string name="room_prompt_cancel">Hepsini iptal et</string>
     <string name="room_resend_unsent_messages">Gönderilmeyen mesajları tekrar gönder</string>
@@ -619,9 +617,9 @@ Eğer yeni kurtarma yöntemini siz ayarlamadıysanız, bir saldırgan hesabını
 \nLütfen hesap ayarlarınızı gözden geçirin.</string>
     <string name="settings_troubleshoot_test_account_settings_quickfix">Etkinleştir</string>
 
-    <string name="settings_troubleshoot_test_device_settings_title">Cihaz Ayarları.</string>
-    <string name="settings_troubleshoot_test_device_settings_success">Bildirimler bu cihaz için etkinleştirilmiş.</string>
-    <string name="settings_troubleshoot_test_device_settings_failed">Bildirimler bu cihaz için etkin değil.
+    <string name="settings_troubleshoot_test_device_settings_title">Oturum Ayarları.</string>
+    <string name="settings_troubleshoot_test_device_settings_success">Bildirimler bu oturum için etkinleştirilmiş.</string>
+    <string name="settings_troubleshoot_test_device_settings_failed">Bildirimler bu oturum için etkin değil. 
 \nLütfen Riot ayarlarını gözden geçirin.</string>
     <string name="settings_troubleshoot_test_device_settings_quickfix">Etkinleştir</string>
 
@@ -680,13 +678,13 @@ Eğer yeni kurtarma yöntemini siz ayarlamadıysanız, bir saldırgan hesabını
 
     <string name="settings_troubleshoot_test_battery_title">Pil Optimizasyonu</string>
     <string name="settings_troubleshoot_test_battery_success">Riot Pil Optimizasyonundan etkilenmedi.</string>
-    <string name="settings_troubleshoot_test_battery_failed">Eğer kullanıcı cihazını prize bağlanmamış sabit ve ekranı kapalı bir şekilde bir süre bırakırsa cihaz Derin uyku moduna geçer. Bu uygulamaların internete erişmesini engeller ve yapılacak işlerini, senkronizasyolarını, alarmını erteler</string>
+    <string name="settings_troubleshoot_test_battery_failed">Eğer kullanıcı cihazını prize bağlanmamış sabit ve ekranı kapalı bir şekilde bir süre bırakırsa cihaz Derin uyku moduna geçer. Bu uygulamaların internete erişmesini engeller ve yapılacak işlerini, senkronizasyolarını, alarmını erteler.</string>
     <string name="settings_troubleshoot_test_battery_quickfix">Optimizasyonu Göz ardı et</string>
 
     <string name="settings_notification_privacy_normal">Normal</string>
     <string name="settings_notification_privacy_reduced">Azaltılmış gizlilik</string>
     <string name="settings_notification_privacy_need_permission">Uygulamanın arkaplanda çalışması için izne ihtiyacı var</string>
-    <string name="settings_notification_privacy_fcm">• Bildirimler Google Bulut Mesajlaşma ile gönderildi</string>
+    <string name="settings_notification_privacy_fcm">• Bildirimler Firebase Bulut Mesajlaşma ile gönderildi</string>
     <string name="settings_notification_privacy_metadata">• Bildirimler sadece meta verileri içeriyor</string>
     <string name="settings_notification_privacy_secure_message_content">• Bildirimin mesaj içeriği <b>direkt Matrix anamakinesinden güvenli bir şekilde bulundu</b></string>
     <string name="settings_notification_privacy_nosecure_message_content">• Bildirimler <b>meta ve mesaj verileri</b> içeriyor</string>
@@ -694,7 +692,7 @@ Eğer yeni kurtarma yöntemini siz ayarlamadıysanız, bir saldırgan hesabını
 
     <string name="settings_notification_ringtone">Bildirim sesi</string>
     <string name="settings_enable_all_notif">Bildirim seslerini bu hesap için etkinleştir</string>
-    <string name="settings_enable_this_device">Bildirim seslerini bu cihaz için etkinleştir</string>
+    <string name="settings_enable_this_device">Bildirim seslerini bu oturum için etkinleştir</string>
     <string name="settings_turn_screen_on">Ekranı 3 saniyeliğine açık tut</string>
     <string name="settings_noisy_notifications_preferences">Sesli Bildirimleri Ayarla</string>
     <string name="settings_call_notifications_preferences">Arama Bildirimlerini Ayarla</string>
@@ -714,7 +712,7 @@ Eğer yeni kurtarma yöntemini siz ayarlamadıysanız, bir saldırgan hesabını
     <string name="settings_start_on_boot">Açılışta başlat</string>
     <string name="settings_enable_background_sync">Arkaplanda eşzamanlamayı etkinleştir</string>
     <string name="settings_set_sync_timeout">Eşzamanlama talep süresi doldu</string>
-    <string name="settings_set_sync_delay">Her talep arasında gecikme</string>
+    <string name="settings_set_sync_delay">Her senkronizasyon arası gecikme</string>
     <string name="settings_second">saniye</string>
     <string name="settings_seconds">saniye</string>
 
@@ -742,7 +740,7 @@ Eğer yeni kurtarma yöntemini siz ayarlamadıysanız, bir saldırgan hesabını
     <string name="settings_home_display">Ana ekran</string>
     <string name="settings_pin_missed_notifications">Bildirimlerini kaçırdığın odaları öne çıkar</string>
     <string name="settings_pin_unread_messages">Okunmamış mesajlı odaları öne çıkar</string>
-    <string name="settings_devices_list">Cihazlar</string>
+    <string name="settings_devices_list">Oturumlar</string>
     <string name="settings_inline_url_preview">Satır içi URL önizlemesi</string>
     <string name="settings_inline_url_preview_summary">Bağlantıları anamakine destekliyorsa sohbette önizle.</string>
     <string name="settings_send_typing_notifs">Yazıyor bildirimleri gönder</string>
@@ -782,10 +780,10 @@ Eğer yeni kurtarma yöntemini siz ayarlamadıysanız, bir saldırgan hesabını
     <string name="settings_data_save_mode">Veri kaydetme modu</string>
     <string name="settings_data_save_mode_summary">Veri kaydetme modu belirli filtreler uygular bu sayede ilerki güncellemeler ve yazıyor bildirimleri filtrelenir.</string>
 
-    <string name="devices_details_dialog_title">Cihaz detayları</string>
+    <string name="devices_details_dialog_title">Oturum bilgileri</string>
     <string name="devices_details_id_title">ID</string>
-    <string name="devices_details_name_title">Ad</string>
-    <string name="devices_details_device_name">Cihaz Adı</string>
+    <string name="devices_details_name_title">Görünür Ad</string>
+    <string name="devices_details_device_name">Görünür Adı Güncelle</string>
     <string name="devices_details_last_seen_title">Son görülme</string>
     <string name="devices_details_last_seen_format">%1$s @ %2$s</string>
     <string name="devices_delete_dialog_text">Bu işlem ek yetki gerektiriyor.
@@ -812,9 +810,9 @@ Eğer yeni kurtarma yöntemini siz ayarlamadıysanız, bir saldırgan hesabını
 
     <string name="settings_password">Şifre</string>
     <string name="settings_change_password">Şifreni değiştir</string>
-    <string name="settings_old_password">Eski şifre</string>
+    <string name="settings_old_password">Mevcut şifre</string>
     <string name="settings_new_password">Yeni şifre</string>
-    <string name="settings_confirm_password">Tekrar şifre</string>
+    <string name="settings_confirm_password">Yeni şifreyi onayla</string>
     <string name="settings_fail_to_update_password">Şifreyi güncellerken hata oluştu</string>
     <string name="settings_password_updated">Şifren güncellendi</string>
     <string name="settings_unignore_user">%s den/dan tüm mesajlar gösterilsin mi\?
@@ -885,8 +883,8 @@ Eğer yeni kurtarma yöntemini siz ayarlamadıysanız, bir saldırgan hesabını
     <string name="room_settings_labs_end_to_end">Uçtan-uca Şifreleme</string>
     <string name="room_settings_labs_end_to_end_is_active">Uçtan-uca Şifreleme etkin</string>
     <string name="room_settings_labs_end_to_end_warnings">Şifrelemeyi etkinleştimek için çıkış yapman gerekiyor.</string>
-    <string name="room_settings_never_send_to_unverified_devices_title">Sadece doğrulanmış cihazlara şifrele</string>
-    <string name="room_settings_never_send_to_unverified_devices_summary">Asla doğrulanmamış cihaz olan oda da şifrelenmiş mesaj gönderme.</string>
+    <string name="room_settings_never_send_to_unverified_devices_title">Sadece doğrulanmış oturumlara şifrele</string>
+    <string name="room_settings_never_send_to_unverified_devices_summary">Asla doğrulanmamış oturum olan oda da şifrelenmiş mesaj gönderme.</string>
 
     <string name="room_settings_addresses_no_local_addresses">Bu oda yerel adrese sahip değil</string>
     <string name="room_settings_addresses_add_new_address">Yeni adres (örn. #foo:matrix.org)</string>
@@ -919,7 +917,7 @@ Eğer yeni kurtarma yöntemini siz ayarlamadıysanız, bir saldırgan hesabını
 
     <string name="encryption_information_title">Uçtan-uca şifreleme bilgilendirmesi</string>
 
-    <string name="encryption_information_device_info">Olay Bilgilendirmesi</string>
+    <string name="encryption_information_device_info">Etkinlik Bilgilendirmesi</string>
     <string name="encryption_information_user_id">Kullanıcı idsi</string>
     <string name="encryption_information_curve25519_identity_key">Curve25519 kimlik anahtarı</string>
     <string name="encryption_information_claimed_ed25519_fingerprint_key">Alınmış Ed25519 parmak izi anahtarı</string>
@@ -927,11 +925,11 @@ Eğer yeni kurtarma yöntemini siz ayarlamadıysanız, bir saldırgan hesabını
     <string name="encryption_information_session_id">Oturum ID\'si</string>
     <string name="encryption_information_decryption_error">Çözme hatası</string>
 
-    <string name="encryption_information_sender_device_information">Göndericinin cihaz bilgisi</string>
-    <string name="encryption_information_device_name">Cihaz adı</string>
-    <string name="encryption_information_name">Ad</string>
-    <string name="encryption_information_device_id">Cihaz ID\'si</string>
-    <string name="encryption_information_device_key">Cihaz anahtarı</string>
+    <string name="encryption_information_sender_device_information">Göndericinin oturum bilgisi</string>
+    <string name="encryption_information_device_name">Görünür Ad</string>
+    <string name="encryption_information_name">Görünür Ad</string>
+    <string name="encryption_information_device_id">Kimlik</string>
+    <string name="encryption_information_device_key">Oturum anahtarı</string>
     <string name="encryption_information_verification">Doğrulama</string>
     <string name="encryption_information_ed25519_fingerprint">Ed25519 parmak izi</string>
 
@@ -951,15 +949,15 @@ Eğer yeni kurtarma yöntemini siz ayarlamadıysanız, bir saldırgan hesabını
     <string name="encryption_import_room_keys">Oda anahtarlarını içe aktar</string>
     <string name="encryption_import_room_keys_summary">Oda anahtarını yerel dosyadan içe aktar</string>
     <string name="encryption_import_import">İçe aktar</string>
-    <string name="encryption_never_send_to_unverified_devices_title">Sadece doğrulanmış cihazlara şifrele</string>
-    <string name="encryption_never_send_to_unverified_devices_summary">Asla bu cihazdan doğrulanmamış cihazlara şifrelenmiş mesaj gönderme.</string>
+    <string name="encryption_never_send_to_unverified_devices_title">Sadece doğrulanmış oturumlara şifrele</string>
+    <string name="encryption_never_send_to_unverified_devices_summary">Asla bu cihazdan doğrulanmamış oturumlara şifrelenmiş mesaj gönderme.</string>
     <string name="encryption_import_room_keys_success">%1$d/%2$d anahtar başarı ile içe aktarıldı.</string>
 
     <string name="encryption_information_not_verified">Doğrulanmamış</string>
     <string name="encryption_information_verified">Doğrulanmış</string>
     <string name="encryption_information_blocked">Karalistede</string>
 
-    <string name="encryption_information_unknown_device">bilinmeyen cihaz</string>
+    <string name="encryption_information_unknown_device">bilinmeyen oturum</string>
     <string name="encryption_information_none">yok</string>
 
     <string name="encryption_information_verify">Doğrula</string>
@@ -967,21 +965,21 @@ Eğer yeni kurtarma yöntemini siz ayarlamadıysanız, bir saldırgan hesabını
     <string name="encryption_information_block">Karalisteye ekle</string>
     <string name="encryption_information_unblock">Karalisteden sil</string>
 
-    <string name="encryption_information_verify_device">Cihazı doğrula</string>
-    <string name="encryption_information_verify_device_warning">Bu cihazın güvenilir olduğunu doğrulamak için, lütfen sahibi ile iletişime geçin (örn. yüz yüze ya da telefonla arama) ve onlara Kullanıcı Ayarları altında hangi anahtarın aşağıdaki anahtar ile uyuştuğunu sorun:</string>
-    <string name="encryption_information_verify_device_warning2">Eğer uyuşursa aşağıdaki doğrulama tuşuna basın. Eğer uyuşmaz ise biri bu cihazı engelliyor demektir bu durumda sen o kişi karalisteye eklemelisin. Gelecekte doğrulama işlemi daha gelişmiş olacak.</string>
+    <string name="encryption_information_verify_device">Oturumu doğrula</string>
+    <string name="encryption_information_verify_device_warning">Bu oturumun güvenilir olduğunu doğrulamak için, lütfen sahibi ile iletişime geçin (örn. yüz yüze ya da telefonla arama) ve onlara Kullanıcı Ayarları altında hangi anahtarın aşağıdaki anahtar ile uyuştuğunu sorun:</string>
+    <string name="encryption_information_verify_device_warning2">Eğer uyuşursa aşağıdaki doğrulama tuşuna basın. Eğer uyuşmaz ise biri bu oturum engelliyor demektir bu durumda sen o kişi karalisteye eklemelisin. Gelecekte doğrulama işlemi daha gelişmiş olacak.</string>
     <string name="encryption_information_verify_key_match">Anahtarın uyuştuğunu doğruluyorum</string>
 
-    <string name="e2e_enabling_on_app_update">Riot artık uçtan-uca şifrelemeyi destekliyor ancak etkinleştirmen için tekrar giriş yapman gerekli.
-\n
-\nBunu şimdi yada sonra uygulama ayarlarından yapabilirsin.</string>
+    <string name="e2e_enabling_on_app_update">Riot artık uçtan-uca şifrelemeyi destekliyor ancak etkinleştirmen için tekrar giriş yapman gerekli. 
+\n 
+\nBunu şimdi ya da sonra uygulama ayarlarından yapabilirsin.</string>
 
-    <string name="unknown_devices_alert_title">Oda bilinmeyen cihaz barındırıyor</string>
-    <string name="unknown_devices_alert_message">Bu oda doğrulanmamış bilinmeyen cihaz barındırıyor.
-\nBu cihazların kullanıcıların sahip olduğu cihaz olduklarının garantisi yok.
-\nDevam etmeden önce her cihaz için doğrulama işlemi yapmanızı öneririz, fakat isterseniz mesajları doğrulamadan da tekrar gönderebilirsiniz.
-\n
-\nBilinmeyen Cihazlar:</string>
+    <string name="unknown_devices_alert_title">Oda bilinmeyen oturum barındırıyor</string>
+    <string name="unknown_devices_alert_message">Bu oda doğrulanmamış bilinmeyen oturum barındırıyor. 
+\nBu oturumların kullanıcıların sahip olduğu cihaz olduklarının garantisi yok. 
+\nDevam etmeden önce her oturum için doğrulama işlemi yapmanızı öneririz, fakat isterseniz mesajları doğrulamadan da tekrar gönderebilirsiniz. 
+\n 
+\nBilinmeyen Oturumlar:</string>
 
     <string name="select_room_directory">Bir oda dizini seç</string>
     <string name="directory_server_fail_to_retrieve_server">Sunucu müsait değil ya da aşırı yüklenmiş</string>
@@ -1045,8 +1043,8 @@ Eğer yeni kurtarma yöntemini siz ayarlamadıysanız, bir saldırgan hesabını
     <string name="settings_labs_enable_send_voice">Sesli mesaj gönder</string>
     <string name="settings_labs_enable_send_voice_summary">Bu seçenek mesajları kaydetmek için üçüncü parti bir uygulama gerektiriyor.</string>
 
-    <string name="you_added_a_new_device">%s adlı şifreleme anahatarlarını isteyebilen yeni bir cihaz eklediniz.</string>
-    <string name="your_unverified_device_requesting">%s adlı doğrulanmamış cihaz şifreleme anahtarlarını istiyor.</string>
+    <string name="you_added_a_new_device">%s adlı şifreleme anahatarlarını isteyebilen yeni bir oturum eklediniz.</string>
+    <string name="your_unverified_device_requesting">%s adlı doğrulanmamış oturum şifreleme anahtarlarını istiyor.</string>
     <string name="start_verification">Doğrulamayı başlat</string>
     <string name="share_without_verifying">Doğrulamadan paylaş</string>
     <string name="ignore_request">İsteği göz ardı et</string>
@@ -1236,11 +1234,11 @@ Neden Riot.im’i seçmeliyim?
 
     <string name="keys_backup_setup_step3_please_make_copy">Lütfen bir kopya oluşturun</string>
     <string name="keys_backup_setup_step3_share_intent_chooser_title">Kurtarma anahtarını bununla paylaş…</string>
-    <string name="keys_backup_setup_step3_generating_key_status">Parola kullanılarak Kurtarma anahtarı oluşturuluyor bu işlem bir kaç saniye sürecek.</string>
+    <string name="keys_backup_setup_step3_generating_key_status">Parola kullanılarak Kurtarma anahtarı oluşturuluyor bu işlem birkaç saniye sürecek.</string>
     <string name="recovery_key">Kurtarma Anahtarı</string>
     <string name="unexpected_error">Beklenmeyen hata</string>
     <string name="keys_backup_setup_backup_started_title">Yedekleme Başlatıldı</string>
-    <string name="keys_backup_setup_backup_started_message">Şifreleme anahtarın arkaplanda anamakineye yedeklenecek. İlk yedekleme bir kaç dakika sürecek.</string>
+    <string name="keys_backup_setup_backup_started_message">Şifreleme anahtarın arkaplanda anamakineye yedeklenecek. İlk yedekleme birkaç dakika sürecek.</string>
 
 
     <string name="keys_backup_setup_skip_title">Emin misin\?</string>
@@ -1269,14 +1267,14 @@ Neden Riot.im’i seçmeliyim?
     <string name="keys_backup_recovery_code_error_decrypt">Yedekleme bu kurtarma anahtarı ile çözülemez: lütfen doğru kurtarma anahtarını girdiğinizi doğrulayın.</string>
 
     <string name="keys_backup_restore_success_title">Yedekleme İşlendi %s !</string>
-    <string name="keys_backup_restore_success_description">%1$d oturum anahtarı onarıldı ve bu cihaz tarafından bilinmeyen %2$d yeni anahtar eklendi</string>
+    <string name="keys_backup_restore_success_description">%1$d oturum anahtarı onarıldı ve bu oturum tarafından bilinmeyen %2$d yeni anahtar eklendi</string>
     <plurals name="keys_backup_restore_success_description_part1">
         <item quantity="one">Yedekleme %d anahtarı ile işlendi.</item>
         <item quantity="other">Yedekleme %d anahtarları ile işlendi.</item>
     </plurals>
     <plurals name="keys_backup_restore_success_description_part2">
-        <item quantity="one">%d tane yeni anahtar bu cihaza eklendi.</item>
-        <item quantity="other">%d tane yeni anahtar bu cihaza eklendi.</item>
+        <item quantity="one">%d yeni anahtar bu oturuma eklendi.</item>
+        <item quantity="other">%d tane yeni anahtar bu oturuma eklendi.</item>
     </plurals>
 
     <string name="keys_backup_get_version_error">Son sürüm onarma anahtarı alınırken hata oluştu (%s).</string>
@@ -1286,16 +1284,16 @@ Neden Riot.im’i seçmeliyim?
     <string name="keys_backup_settings_restore_backup_button">Yedeklemeden onar</string>
     <string name="keys_backup_settings_delete_backup_button">Yedeklemeyi Sil</string>
 
-    <string name="keys_backup_settings_status_ok">Anahtar Yedekleme bu cihaz için doğru bir şekilde ile ayarlandı.</string>
-    <string name="keys_backup_settings_status_ko">Anahtar Yedekleme bu cihazda etkin değil.</string>
-    <string name="keys_backup_settings_status_not_setup">Anahtarlarınız bu cihazdan yenilenemiyor.</string>
+    <string name="keys_backup_settings_status_ok">Anahtar Yedekleme bu oturum için doğru bir şekilde ile ayarlandı.</string>
+    <string name="keys_backup_settings_status_ko">Anahtar Yedekleme bu oturumda etkin değil.</string>
+    <string name="keys_backup_settings_status_not_setup">Anahtarlarınız bu oturumdan yenilenemiyor.</string>
 
-    <string name="keys_backup_settings_signature_from_unknown_device">Yedekleme %s ID\'li bilinmeyen cihazdan gelen bir imzaya sahip.</string>
-    <string name="keys_backup_settings_valid_signature_from_this_device">Yedekleme bu cihazdan geçerli imzaya sahip.</string>
-    <string name="keys_backup_settings_valid_signature_from_verified_device">Yedekleme %s adlı doğrulanmış cihazdan geçerli imzaya sahip.</string>
-    <string name="keys_backup_settings_valid_signature_from_unverified_device">Yedekleme %s adlı doğrulanmamış cihazdan geçerli imzaya sahip</string>
-    <string name="keys_backup_settings_invalid_signature_from_verified_device">Yedekleme %s adlı doğrulanmış cihazdan geçersiz imzaya sahip</string>
-    <string name="keys_backup_settings_invalid_signature_from_unverified_device">Yedekleme %s adlı doğrulanmamış cihazdan geçersiz imzaya sahip</string>
+    <string name="keys_backup_settings_signature_from_unknown_device">Yedekleme %s ID\'li bilinmeyen oturumdan gelen bir imzaya sahip.</string>
+    <string name="keys_backup_settings_valid_signature_from_this_device">Yedekleme bu oturumdan geçerli imzaya sahip.</string>
+    <string name="keys_backup_settings_valid_signature_from_verified_device">Yedekleme %s adlı doğrulanmış oturumdan geçerli imzaya sahip.</string>
+    <string name="keys_backup_settings_valid_signature_from_unverified_device">Yedekleme %s adlı doğrulanmamış oturumdan geçerli imzaya sahip</string>
+    <string name="keys_backup_settings_invalid_signature_from_verified_device">Yedekleme %s adlı doğrulanmış oturumdan geçersiz imzaya sahip</string>
+    <string name="keys_backup_settings_invalid_signature_from_unverified_device">Yedekleme %s adlı doğrulanmamış oturumdan geçersiz imzaya sahip</string>
     <string name="keys_backup_get_trust_error">Yedekleme için güven bilgisi alınırken hata oluştu (%s).</string>
 
     <plurals name="keys_backup_info_keys_backing_up">
@@ -1307,26 +1305,268 @@ Neden Riot.im’i seçmeliyim?
     <string name="keys_backup_info_title_algorithm">Algoritma</string>
     <string name="keys_backup_info_title_signature">İmza</string>
 
-    <string name="notification_sync_init">İşlem başlatılıyor</string>
-    <string name="title_activity_verify_device">Cihazı doğrula</string>
+    <string name="notification_sync_init">Hizmet başlatılıyor</string>
+    <string name="title_activity_verify_device">Oturumu doğrula</string>
 
     <string name="none">Hiç (Yok)</string>
     <string name="revoke">Geri Al</string>
     <string name="disconnect">Bağlantıyı Kes</string>
-    <string name="ignore">Önemseme</string>
+    <string name="ignore">Yoksay</string>
     <string name="review">Gözden Geçir</string>
     <string name="decline">Reddet</string>
 
     <string name="action_mark_room_read">Okunmuş olarak işaretle</string>
-    <string name="call_failed_no_ice_title">Arama yanlış yapılandırılmış odadan dolayı başarısız oldu</string>
+    <string name="call_failed_no_ice_title">Arama yanlış yapılandırılmış sunucudan dolayı başarısız oldu</string>
     <string name="call_failed_no_ice_use_alt">%s kullanmayı deneyin</string>
-    <string name="call_failed_dont_ask_again">Yeniden sorma</string>
+    <string name="call_failed_dont_ask_again">Tekrar sorma</string>
 
     <string name="auth_login_sso">Tek oturum açma ile giriş yap</string>
-    <string name="auth_add_email_message_2">Hesap kurtarması için email ayarla, ve sonradan da isteğe bağlı olarak başklarının seni tanıyan kişilerin bulması için kullan.</string>
+    <string name="auth_add_email_message_2">Hesap kurtarma epostası kaydedin ve daha sonra isteğe bağlı olarak sizi tanıyan kişilerin sizi bulabilmesini sağlayın.</string>
     <string name="login_error_unknown_host">Bu adrese erişilemiyor, lütfen kontrol et</string>
-    <string name="settings_notification_privacy_no_background_sync">Bu uygulamanın arkaplanda anasunucuya bağlanması <b>gerekmez</b>, bu durum batarya kullanımını azaltır.</string>
+    <string name="settings_notification_privacy_no_background_sync">Bu uygulamanın arkaplanda anasunucuya bağlanması <b>gerekmez</b>, bu durum batarya kullanımını azaltır</string>
     <string name="settings_send_message_with_enter">Enter ile mesaj gönder</string>
     <string name="settings_send_message_with_enter_summary">Klavyedeki Enter tuşuna bastığında alt satıra geçmek yerine mesajı gönder</string>
 
+    <string name="resources_script">Latn</string>
+
+    <string name="people_no_identity_server">Hiçbir kimlik sunucusu yapılandırılmamış.</string>
+
+    <string name="call_failed_no_ice_description">Lütfen çağrıların düzgün çalışması için anasunucuzun (%1$s) yetkilisine DÖNÜŞ sunucusunu yapılandırmasını söyleyin.
+\n
+\nAlternatif olarak %2$s herkese açık sunucuyu kullanmayı da deneyebilirsiniz, ancak bu o kadar da güvenilir olmayacak ve IP adresiniz sunucu ile paylaşılacaktır. Bunu ayrıca Ayarlardan da düzenleyebilirsiniz.</string>
+    <string name="auth_add_phone_message_2">Telefon numarası kaydedin ve daha sonra isteğe bağlı olarak sizi tanıyan kişilerin sizi bulabilmesini sağlayın.</string>
+    <string name="auth_add_email_phone_message_2">Hesap kurtarma epostası kaydedin. Daha sonra isteğe bağlı eposta veya telefon nuraması kullanarak sizi tanıyan kişilerin sizi bulabilmesini sağlayın.</string>
+    <string name="auth_add_email_and_phone_message_2">Hesap kurtarma epostası kaydedin. Daha sonra isteğe bağlı eposta veya telefon nuraması kullanarak sizi tanıyan kişilerin sizi bulabilmesini sağlayın.</string>
+    <string name="login_error_ssl_handshake">Cihazın saldırılara açık, eski bir TLS güvenlik protokolü kullanıyor; güvenliğin için bağlantın engellendi</string>
+    <string name="settings_call_ringtone_use_default_stun">İkincil çağrı yardımcı sunucusuna izin ver</string>
+    <string name="settings_call_ringtone_use_default_stun_sum">Anasunucunuz çağrı yardımcı sunucusu vermez ise %s çağrı yardımcı sunucusu olarak kullanılacaktır (Çağrıda IP adresiniz paylaşılacaktır)</string>
+    <string name="invite_no_identity_server_error">Bu eylemi gerçekleştirebilmek için ayarlarınızdan bir kimlik sunucusu ekleyin.</string>
+    <string name="settings_add_3pid_confirm_password_title">Şifreni doğrula</string>
+    <string name="settings_background_fdroid_sync_mode_battery_description">Riot, cihazın sınırlı kaynaklarını (pil) koruyacak şekilde arka planda senkronize olur.
+\nCihazınızın kaynak durumuna bağlı olarak, senkronizasyon işletim sistemi tarafından ertelenebilir.</string>
+    <string name="settings_background_fdroid_sync_mode_real_time">Gerçek zamanlı için optimize</string>
+    <string name="settings_background_fdroid_sync_mode_real_time_description">Riot periyodik olarak belirli bir zamanda (ayarlanabilir) arka planda senkronize olur.
+\nBu pil ve radyo kullanımını etkileyecek ve riotun olayları dinlediğini belirten kalıcı bir bildirim gösterecektir.</string>
+    <string name="settings_background_fdroid_sync_mode_disabled">Arka plan senkronizasyonu yok</string>
+    <string name="settings_set_workmanager_delay">Tercih Edilen Senkronize Aralığı</string>
+    <string name="settings_set_workmanager_delay_summary">%s
+\nSenkronizasyon kaynağın (pil) yada cihazın durumuna (uyku) bağlı olarak değişebilir.</string>
+    <string name="settings_integrations">Entegrasyonlar</string>
+    <string name="settings_integrations_summary">Botları, köprüleri, widget\'ları ve etiket paketlerini yönetmek için bir entegrasyon yöneticisi kullanın.
+\nEntegrasyon yöneticileri yapılandırma verilerini alır ve widget\'ları değiştirebilir, oda davetlerini gönderebilir ve sizin adınıza yetki seviyelerini ayarlayabilir.</string>
+    <string name="settings_discovery_category">Keşif</string>
+    <string name="settings_discovery_manage">Keşif ayarlarını düzenle.</string>
+    <string name="settings_integration_allow">Entegrasyonlara izin ver</string>
+    <string name="settings_integration_manager">Entegre Yöneticisi</string>
+
+    <string name="settings_change_password_submit">Şifreyi güncelle</string>
+    <string name="settings_fail_to_update_password_invalid_current_password">Şifre geçersiz</string>
+    <string name="passwords_do_not_match">Şifreler uyuşmuyor</string>
+
+    <string name="settings_media">Medya</string>
+    <string name="settings_default_compression">Varsayılan sıkıştırma</string>
+    <string name="compression_opt_list_choose">Seç</string>
+    <string name="settings_default_media_source">Varsayılan medya kaynağı</string>
+    <string name="media_source_choose">Seç</string>
+    <string name="settings_play_shutter_sound">Deklanşör sesi çal</string>
+
+    <string name="encryption_information_device_name_with_warning">Görünür ad (iletişim kurduğunuz kişilere görünen)</string>
+    <string name="device_name_warning">Bir oturumun görünür adı iletişim kurduğunuz kişilere görünür</string>
+    <string name="encryption_information_unknown_ip">bilinmeyen ip</string>
+    <plurals name="notification_compat_summary_line_for_room">
+        <item quantity="one">%1$s: 1 mesaj</item>
+        <item quantity="other">%1$s: %2$d tane mesaj</item>
+    </plurals>
+    <plurals name="notification_compat_summary_title">
+        <item quantity="one">%d bildirim</item>
+        <item quantity="other">%d tane bildirim</item>
+    </plurals>
+
+    <string name="notification_unknown_new_event">Yeni Etkinlik</string>
+    <string name="notification_unknown_room_name">Oda</string>
+    <string name="notification_new_messages">Yeni Mesajlar</string>
+    <string name="notification_new_invitation">Yeni Davet</string>
+    <string name="notification_sender_me">Ben</string>
+    <string name="notification_inline_reply_failed">** Görderme başarısız - lütfen alan aç</string>
+
+    <string name="room_widget_activity_title">Widget</string>
+    <string name="room_widget_permission_title">Widget Yükle</string>
+    <string name="room_widget_permission_added_by">Bu widget\'ı ekleyen:</string>
+    <string name="room_widget_permission_webview_shared_info_title">Bunu kullanmak çerezler oluşturabilir ve %s ile veri paylaşabilir:</string>
+    <string name="room_widget_permission_shared_info_title">Bunu kullanmak %s ile veri paylaşabilir:</string>
+    <string name="room_widget_failed_to_load">Widget yüklenemedi.
+\n%s</string>
+    <string name="room_widget_reload">Widget\'ı yenile</string>
+    <string name="room_widget_open_in_browser">Tarayıcıda Aç</string>
+    <string name="room_widget_revoke_access">Benim için erişimi iptal et</string>
+
+    <string name="room_widget_permission_display_name">Görünür adın</string>
+    <string name="room_widget_permission_avatar_url">Avatarının URL\'si</string>
+    <string name="room_widget_permission_user_id">Kullanıcı kimliğin</string>
+    <string name="room_widget_permission_theme">Teman</string>
+    <string name="room_widget_permission_widget_id">Widget kimliği</string>
+    <string name="room_widget_permission_room_id">Oda kimliği</string>
+
+
+    <string name="error_jitsi_not_supported_on_old_device">Üzgünüz, jitsi konferans aramaları eski cihazlarda desteklenmiyor (Android 5.0 altı)</string>
+    <string name="room_widget_resource_permission_title">Bu widget şu kaynakları kullanmak istiyor:</string>
+    <string name="room_widget_resource_grant_permission">İzin ver</string>
+    <string name="room_widget_resource_decline_permission">Hepsini reddet</string>
+    <string name="room_widget_webview_access_camera">Kamera kullan</string>
+    <string name="room_widget_webview_access_microphone">Mikrofon kullan</string>
+    <string name="room_widget_webview_read_protected_media">DRM korumalı içerik oynat</string>
+
+    <string name="integration_manager_not_configured">Hiçbir entegrasyon düzenleyicisi yapılandırılmamış.</string>
+    <string name="widget_integration_review_terms">Devam etmek için Hizmet Şartlarını kabul etmeniz gerekir.</string>
+
+    <string name="you_added_a_new_device_with_info">Yeni oturum şifreleme anahtarlarını talep ediyor. Oturum adı: %1$s
+\nSon görülme: %2$s
+\nEğer farklı bir oturumda giriş yapmadıysanız bu talebi reddedin.</string>
+    <string name="your_unverified_device_requesting_with_info">Bir doğrulanmamış oturum şifreleme anahtarlarını talep ediyor.
+\nOturum adı: %1$s
+\nSon görülme: %2$s
+\nEğer farklı bir oturumda giriş yapmadıysanız bu talebi reddedin.</string>
+
+    <string name="start_verification_short_label">Doğrula</string>
+    <string name="share_without_verifying_short_label">Paylaş</string>
+    <string name="key_share_request">Anahtar Paylaşma Talebi</string>
+    <string name="ignore_request_short_label">Reddet</string>
+
+    <string name="keys_backup_setup_override_backup_prompt_tile">Ana sunucunuzda bir yedek zaten var</string>
+    <string name="keys_backup_setup_override_backup_prompt_description">Başka bir oturumda zaten kurum anahtarı yapmışsın gibi görünüyor. Bunları şu anki oluşturulanlar ile değiştirmek ister misin\?</string>
+    <string name="keys_backup_setup_override_replace">Değiştir</string>
+    <string name="keys_backup_setup_override_stop">Dur</string>
+
+    <string name="keys_backup_settings_checking_backup_state">Yedek durumu kontrol ediliyor</string>
+    <string name="autodiscover_invalid_response">Geçersiz anasunucu keşif cevabı</string>
+    <string name="autodiscover_well_known_autofill_dialog_title">Sunucu Ayarlarını Otomatik Doldur</string>
+    <string name="autodiscover_well_known_autofill_dialog_message">Riot userld alan adı için özel sunucu yapılandırması buldu \"%1$s\":
+\n%2$s</string>
+    <string name="autodiscover_well_known_autofill_confirm">Yapılandırmayı kullan</string>
+
+    <string name="invalid_or_expired_credentials">Geçersiz ya da süresi dolmuş girdilerden dolayı çıkış yaptınız.</string>
+
+    <string name="sas_verify_title">Kısa metin dizinisi karşılaştırarak doğrulayın.</string>
+    <string name="sas_security_advise">Yüksek güvenlik için bunu yüz yüze ya da farklı güvenilir iletişim yolu kullanarak yapmanızı tavsiye ederiz.</string>
+    <string name="sas_verify_start_button_title">Doğrulamaya Başla</string>
+    <string name="sas_incoming_request_title">Gelen Doğrulama Talebi</string>
+    <string name="sas_incoming_request_description">Güvenilir olarak işaretlemek için bu oturumu doğrulayın. Partnerlerin oturumlarına güvenmek, uçtan uca şifreli mesajlar kullanırken size ekstra huzur verir.</string>
+    <string name="sas_incoming_request_description_2">Bu oturumun doğrulanmak oturumu kendinizde ve ayrıca partnerinizde güvenilir olarak işaretleyecektir.</string>
+
+    <string name="sas_emoji_description">Partnerinizin ekranında aşağıdaki emojinin göründüğünü onaylayarak bu oturumu doğrulayın</string>
+    <string name="sas_decimal_description">Partnerinizin ekranında aşağıdaki sayıların göründüğünü onaylayarak bu oturumu doğrulayın</string>
+
+    <string name="sas_incoming_verification_request_dialog">Gelen bir doğrulama talebi aldın.</string>
+    <string name="sas_view_request_action">Talebi görüntüle</string>
+    <string name="sas_waiting_for_partner">Partnerinizin kabul etmesi bekleniyor…</string>
+
+    <string name="sas_verified">Doğrulandı!</string>
+    <string name="sas_verified_successful">Bu oturumu başarıyla doğruladın.</string>
+    <string name="sas_verified_successful_description">Bu kullanıcı ile güvenli mesajlar uçtan uca şifrelenir ve üçüncü şahıslar tarafından okunamaz.</string>
+    <string name="sas_got_it">Anlaşıldı</string>
+
+    <string name="sas_verifying_keys">Hiçbir şey gözükmüyor mu\? Şimdilik bütün platformlar interaktif doğrulamayı desteklemiyor. Eski doğrulamayı kullanın.</string>
+    <string name="sas_legacy_verification_button_title">Eski doğrulama yöntemini kullan.</string>
+
+    <string name="sas_verification_request_notification_channel_title">Anahtar Doğrulaması</string>
+    <string name="sas_cancelled_dialog_title">Talep İptal edildi</string>
+    <string name="sas_cancelled_by_other">Diğer grup doğrulamayı iptal etti.
+\n%s</string>
+    <string name="sas_cancelled_by_me">Doğrulama iptal edildi.
+\nSebep: %s</string>
+
+    <string name="sas_verification_request_notification_channel">Etkileşimli Oturum Doğrulama</string>
+    <string name="sas_incoming_request_notif_title">Doğrulama Talebi</string>
+    <string name="sas_incoming_request_notif_content">%s oturumunu doğrulamak istiyor</string>
+
+    <string name="sas_error_m_user">Kullanıcı doğrulamayı iptal etti</string>
+    <string name="sas_error_m_timeout">Doğrulama işlemi zaman aşımına uğradı</string>
+    <string name="sas_error_m_unknown_transaction">Oturum bu işlemi bilmiyor</string>
+    <string name="sas_error_m_unknown_method">Oturum anahtar anlaşması, hash, MAC, yada SAS yöntemi üzerinde anlaşamaz</string>
+    <string name="sas_error_m_mismatched_commitment">Hash tahaddütü eşleşmedi</string>
+    <string name="sas_error_m_mismatched_sas">SAS eşleşmedi</string>
+    <string name="sas_error_m_unexpected_message">Oturum beklenmeyen bir mesaj aldı</string>
+    <string name="sas_error_m_invalid_message">Geçersiz bir mesaj alındı</string>
+    <string name="sas_error_m_key_mismatch">Anahtar uyuşmazlığı</string>
+    <string name="sas_error_m_user_error">Kullanıcı uyuşmazlığı</string>
+    <string name="sas_error_unknown">Bilinmeyen Hata</string>
+
+    <string name="identity_server_not_defined">Herhangi bir kimlik sunucusu kullanmıyorsunuz</string>
+    <string name="identity_server_not_defined_for_password_reset">Hiçbir kimlik sunucusu yapılandırılmamış, bu şifrenizi değiştirebilmeniz için gerekli.</string>
+
+    <string name="security_warning_identity_server">Riot\'un önceki sürümlerinde, kimlik sunucunuzun (%1$s) hesabınıza erişebilmesini sağlayan bir güvenlik hatası vardı. %2$s sunucusuna güveniyorsanız, bunu göz ardı edebilirsiniz; aksi takdirde lütfen çıkış yapın ve tekrar giriş yapın.
+\n
+\nDaha fazla ayrıntıya buradan bakabilirsiniz:
+\nhttps://medium.com/@RiotChat/36b4792ea0d6</string>
+
+    <string name="error_user_already_logged_in">Başka bir anasunucuya bağlanmaya çalışıyorsunuz gibi görünüyor. Çıkış yapmak ister misiniz\?</string>
+
+    <string name="edit">Düzenle</string>
+    <string name="reply">Yanıtla</string>
+
+    <string name="global_retry">Tekrar dene</string>
+    <string name="room_list_empty">Uygulamayı kullanmaya başlamak için bir odaya katıl.</string>
+    <string name="send_you_invite">Sana bir davet gönderdi</string>
+    <string name="invited_by">%s seni davet etti</string>
+
+    <string name="room_list_catchup_empty_title">Her şey tamam!</string>
+    <string name="room_list_catchup_empty_body">Hiç okunmamış mesajınız bulunmuyor</string>
+    <string name="room_list_catchup_welcome_title">Eve hoşgeldiniz!</string>
+    <string name="room_list_catchup_welcome_body">Okunmamış mesajları burada bulursun</string>
+    <string name="room_list_people_empty_title">Tartışmalar</string>
+    <string name="room_list_people_empty_body">Doğrudan mesajların burada görünecek</string>
+    <string name="room_list_rooms_empty_title">Odalar</string>
+    <string name="room_list_rooms_empty_body">Odalar burada görünecek</string>
+
+    <string name="title_activity_emoji_reaction_picker">Tepkiler</string>
+    <string name="reactions_agree">Bencede</string>
+    <string name="reactions_like">Beğendim</string>
+    <string name="message_add_reaction">Bir Tepki Ekle</string>
+    <string name="message_view_reaction">Tekpileri Görüntüle</string>
+    <string name="reactions">Tepkiler</string>
+
+    <string name="event_redacted_by_user_reason">Etkinlik kullanıcı tarafından silindi</string>
+    <string name="event_redacted_by_admin_reason">Etkinlik oda yöneticisi tarafından yönetildi</string>
+    <string name="last_edited_info_message">%2$s tarihinde %1$s tarafından düzenlendi</string>
+
+
+    <string name="malformed_message">Hatalı etkinlik, görüntülenemiyor</string>
+    <string name="create_new_room">Yeni Oda Oluştur</string>
+    <string name="error_no_network">Internet yok. Lütfen internet bağlantını kontrol et.</string>
+    <string name="action_change">Değiştir</string>
+    <string name="change_room_directory_network">Ağı değiştir</string>
+    <string name="please_wait">Lütfen bekleyin…</string>
+    <string name="group_all_communities">Tüm Topluluklar</string>
+
+    <string name="room_preview_no_preview">Bu oda önizlenemez</string>
+    <string name="room_preview_world_readable_room_not_supported_yet">RiotX henüz herkese-açık odaları önizlemeyi desteklemiyor</string>
+
+    <string name="fab_menu_create_room">Odalar</string>
+    <string name="fab_menu_create_chat">Doğrudan Mesajlar</string>
+
+    <string name="create_room_title">Yeni Oda</string>
+    <string name="create_room_action_create">OLUŞTUR</string>
+    <string name="create_room_name_hint">Oda Adı</string>
+    <string name="create_room_public_title">Herkese Açık</string>
+    <string name="create_room_public_description">Herkes bu odaya katılabilir</string>
+    <string name="create_room_directory_title">Oda Dizini</string>
+    <string name="create_room_directory_description">Bu odayı oda dizininde yayınla</string>
+
+    <string name="keys_backup_unable_to_get_trust_info">Güven bilgisi alınırken hata oluştu</string>
+    <string name="keys_backup_unable_to_get_keys_backup_data">Anahtar yedek verileri alınırken hata oluştu</string>
+
+    <string name="alpha_disclaimer_title">Betaya hoşgeldiniz!</string>
+    <string name="alpha_disclaimer_content_line_1">RiotX geliştirme sürecindeyken bazı özellikler eksik olabilir ve hatalar ile karşılaşabilirsiniz.</string>
+    <string name="login_error_no_homeserver_found">Bu geçerli bir Matrix sunucu adresi değil</string>
+    <string name="login_error_homeserver_not_found">Bu URL ile ev-sunucusuna erişilemiyor, lütfen kontrol edin</string>
+    <string name="settings_add_3pid_flow_not_supported">Bunu Riot mobil ile yapamazsınız</string>
+    <string name="settings_add_3pid_authentication_needed">Kimlik doğrulama gereklidir</string>
+
+
+    <string name="settings_background_fdroid_sync_mode">Arkaplan Senkronizasyon Modu (Deneysel)</string>
+    <string name="settings_background_fdroid_sync_mode_battery">Batarya için optimize edildi</string>
+    <string name="settings_background_fdroid_sync_mode_disabled_description">Uygulama arka plandayken gelen mesajlar için uyarılmayacaksınız.</string>
+    <string name="settings_background_sync_update_error">Ayarlar güncellenemedi.</string>
+
+
 </resources>
diff --git a/vector/src/main/res/values-zh-rCN/strings.xml b/vector/src/main/res/values-zh-rCN/strings.xml
index ea1506ca99..6f6d809624 100644
--- a/vector/src/main/res/values-zh-rCN/strings.xml
+++ b/vector/src/main/res/values-zh-rCN/strings.xml
@@ -191,7 +191,7 @@
     <string name="cannot_start_call">无法开始通话,请稍后重试</string>
     <string name="missing_permissions_warning">由于缺少权限,某些功能将无法使用…</string>
     <string name="missing_permissions_title_to_start_conf_call">无法发起通话</string>
-    <string name="device_information">设备信息</string>
+    <string name="device_information">会话信息</string>
     <string name="room_no_conference_call_in_encrypted_rooms">加密的聊天室不支持电话会议</string>
     <string name="action_open">打开</string>
     <string name="action_close">关闭</string>
@@ -1373,7 +1373,7 @@ Riot 在后台时的工作将被显著的限制,这可能会影响消息通知
 
     <string name="error_jitsi_not_supported_on_old_device">抱歉,旧设备 (Android 系统版本低于 5.0)不支持使用 Jitsi 创建电话会议</string>
 
-    <string name="title_activity_verify_device">验证设备</string>
+    <string name="title_activity_verify_device">验证会话</string>
 
     <string name="encryption_information_unknown_ip">未知 IP</string>
     <string name="you_added_a_new_device_with_info">一个新设备正在请求加密密钥。
@@ -1480,4 +1480,19 @@ Riot 在后台时的工作将被显著的限制,这可能会影响消息通知
     <string name="people_no_identity_server">没有设置身份服务器。</string>
 
     <string name="call_failed_no_ice_title">服务器的错误配置导致通话失败</string>
+    <string name="resources_script">Latn</string>
+
+    <string name="call_failed_no_ice_description">请要求您的家庭服务器(%1$s)的管理员配置TURN服务器,以使通话可靠地工作。
+\n
+\n 或者,您可以尝试使用%2$s的公共服务器,但这将不那么可靠,并且它将与该服务器共享您的IP地址。 您也可以在“设置”中进行管理。</string>
+    <string name="call_failed_no_ice_use_alt">尝试使用 %s</string>
+    <string name="call_failed_dont_ask_again">不要再问我</string>
+
+    <string name="auth_add_email_message_2">设置用于帐户恢复的电子邮件,然后就可以让认识您的人选择性探索到您。</string>
+    <string name="auth_add_phone_message_2">设定电话,然后就可以让认识您的人选择性探索到您。</string>
+    <string name="auth_add_email_phone_message_2">设定电子邮件以供帐号复原。 然后就可以让认识您的人用电子邮件或电话选择性探索到您。</string>
+    <string name="auth_add_email_and_phone_message_2">设定电子邮件以供帐号复原。 然后就可以让认识您的人用电子邮件或电话选择性探索到您。</string>
+    <string name="login_error_no_homeserver_found">這不是有效的 Matrix 服务器位置</string>
+    <string name="login_error_homeserver_not_found">无法在此 URL 找到家庭服务器,请检查</string>
+    <string name="settings_call_ringtone_use_default_stun">允许后备呼叫协助服务器</string>
 </resources>
diff --git a/vector/src/main/res/values-zh-rTW/strings.xml b/vector/src/main/res/values-zh-rTW/strings.xml
index 111ee26b36..2bc18012c2 100644
--- a/vector/src/main/res/values-zh-rTW/strings.xml
+++ b/vector/src/main/res/values-zh-rTW/strings.xml
@@ -218,7 +218,7 @@
 
     <string name="groups_list">群組清單</string>
 
-    <string name="compression_options">"傳送為 "</string>
+    <string name="compression_options">傳送為</string>
     <string name="compression_opt_list_original">原始</string>
     <string name="compression_opt_list_large">大</string>
     <string name="compression_opt_list_medium">中</string>
@@ -258,13 +258,13 @@
 
 請在下個彈跳視窗允許存取,來從手機傳送檔案。</string>
     <string name="permissions_rationale_msg_camera">Riot 需要權限存取您的相機,來拍照與視訊通話。</string>
-    <string name="permissions_rationale_msg_camera_explanation">
-
-為了要通話,請在下個彈跳視窗中允許存取。</string>
+    <string name="permissions_rationale_msg_camera_explanation">"
+\n
+\n為了要通話,請在下個彈跳視窗中允許存取。"</string>
     <string name="permissions_rationale_msg_record_audio">Riot 需要權限來存取麥克風,來撥打語音通話。</string>
-    <string name="permissions_rationale_msg_record_audio_explanation">
-
-為了要通話,請在下個彈跳視窗中允許存取。</string>
+    <string name="permissions_rationale_msg_record_audio_explanation">"
+\n
+\n為了要通話,請在下個彈跳視窗中允許存取。"</string>
     <string name="permissions_rationale_msg_camera_and_audio">Riot 需要權限來存取相機及麥克風來撥打視訊通話。
 
 為了要通話,請在下個彈跳視窗中允許存取。</string>
@@ -398,7 +398,7 @@
     <string name="go_on_with">使用…打開</string>
     <string name="error_no_external_application_found">對不起,沒有應用程式可以完成此操作。</string>
 
-    <string name="e2e_re_request_encryption_key">從其他工作階段<u>重新請求金鑰</u>。</string>
+    <string name="e2e_re_request_encryption_key">從其他工作階段重新請求金鑰。<u>重新請求金鑰</u>。</string>
 
     <string name="e2e_re_request_encryption_key_sent">已發送金鑰分享請求。</string>
 
@@ -736,8 +736,8 @@
     <string name="encryption_information_unblock">解除黑名單</string>
 
     <string name="encryption_information_verify_device">驗證工作階段</string>
-    <string name="encryption_information_verify_device_warning">要驗證此工作階段是否可信,請使用其他方式(例如:面對面或是打電話)聯絡它的擁有者並詢問他們在使用者設定中看到此工作階段的金鑰是否與下列的金鑰相符:</string>
-    <string name="encryption_information_verify_device_warning2">如果符合的話,請按下方的驗證按鈕。如果沒有的話,那麼其他地方的某個人可能正在攔截此工作階段,您應該將其列入黑名單。未來,這個驗證程序會變得更加複雜。</string>
+    <string name="encryption_information_verify_device_warning">透過將以下內容與您的其他工作階段中的使用者設定來確認:</string>
+    <string name="encryption_information_verify_device_warning2">如果不符合的話,您的通訊安全可能正受到威脅。</string>
     <string name="encryption_information_verify_key_match">我驗證金鑰相符</string>
 
     <string name="e2e_enabling_on_app_update">Riot 目前支援端到端加密,但您需要重新登入以啟用。
@@ -915,7 +915,7 @@ Matrix 中的消息可見度類似于電子郵件。我們忘記您的郵件意
     <string name="room_participants_now">目前 %1$s</string>
     <string name="room_participants_ago">%1$s %2$s 前</string>
 
-    <string name="room_participants_invite_join_names">%1$s,</string>
+    <string name="room_participants_invite_join_names">"%1$s, "</string>
     <string name="room_participants_invite_join_names_and">%1$s 與 %2$s</string>
     <string name="room_participants_invite_join_names_combined">%1$s %2$s</string>
 
@@ -1276,7 +1276,7 @@ Matrix 中的消息可見度類似于電子郵件。我們忘記您的郵件意
     <string name="keys_backup_banner_recover_line1">永遠不失去加密訊息</string>
     <string name="keys_backup_banner_recover_line2">使用金鑰備份</string>
 
-    <string name="keys_backup_banner_update_line1">新加密訊息金鑰</string>
+    <string name="keys_backup_banner_update_line1">新安全訊息金鑰</string>
     <string name="keys_backup_banner_update_line2">管理金鑰備份</string>
 
     <string name="keys_backup_banner_in_progress">正在備份金鑰……</string>
@@ -2033,8 +2033,8 @@ Matrix 中的消息可見度類似于電子郵件。我們忘記您的郵件意
 
     <string name="room_member_jump_to_read_receipt">跳至讀取回條</string>
 
-    <string name="rendering_event_error_type_of_event_not_handled">RiotX 尚無法處理類型為「%1$s」的事件</string>
-    <string name="rendering_event_error_type_of_message_not_handled">RiotX 尚無法處理類型為「%1$s」的訊息</string>
+    <string name="rendering_event_error_type_of_event_not_handled">RiotX 無法處理類型為「%1$s」的事件</string>
+    <string name="rendering_event_error_type_of_message_not_handled">RiotX 無法處理類型為「%1$s」的訊息</string>
     <string name="rendering_event_error_exception">在彩現 id「%1$s」事件的內容時,RiotX 遇到問題</string>
 
     <string name="unignore">取消忽略</string>
@@ -2093,11 +2093,11 @@ Matrix 中的消息可見度類似于電子郵件。我們忘記您的郵件意
         <item quantity="other">%d 活躍的工作階段</item>
     </plurals>
 
-    <string name="crosssigning_verify_this_session">驗證此工作階段</string>
+    <string name="crosssigning_verify_this_session">驗證此登入</string>
     <string name="crosssigning_other_user_not_trust">其他使用者可能不會信任它</string>
     <string name="complete_security">全面的安全性</string>
 
-    <string name="verification_open_other_to_verify">開啟既有的工作階段並使用它來驗證這個,讓它可以存取已加密的訊息。如果您無法存取,請使用您的復原金鑰或通關密語。</string>
+    <string name="verification_open_other_to_verify">使用既有的工作階段來驗證這個,讓它可以存取已加密的訊息。</string>
 
 
     <string name="verification_profile_verify">驗證</string>
@@ -2119,8 +2119,220 @@ Matrix 中的消息可見度類似于電子郵件。我們忘記您的郵件意
 
     <string name="a11y_qr_code_for_verification">QR code</string>
 
+    <string name="qr_code_scanned_by_other_notice">就快完成了!%s 有顯示相同的盾牌嗎?</string>
     <string name="qr_code_scanned_by_other_yes">是</string>
     <string name="qr_code_scanned_by_other_no">否</string>
 
     <string name="no_connectivity_to_the_server_indicator">到伺服器的連線已遺失</string>
+    <string name="login_signup_username_hint">使用者名稱</string>
+    <string name="settings_dev_tools">開發者工具</string>
+    <string name="settings_account_data">帳號資料</string>
+    <plurals name="poll_info">
+        <item quantity="other">%d 投票</item>
+    </plurals>
+    <plurals name="poll_info_final">
+        <item quantity="other">%d 投票 - 最後結果</item>
+    </plurals>
+    <string name="poll_item_selected_aria">已選取的選項</string>
+    <string name="command_description_poll">建立簡易投票</string>
+    <string name="verification_cannot_access_other_session">使用復原通關密語或金鑰</string>
+    <string name="verification_use_passphrase">如果您無法存取既有的工作階段的話</string>
+
+    <string name="new_signin">新登入</string>
+
+    <string name="enter_secret_storage_invalid">在儲存空間中找不到秘密</string>
+    <string name="enter_secret_storage_passphrase">輸入秘密儲存空間通關密語</string>
+    <string name="enter_secret_storage_passphrase_warning">警告:</string>
+    <string name="enter_secret_storage_passphrase_warning_text">您僅能從受信任的裝置存取秘密儲存空間</string>
+
+    <string name="message_action_item_redact">移除……</string>
+    <string name="share_confirm_room">您想要傳送此附件到 %1$s 嗎?</string>
+    <plurals name="send_images_with_original_size">
+        <item quantity="other">使用原始大小傳送圖片</item>
+    </plurals>
+
+    <string name="delete_event_dialog_title">確認移除</string>
+    <string name="delete_event_dialog_content">您確定您想要移除(刪除)此活動嗎?注意,如果您刪除聊天室名稱或變更主題,則可能會撤銷變更。</string>
+    <string name="delete_event_dialog_reason_checkbox">包含理由</string>
+    <string name="delete_event_dialog_reason_hint">修改原因</string>
+
+    <string name="event_redacted_by_user_reason_with_reason">被使用者刪除的活動,理由:%1$s</string>
+    <string name="event_redacted_by_admin_reason_with_reason">由聊天室管理員管理的活動,理由:%1$s</string>
+
+    <string name="keys_backup_restore_success_title_already_up_to_date">金鑰已為最新!</string>
+
+    <string name="login_mobile_device_riotx">RiotX Android</string>
+
+    <string name="settings_key_requests">金鑰請求</string>
+
+    <string name="e2e_use_keybackup">解鎖已加密的訊息歷史</string>
+
+    <string name="refresh">重新整理</string>
+
+    <string name="new_session">新登入。是您嗎?</string>
+    <string name="new_session_review">輕觸即可以審閱並驗證</string>
+    <string name="verify_new_session_notice">使用此工作階段來驗證新的,讓它可以存取已加密的訊息。</string>
+    <string name="verify_new_session_was_not_me">這不是我</string>
+    <string name="verify_new_session_compromized">您的帳號可能已被盜用</string>
+
+    <string name="verify_cancel_self_verification_from_untrusted">如果您取消,您可能無法在此裝置上讀取已加密的訊息,而其他使用者也不會信任它</string>
+    <string name="verify_cancel_self_verification_from_trusted">如果您取消,您可能無法在您新的裝置上讀取已加密的訊息,而其他使用者也不會信任它</string>
+    <string name="verify_cancel_other">如果您現在取消,您將無法驗證 %1$s (%2$s)。在他們的使用者檔案中重新開始。</string>
+
+    <string name="verify_not_me_self_verification">下列其中一項可能已被盜用:
+\n
+\n- 您的密碼
+\n- 您的家伺服器
+\n- 此裝置或其他裝置
+\n- 任一裝置正在使用的網際網路連線
+\n
+\n我們建議您立刻在設定中變更您的密碼與復原金鑰。</string>
+
+    <string name="verify_cancelled_notice">透過設定驗證您的裝置。</string>
+    <string name="verification_cancelled">驗證已取消</string>
+
+    <string name="recovery_passphrase">復原通關密語</string>
+    <string name="message_key">訊息金鑰</string>
+    <string name="account_password">帳號密碼</string>
+
+    <string name="set_recovery_passphrase">設定 %s</string>
+    <string name="generate_message_key">生成訊息金鑰</string>
+
+    <string name="confirm_recovery_passphrase">確認 %s</string>
+
+    <string name="enter_account_password">輸入您的 %s 以繼續。</string>
+
+    <string name="bootstrap_info_text">保護與解鎖已加密的訊息並信任 %s。</string>
+    <string name="bootstrap_info_confirm_text">再次輸入您的 %s 以確認。</string>
+    <string name="bootstrap_dont_reuse_pwd">不要重用您的帳號密碼。</string>
+
+
+    <string name="bootstrap_loading_text">這可能需要數秒,請稍候。</string>
+    <string name="bootstrap_loading_title">設定復原。</string>
+    <string name="your_recovery_key">您的復原金鑰</string>
+    <string name="bootstrap_finish_title">已完成!</string>
+    <string name="keep_it_safe">把它放在安全的地方</string>
+    <string name="finish">完成</string>
+
+    <string name="bootstrap_save_key_description">使用這個 %1$s 做為安全網以避免您忘記您的 %2$s。</string>
+
+    <string name="bootstrap_crosssigning_progress_initializing">正在發佈已建立的識別金鑰</string>
+    <string name="bootstrap_crosssigning_progress_pbkdf2">正在從通關密語生成安全金鑰</string>
+    <string name="bootstrap_crosssigning_progress_default_key">正在定義 SSSS 預設金鑰</string>
+    <string name="bootstrap_crosssigning_progress_save_msk">正在同步主控金鑰</string>
+    <string name="bootstrap_crosssigning_progress_save_usk">正在同步使用者金鑰</string>
+    <string name="bootstrap_crosssigning_progress_save_ssk">正在同步自行簽署金鑰</string>
+    <string name="bootstrap_crosssigning_progress_key_backup">設定金鑰備份</string>
+
+
+    <string name="bootstrap_cross_signing_success">您的 %2$s 與 %1$s 設定好了。
+\n
+\n請保護它們的安全!如果您遺失所有作用中的工作階段,您將會需要它們來解鎖已加密的訊息並保護資訊。</string>
+
+    <string name="bootstrap_crosssigning_print_it">列印並將其存放在安全的地方</string>
+    <string name="bootstrap_crosssigning_save_usb">將其儲存在 USB 隨身碟或備份磁碟上</string>
+    <string name="bootstrap_crosssigning_save_cloud">將其複製到您的私人雲端儲存空間</string>
+
+    <string name="auth_flow_not_supported">您不能從行動裝置上做這件事</string>
+
+    <string name="bootstrap_skip_text">設定訊息密碼可讓您保護並解鎖已加密的訊息並信任。
+\n
+\n如果您不想要設定訊息密碼,請生成訊息金鑰來代替。</string>
+    <string name="bootstrap_skip_text_no_gen_key">設定復原通關密語可讓您保護並解鎖已加密的訊息並信任。</string>
+
+
+    <string name="encryption_enabled">加密已啟用</string>
+    <string name="encryption_enabled_tile_description">在此聊天室中的訊息已端到端加密。取得更多資訊並在使用者的個人檔案中驗證他們。</string>
+    <string name="encryption_not_enabled">加密未啟用</string>
+    <string name="encryption_unknown_algorithm_tile_description">用於此聊天室的加密未受支援</string>
+
+    <string name="room_created_summary_item">%s 建立並設定聊天室。</string>
+
+    <string name="qr_code_scanned_self_verif_notice">就快完成了!其他裝置有顯示相同的盾牌嗎?</string>
+    <string name="qr_code_scanned_verif_waiting_notice">就快完成了!正在等待確認……</string>
+    <string name="qr_code_scanned_verif_waiting">正在等待 %s……</string>
+
+    <string name="error_failed_to_import_keys">匯入金鑰失敗</string>
+
+    <string name="settings_notification_configuration">通知設定</string>
+    <string name="settings_messages_at_room">訊息包含 @room</string>
+    <string name="settings_messages_in_e2e_one_to_one">在一對一的聊天中已加密的訊息</string>
+    <string name="settings_messages_in_e2e_group_chat">群組聊天中的已加密訊息</string>
+    <string name="settings_when_rooms_are_upgraded">當聊天室升級時</string>
+    <string name="settings_troubleshoot_title">疑難排解</string>
+    <string name="settings_notification_advanced_summary_riotx">按事件設定通知重要性</string>
+
+    <string name="command_description_plain">傳送純文字訊息,不將它們解譯為 markdown</string>
+
+    <string name="auth_invalid_login_param_space_in_password">不正確的使用者名稱及/或密碼。輸入的密碼以空格開頭或結尾,請檢查。</string>
+
+    <string name="room_message_placeholder">訊息……</string>
+
+    <string name="upgrade_security">提供加密升級</string>
+    <string name="security_prompt_text">驗證您自己與其他人以保證聊天安全</string>
+
+    <string name="bootstrap_enter_recovery">輸入您的 %s 以繼續</string>
+    <string name="use_file">使用檔案</string>
+
+    <string name="enter_backup_passphrase">輸入 %s</string>
+    <string name="backup_recovery_passphrase">復源通關密語</string>
+    <string name="bootstrap_invalid_recovery_key">這不是有效的復原金鑰</string>
+    <string name="recovery_key_empty_error_message">請輸入復原金鑰</string>
+
+    <string name="bootstrap_progress_checking_backup">正在檢查備份金鑰</string>
+    <string name="bootstrap_progress_checking_backup_with_info">正在檢查備份金鑰 (%s)</string>
+    <string name="bootstrap_progress_compute_curve_key">正在取得曲線金鑰</string>
+    <string name="bootstrap_progress_generating_ssss">正在從通關密語生成 SSSS 金鑰</string>
+    <string name="bootstrap_progress_generating_ssss_with_info">正在從通關密語生成 SSSS 金鑰 (%s)</string>
+    <string name="bootstrap_progress_generating_ssss_recovery">正在從復原金鑰生成 SSSS 金鑰</string>
+    <string name="bootstrap_progress_storing_in_sss">正在 SSSS 中儲存金鑰備份秘密</string>
+    <string name="new_session_review_with_info">%1$s (%2$s)</string>
+
+    <string name="bootstrap_migration_enter_backup_password">輸入您的金鑰備份通關密語以繼續。</string>
+    <string name="bootstrap_migration_use_recovery_key">使用您的金鑰備份復原金鑰</string>
+    <string name="bootstrap_migration_with_passphrase_helper_with_link">不知道您的金鑰備份通關密語,您可以 %s。</string>
+    <string name="bootstrap_migration_backup_recovery_key">金鑰備份復原金鑰</string>
+
+    <string name="settings_security_prevent_screenshots_title">避免對應用程式進行螢幕截圖</string>
+    <string name="settings_security_prevent_screenshots_summary">啟用此設定會新增 FLAG_SECURE 到所有活動。重新啟動應用程式以讓變動生效。</string>
+
+    <string name="media_file_added_to_gallery">媒體檔案已新增至媒體庫中</string>
+    <string name="error_adding_media_file_to_gallery">無法新增媒體檔案到媒體庫中</string>
+    <string name="change_password_summary">設定新的帳號密碼……</string>
+
+    <string name="use_other_session_content_description">在您的其他裝置上使用最新的 Riot、Riot Web、Riot 桌面版、Riot iOS、RiotX for Android 或其他有交叉簽章功能的 Matrix 客戶端</string>
+    <string name="riot_desktop_web">Riot Web
+\nRiot 桌面版</string>
+    <string name="riot_ios_android">Riot iOS
+\nRiot X for Android</string>
+    <string name="or_other_mx_capabale_client">或其他有交叉簽章功能的 Matrix 客戶端</string>
+    <string name="use_latest_riot">在您的其他裝置上使用最新的 Riot:</string>
+    <string name="command_description_discard_session">強制丟棄目前在加密聊天室中的外發群組工作階段</string>
+    <string name="command_description_discard_session_not_handled">僅在加密聊天室中支援</string>
+    <string name="enter_secret_storage_passphrase_or_key">使用您的 %1$s 或使用您的 %2$s 以繼續。</string>
+    <string name="use_recovery_key">使用復原金鑰</string>
+    <string name="enter_secret_storage_input_key">選取您的復原金鑰,或是透過打字或從您的剪貼簿貼上來手動輸入</string>
+    <string name="keys_backup_recovery_key_error_decrypt">無法使用此復原金鑰解密備份:請驗證您是否輸入了正確的復原金鑰。</string>
+    <string name="failed_to_access_secure_storage">存取安全儲存空間失敗</string>
+
+    <string name="cross_signing_verify_by_text">透過文字手動驗證</string>
+    <string name="crosssigning_verify_session">驗證登入</string>
+    <string name="cross_signing_verify_by_emoji">透過顏文字來進行互動驗證</string>
+    <string name="confirm_your_identity">從您的其他工作階段驗證此登入以確認您的身份並授予存取加密訊息的權限。</string>
+    <string name="mark_as_verified">標記為受信任</string>
+
+    <string name="error_empty_field_choose_user_name">請選擇使用者名稱。</string>
+    <string name="error_empty_field_choose_password">請選擇密碼。</string>
+    <string name="external_link_confirmation_title">仔細檢查此連結</string>
+    <string name="external_link_confirmation_message">連結 %1$s 正在將您帶往其他網站:%2$s。
+\n
+\n您確定您想要繼續嗎?</string>
+
+    <string name="create_room_dm_failure">我們無法建立您的直接訊息。請檢查您想要邀請的使用者,然後再試一次。</string>
+    <string name="unencrypted">未加密</string>
+    <string name="encrypted_unverified">由未驗證的裝置加密</string>
+    <string name="review_logins">審閱您從何處登入</string>
+    <string name="verify_other_sessions">驗證您所有的工作階段以確保您的帳號與訊息都安全</string>
+    <string name="verify_this_session">驗證正在存取您帳號的新登入:%1$s</string>
+
 </resources>
diff --git a/vector/src/main/res/values/colors_riotx.xml b/vector/src/main/res/values/colors_riotx.xml
index 7c0e57be93..238fcbd6a2 100644
--- a/vector/src/main/res/values/colors_riotx.xml
+++ b/vector/src/main/res/values/colors_riotx.xml
@@ -99,6 +99,11 @@
     <color name="riotx_text_secondary_dark">#FFA1B2D1</color>
     <color name="riotx_text_secondary_black">#FFA1B2D1</color>
 
+    <attr name="riotx_text_primary_body_contrast" format="color" />
+    <color name="riotx_text_primary_body_contrast_light">#FF61708B</color>
+    <color name="riotx_text_primary_body_contrast_dark">#FFA1B2D1</color>
+    <color name="riotx_text_primary_body_contrast_black">#FFA1B2D1</color>
+
     <attr name="riotx_android_secondary" format="color" />
     <color name="riotx_android_secondary_light">#FF7E899C</color>
     <color name="riotx_android_secondary_dark">#FF7E899C</color>
diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml
index 9d20908b14..2c65918b67 100644
--- a/vector/src/main/res/values/strings.xml
+++ b/vector/src/main/res/values/strings.xml
@@ -287,7 +287,7 @@
     <string name="login_error_no_homeserver_found">This is not a valid Matrix server address</string>
     <string name="login_error_homeserver_not_found">Cannot reach a homeserver at this URL, please check it</string>
     <string name="login_error_ssl_handshake">Your device is using an outdated TLS security protocol, vulnerable to attack, for your security you will not be able to connect</string>
-    <string name="login_mobile_device">RiotX Android</string>
+    <string name="login_mobile_device">Mobile</string>
 
     <string name="login_error_forbidden">Invalid username/password</string>
     <string name="login_error_unknown_token">The access token specified was not recognised</string>
@@ -1024,7 +1024,7 @@
     <string name="encryption_never_send_to_unverified_devices_summary">Never send encrypted messages to unverified sessions from this session.</string>
     <string name="encryption_import_room_keys_success">%1$d/%2$d key(s) imported with success.</string>
 
-    <string name="encryption_information_not_verified">NOT Verified</string>
+    <string name="encryption_information_not_verified">Not Verified</string>
     <string name="encryption_information_verified">Verified</string>
     <string name="encryption_information_blocked">Blacklisted</string>
 
@@ -1038,8 +1038,8 @@
     <string name="encryption_information_unblock">Unblacklist</string>
 
     <string name="encryption_information_verify_device">Verify session</string>
-    <string name="encryption_information_verify_device_warning">To verify that this session can be trusted, please contact its owner using some other means (e.g. in person or a phone call) and ask them whether the key they see in their User Settings for this session matches the key below:</string>
-    <string name="encryption_information_verify_device_warning2">If it matches, press the verify button below. If it doesn’t, then someone else is intercepting this session and you should probably blacklist it. In the future this verification process will be more sophisticated.</string>
+    <string name="encryption_information_verify_device_warning">Confirm by comparing the following with the User Settings in your other session:</string>
+    <string name="encryption_information_verify_device_warning2">"If they don't match, the security of your communication may be compromised."</string>
     <string name="encryption_information_verify_key_match">I verify that the keys match</string>
 
     <string name="e2e_enabling_on_app_update">Riot now supports end-to-end encryption but you need to log in again to enable it.\n\nYou can do it now or later from the application settings.</string>
@@ -2112,7 +2112,7 @@ Not all features in Riot are implemented in RiotX yet. Main missing (and coming
     <string name="settings_active_sessions_list">Active Sessions</string>
     <string name="settings_active_sessions_show_all">Show All Sessions</string>
     <string name="settings_active_sessions_manage">Manage Sessions</string>
-    <string name="settings_active_sessions_signout_device">Sign out this session</string>
+    <string name="settings_active_sessions_signout_device">Sign out of this session</string>
 
     <string name="settings_failed_to_get_crypto_device_info">No cryptographic information available</string>
 
@@ -2124,7 +2124,7 @@ Not all features in Riot are implemented in RiotX yet. Main missing (and coming
         <item quantity="other">%d active sessions</item>
     </plurals>
 
-    <string name="crosssigning_verify_this_session">Verify this session</string>
+    <string name="crosssigning_verify_this_session">Verify this login</string>
     <string name="crosssigning_other_user_not_trust">Other users may not trust it</string>
     <string name="complete_security">Complete Security</string>
 
@@ -2168,7 +2168,7 @@ Not all features in Riot are implemented in RiotX yet. Main missing (and coming
     </plurals>
     <string name="poll_item_selected_aria">Selected Option</string>
     <string name="command_description_poll">Creates a simple poll</string>
-    <string name="verification_cannot_access_other_session">Use a recovery method</string>
+    <string name="verification_cannot_access_other_session">Use a Recovery Passphrase or Key</string>
     <string name="verification_use_passphrase">If you can’t access an existing session</string>
 
     <string name="new_signin">New Sign In</string>
@@ -2177,7 +2177,6 @@ Not all features in Riot are implemented in RiotX yet. Main missing (and coming
     <string name="enter_secret_storage_passphrase">Enter secret storage passphrase</string>
     <string name="enter_secret_storage_passphrase_warning">Warning:</string>
     <string name="enter_secret_storage_passphrase_warning_text">You should only access secret storage from a trusted device</string>
-    <string name="enter_secret_storage_passphrase_reason_verify">Access your secure message history and your cross-signing identity for verifying other sessions by entering your passphrase</string>
 
     <string name="message_action_item_redact">Remove…</string>
     <string name="share_confirm_room">Do you want to send this attachment to %1$s?</string>
@@ -2196,4 +2195,180 @@ Not all features in Riot are implemented in RiotX yet. Main missing (and coming
 
     <string name="keys_backup_restore_success_title_already_up_to_date">Keys are already up to date!</string>
 
+    <string name="login_mobile_device_riotx">RiotX Android</string>
+
+    <string name="settings_key_requests">Key Requests</string>
+
+    <string name="e2e_use_keybackup">Unlock encrypted messages history</string>
+
+    <string name="refresh">Refresh</string>
+
+    <string name="new_session">New login. Was this you?</string>
+    <string name="new_session_review">Tap to review &amp; verify</string>
+    <string name="verify_new_session_notice">Use this session to verify your new one, granting it access to encrypted messages.</string>
+    <string name="verify_new_session_was_not_me">This wasn’t me</string>
+    <string name="verify_new_session_compromized">Your account may be compromised</string>
+
+    <string name="verify_cancel_self_verification_from_untrusted">If you cancel, you won’t be able to read encrypted messages on this device, and other users won’t trust it</string>
+    <string name="verify_cancel_self_verification_from_trusted">If you cancel, you won’t be able to read encrypted messages on your new device, and other users won’t trust it</string>
+    <string name="verify_cancel_other">You won’t verify %1$s (%2$s) if you cancel now. Start again in their user profile.</string>
+
+    <string name="verify_not_me_self_verification">
+        One of the following may be compromised:\n\n- Your password\n- Your homeserver\n- This device, or the other device\n- The internet connection either device is using\n\nWe recommend you change your password &amp; recovery key in Settings immediately.
+    </string>
+
+    <string name="verify_cancelled_notice">Verify your devices from Settings.</string>
+    <string name="verification_cancelled">Verification Cancelled</string>
+
+    <string name="recovery_passphrase">Recovery Passphrase</string>
+    <string name="message_key">Message Key</string>
+    <string name="account_password">Account Password</string>
+
+    <!-- %s will be replaced by recovery_passphrase -->
+    <string name="set_recovery_passphrase">Set a %s</string>
+    <string name="generate_message_key">Generate a Message Key</string>
+
+    <!-- %s will be replaced by recovery_passphrase -->
+    <string name="confirm_recovery_passphrase">Confirm %s</string>
+
+    <!-- %s will be replaced by account_password -->
+    <string name="enter_account_password">Enter your %s to continue.</string>
+
+    <!-- %s will be replaced by recovery_passphrase -->
+    <string name="bootstrap_info_text">Secure &amp; unlock encrypted messages and trust with a %s.</string>
+    <!-- %s will be replaced by recovery_passphrase -->
+    <string name="bootstrap_info_confirm_text">Enter your %s again to confirm it.</string>
+    <string name="bootstrap_dont_reuse_pwd">Don’t re-use your account password.</string>
+
+
+    <string name="bootstrap_loading_text">This might take several seconds, please be patient.</string>
+    <string name="bootstrap_loading_title">Setting up recovery.</string>
+    <string name="your_recovery_key">Your recovery key</string>
+    <string name="bootstrap_finish_title">"You're done!"</string>
+    <string name="keep_it_safe">Keep it safe</string>
+    <string name="finish">Finish</string>
+
+    <!-- %1$s is replaced by message_key and %2$s by recovery_passphrase -->
+    <string name="bootstrap_save_key_description">Use this %1$s as a safety net in case you forget your %2$s.</string>
+
+    <string name="bootstrap_crosssigning_progress_initializing">Publishing created identity keys</string>
+    <string name="bootstrap_crosssigning_progress_pbkdf2">Generating secure key from passphrase</string>
+    <string name="bootstrap_crosssigning_progress_default_key">Defining SSSS default Key</string>
+    <string name="bootstrap_crosssigning_progress_save_msk">Synchronizing Master key</string>
+    <string name="bootstrap_crosssigning_progress_save_usk">Synchronizing User key</string>
+    <string name="bootstrap_crosssigning_progress_save_ssk">Synchronizing Self Signing key</string>
+    <string name="bootstrap_crosssigning_progress_key_backup">Setting Up Key Backup</string>
+
+
+    <!-- %1$s is replaced by message_key and %2$s by recovery_passphrase -->
+    <string name="bootstrap_cross_signing_success">Your %2$s &amp; %1$s are now set.\n\nKeep them safe! You’ll need them to unlock encrypted messages and secure information if you lose all of your active sessions.</string>
+
+    <!-- the %s will be replaced by a check mark on screen-->
+    <string name="bootstrap_crosssigning_print_it">Print it and store it somewhere safe</string>
+    <string name="bootstrap_crosssigning_save_usb">Save it on a USB key or backup drive</string>
+    <string name="bootstrap_crosssigning_save_cloud">Copy it to your personal cloud storage</string>
+
+    <string name="auth_flow_not_supported">You cannot do that from mobile</string>
+
+    <string name="bootstrap_skip_text">Setting a Recovery Passphrase lets you secure &amp; unlock encrypted messages and trust.\n\nIf you don’t want to set a Message Password, generate a Message Key instead.</string>
+    <string name="bootstrap_skip_text_no_gen_key">Setting a Recovery Passphrase lets you secure &amp; unlock encrypted messages and trust.</string>
+
+
+    <string name="encryption_enabled">Encryption enabled</string>
+    <string name="encryption_enabled_tile_description">Messages in this room are end-to-end encrypted. Learn more &amp; verify users in their profile.</string>
+    <string name="encryption_not_enabled">Encryption not enabled</string>
+    <string name="encryption_unknown_algorithm_tile_description">The encryption used by this room is not supported</string>
+
+    <string name="room_created_summary_item">%s created and configured the room.</string>
+
+    <string name="qr_code_scanned_self_verif_notice">Almost there! Is the other device showing the same shield?</string>
+    <string name="qr_code_scanned_verif_waiting_notice">Almost there! Waiting for confirmation…</string>
+    <string name="qr_code_scanned_verif_waiting">Waiting for %s…</string>
+
+    <string name="error_failed_to_import_keys">Failed to import keys</string>
+
+    <string name="settings_notification_configuration">Notifications configuration</string>
+    <string name="settings_messages_at_room">Messages containing @room</string>
+    <string name="settings_messages_in_e2e_one_to_one">Encrypted messages in one-to-one chats</string>
+    <string name="settings_messages_in_e2e_group_chat">Encrypted messages in group chats</string>
+    <string name="settings_when_rooms_are_upgraded">When rooms are upgraded</string>
+    <string name="settings_troubleshoot_title">Troubleshoot</string>
+    <string name="settings_notification_advanced_summary_riotx">Set notification importance by event</string>
+
+    <string name="command_description_plain">Sends a message as plain text, without interpreting it as markdown</string>
+
+    <string name="auth_invalid_login_param_space_in_password">Incorrect username and/or password. The entered password starts or ends with spaces, please check it.</string>
+
+    <string name="room_message_placeholder">Message…</string>
+
+    <string name="upgrade_security">Encryption upgrade available</string>
+    <string name="security_prompt_text">Verify yourself &amp; others to keep your chats safe</string>
+
+    <!-- %s will be replaced by recovery_key -->
+    <string name="bootstrap_enter_recovery">Enter your %s to continue</string>
+    <string name="use_file">Use File</string>
+
+    <!-- %s will be replaced by recovery_passphrase -->
+    <!--    <string name="upgrade_account_desc">Upgrade this session to allow it to verify other sessions, granting them access to encrypted messages and marking them as trusted for other users.</string>-->
+    <string name="enter_backup_passphrase">Enter %s</string>
+    <string name="backup_recovery_passphrase">Recovery Passphrase</string>
+    <string name="bootstrap_invalid_recovery_key">"It's not a valid recovery key"</string>
+    <string name="recovery_key_empty_error_message">Please enter a recovery key</string>
+
+    <string name="bootstrap_progress_checking_backup">Checking backup Key</string>
+    <string name="bootstrap_progress_checking_backup_with_info">Checking backup Key (%s)</string>
+    <string name="bootstrap_progress_compute_curve_key">Getting curve key</string>
+    <string name="bootstrap_progress_generating_ssss">Generating SSSS key from passphrase</string>
+    <string name="bootstrap_progress_generating_ssss_with_info">Generating SSSS key from passphrase (%s)</string>
+    <string name="bootstrap_progress_generating_ssss_recovery">Generating SSSS key from recovery key</string>
+    <string name="bootstrap_progress_storing_in_sss">Storing keybackup secret in SSSS</string>
+    <!-- To produce things like 'RiotX Android (IQDHUVJTTV)' -->
+    <string name="new_session_review_with_info">%1$s (%2$s)</string>
+
+    <string name="bootstrap_migration_enter_backup_password">Enter your Key Backup Passphrase to continue.</string>
+    <string name="bootstrap_migration_use_recovery_key">use your Key Backup recovery key</string>
+    <!-- %s will be replaced by the value of bootstrap_migration_use_recovery_key  -->
+    <string name="bootstrap_migration_with_passphrase_helper_with_link">Don’t know your Key Backup Passphrase, you can %s.</string>
+    <string name="bootstrap_migration_backup_recovery_key">Key Backup recovery key</string>
+
+    <string name="settings_security_prevent_screenshots_title">Prevent screenshots of the application</string>
+    <string name="settings_security_prevent_screenshots_summary">Enabling this setting adds the FLAG_SECURE to all Activities. Restart the application for the change to take effect.</string>
+
+    <string name="media_file_added_to_gallery">Media file added to the Gallery</string>
+    <string name="error_adding_media_file_to_gallery">Could not add media file to the Gallery</string>
+    <string name="change_password_summary">Set a new account password…</string>
+
+    <string name="use_other_session_content_description">Use the latest Riot on your other devices, Riot Web, Riot Desktop, Riot iOS, RiotX for Android, or another cross-signing capable Matrix client</string>
+    <string name="riot_desktop_web">Riot Web\nRiot Desktop</string>
+    <string name="riot_ios_android">Riot iOS\nRiot X for Android</string>
+    <string name="or_other_mx_capabale_client">or another cross-signing capable Matrix client</string>
+    <string name="use_latest_riot">Use the latest Riot on your other devices:</string>
+    <string name="command_description_discard_session">Forces the current outbound group session in an encrypted room to be discarded</string>
+    <string name="command_description_discard_session_not_handled">Only supported in encrypted rooms</string>
+    <!-- first will be replaced by recovery_passphrase, second will be replaced by recovery_key-->
+    <string name="enter_secret_storage_passphrase_or_key">Use your %1$s or use your %2$s to continue.</string>
+    <string name="use_recovery_key">Use Recovery Key</string>
+    <string name="enter_secret_storage_input_key">Select your Recovery Key, or input it manually by typing it or pasting from your clipboard</string>
+    <string name="keys_backup_recovery_key_error_decrypt">Backup could not be decrypted with this Recovery Key: please verify that you entered the correct Recovery Key.</string>
+    <string name="failed_to_access_secure_storage">Failed to access secure storage</string>
+
+    <string name="unencrypted">Unencrypted</string>
+    <string name="encrypted_unverified">Encrypted by an unverified device</string>
+    <string name="review_logins">Review where you’re logged in</string>
+    <string name="verify_other_sessions">Verify all your sessions to ensure your account &amp; messages are safe</string>
+    <!-- Argument will be replaced by the other session name (e.g, Riot Desktop, mobile) -->
+    <string name="verify_this_session">Verify the new login accessing your account: %1$s</string>
+
+    <string name="cross_signing_verify_by_text">Manually Verify by Text</string>
+    <string name="crosssigning_verify_session">Verify login</string>
+    <string name="cross_signing_verify_by_emoji">Interactively Verify by Emoji</string>
+    <string name="confirm_your_identity">Confirm your identity by verifying this login from one of your other sessions, granting it access to encrypted messages.</string>
+    <string name="mark_as_verified">Mark as Trusted</string>
+
+    <string name="error_empty_field_choose_user_name">Please choose a username.</string>
+    <string name="error_empty_field_choose_password">Please choose a password.</string>
+    <string name="external_link_confirmation_title">Double-check this link</string>
+    <string name="external_link_confirmation_message">The link %1$s is taking you to another site: %2$s.\n\nAre you sure you want to continue?</string>
+
+    <string name="create_room_dm_failure">"We couldn't create your DM. Please check the users you want to invite and try again."</string>
 </resources>
diff --git a/vector/src/main/res/values/strings_riotX.xml b/vector/src/main/res/values/strings_riotX.xml
index 9ef21170a4..585102d46a 100644
--- a/vector/src/main/res/values/strings_riotX.xml
+++ b/vector/src/main/res/values/strings_riotX.xml
@@ -1,117 +1,45 @@
 <?xml version="1.0" encoding="utf-8"?>
 <resources>
 
+    <!--
+
+
+
+
+
+
+
+
+
+
+
+
+
+     PLEASE DO NOT ADD NEW STRINGS HERE, THE FILE WILL BE DELETED, ONCE ALL PR WILL BE MERGED
+
+
+
+
+
+
+
+
+
+
+
+      -->
+
     <!-- Strings not defined in Riot -->
 
-    <!-- Sections has been created to avoid merge conflict. Let's see if it's better -->
+    <!-- Sections has been created to limit merge conflicts. -->
 
     <!-- BEGIN Strings added by Valere -->
 
-
-    <string name="settings_key_requests">Key Requests</string>
-
-    <string name="e2e_use_keybackup">Unlock encrypted messages history</string>
-
-    <string name="refresh">Refresh</string>
-
-
-    <string name="new_session">New Session</string>
-    <string name="new_session_review">Tap to review &amp; verify</string>
-    <string name="verify_new_session_notice">Use this session to verify your new one, granting it access to encrypted messages.</string>
-    <string name="verify_new_session_was_not_me">This wasn’t me</string>
-    <string name="verify_new_session_compromized">Your account may be compromised</string>
-
-    <string name="verify_cancel_self_verification_from_untrusted">If you cancel, you won’t be able to read encrypted messages on this device, and other users won’t trust it</string>
-    <string name="verify_cancel_self_verification_from_trusted">If you cancel, you won’t be able to read encrypted messages on your new device, and other users won’t trust it</string>
-    <string name="verify_cancel_other">You won’t verify %1$s (%2$s) if you cancel now. Start again in their user profile.</string>
-
-    <string name="verify_not_me_self_verification">
-        One of the following may be compromised:\n\n- Your password\n- Your homeserver\n- This device, or the other device\n- The internet connection either device is using\n\nWe recommend you change your password &amp; recovery key in Settings immediately.
-    </string>
-
-    <string name="verify_cancelled_notice">Verify your devices from Settings.</string>
-    <string name="verification_cancelled">Verification Cancelled</string>
-
-    <string name="recovery_passphrase">Message Password</string>
-    <string name="message_key">Message Key</string>
-    <string name="account_password">Account Password</string>
-
-
-    <!-- %s will be replaced by recovery_passphrase -->
-    <string name="set_recovery_passphrase">Set a %s</string>
-    <string name="generate_message_key">Generate a Message Key</string>
-
-    <!-- %s will be replaced by recovery_passphrase -->
-    <string name="confirm_recovery_passphrase">Confirm %s</string>
-
-
-    <!-- %s will be replaced by account_password -->
-    <string name="enter_account_password">Enter your %s to continue.</string>
-
-    <!-- %s will be replaced by recovery_passphrase -->
-    <string name="bootstrap_info_text">Secure &amp; unlock encrypted messages and trust with a %s.</string>
-    <!-- %s will be replaced by recovery_passphrase -->
-    <string name="bootstrap_info_confirm_text">Enter your %s again to confirm it.</string>
-    <string name="bootstrap_dont_reuse_pwd">Don’t re-use your account password.</string>
-
-
-    <string name="bootstrap_loading_text">This might take several seconds, please be patient.</string>
-    <string name="bootstrap_loading_title">Setting up recovery.</string>
-    <string name="your_recovery_key">Your recovery key</string>
-    <string name="bootstrap_finish_title">You‘re done!</string>
-    <string name="keep_it_safe">Keep it safe</string>
-    <string name="finish">Finish</string>
-
-    <!-- %1$s is replaced by message_key and %2$s by recovery_passphrase -->
-    <string name="bootstrap_save_key_description">Use this %1$s as a safety net in case you forget your %2$s.</string>
-
-    <string name="bootstrap_crosssigning_progress_initializing">Publishing created identity keys</string>
-    <string name="bootstrap_crosssigning_progress_pbkdf2">Generating secure key from passphrase</string>
-    <string name="bootstrap_crosssigning_progress_default_key">Defining SSSS default Key</string>
-    <string name="bootstrap_crosssigning_progress_save_msk">Synchronizing Master key</string>
-    <string name="bootstrap_crosssigning_progress_save_usk">Synchronizing User key</string>
-    <string name="bootstrap_crosssigning_progress_save_ssk">Synchronizing Self Signing key</string>
-    <string name="bootstrap_crosssigning_progress_key_backup">Setting Up Key Backup</string>
-
-
-    <!-- %1$s is replaced by message_key and %2$s by recovery_passphrase -->
-    <string name="bootstrap_cross_signing_success">Your %2$s &amp; %1$s are now set.\n\nKeep them safe! You’ll need them to unlock encrypted messages and secure information if you lose all of your active sessions.</string>
-
-    <!-- the %s will be replaced by a check mark on screen-->
-    <string name="bootstrap_crosssigning_print_it">Print it and store it somewhere safe</string>
-    <string name="bootstrap_crosssigning_save_usb">Save it on a USB key or backup drive</string>
-    <string name="bootstrap_crosssigning_save_cloud">Copy it to your personal cloud storage</string>
-
-    <string name="auth_flow_not_supported">You cannot do that from mobile</string>
-
-    <string name="bootstrap_skip_text">Setting a Message Password lets you secure &amp; unlock encrypted messages and trust.\n\nIf you don’t want to set a Message Password, generate a Message Key instead.</string>
-    <string name="bootstrap_skip_text_no_gen_key">Setting a Message Password lets you secure &amp; unlock encrypted messages and trust.</string>
-
-
-    <string name="encryption_enabled">Encryption enabled</string>
-    <string name="encryption_enabled_tile_description">Messages in this room are end-to-end encrypted. Learn more &amp; verify users in their profile.</string>
-    <string name="encryption_not_enabled">Encryption not enabled</string>
-    <string name="encryption_unknown_algorithm_tile_description">The encryption used by this room is not supported</string>
-
-    <string name="room_created_summary_item">%s created and configured the room.</string>
-
-    <string name="qr_code_scanned_self_verif_notice">Almost there! Is the other device showing the same shield?</string>
-    <string name="qr_code_scanned_verif_waiting_notice">Almost there! Waiting for confirmation…</string>
-    <string name="qr_code_scanned_verif_waiting">Waiting for %s…</string>
-
-    <string name="error_failed_to_import_keys">Failed to import keys</string>
-
     <!-- END Strings added by Valere -->
 
 
     <!-- BEGIN Strings added by Benoit -->
-    <string name="settings_notification_configuration">Notifications configuration</string>
-    <string name="settings_messages_at_room">Messages containing @room</string>
-    <string name="settings_messages_in_e2e_one_to_one">Encrypted messages in one-to-one chats</string>
-    <string name="settings_messages_in_e2e_group_chat">Encrypted messages in group chats</string>
-    <string name="settings_when_rooms_are_upgraded">When rooms are upgraded</string>
-    <string name="settings_troubleshoot_title">Troubleshoot</string>
-    <string name="settings_notification_advanced_summary_riotx">Set notification importance by event</string>
+
     <!-- END Strings added by Benoit -->
 
 
@@ -126,8 +54,7 @@
 
 
     <!-- BEGIN Strings added by Others -->
-    <string name="command_description_plain">Sends a message as plain text, without interpreting it as markdown</string>
+
     <!-- END Strings added by Others -->
 
-    <string name="auth_invalid_login_param_space_in_password">Incorrect username and/or password. The entered password starts or ends with spaces, please check it.</string>
 </resources>
diff --git a/vector/src/main/res/values/theme_black.xml b/vector/src/main/res/values/theme_black.xml
index b2ddfd5b81..f3f84a36d8 100644
--- a/vector/src/main/res/values/theme_black.xml
+++ b/vector/src/main/res/values/theme_black.xml
@@ -18,6 +18,7 @@
         <item name="riotx_header_panel_text_secondary">@color/riotx_header_panel_text_secondary_black</item>
         <item name="riotx_text_primary">@color/riotx_text_primary_black</item>
         <item name="riotx_text_secondary">@color/riotx_text_secondary_black</item>
+        <item name="riotx_text_primary_body_contrast">@color/riotx_text_primary_body_contrast_black</item>
         <item name="riotx_android_secondary">@color/riotx_android_secondary_black</item>
         <item name="riotx_search_placeholder">@color/riotx_search_placeholder_black</item>
         <item name="riotx_room_highlight">@color/riotx_room_highlight_black</item>
diff --git a/vector/src/main/res/values/theme_dark.xml b/vector/src/main/res/values/theme_dark.xml
index 09775d4d41..a2be367e55 100644
--- a/vector/src/main/res/values/theme_dark.xml
+++ b/vector/src/main/res/values/theme_dark.xml
@@ -16,6 +16,7 @@
         <item name="riotx_header_panel_text_secondary">@color/riotx_header_panel_text_secondary_dark</item>
         <item name="riotx_text_primary">@color/riotx_text_primary_dark</item>
         <item name="riotx_text_secondary">@color/riotx_text_secondary_dark</item>
+        <item name="riotx_text_primary_body_contrast">@color/riotx_text_primary_body_contrast_dark</item>
         <item name="riotx_android_secondary">@color/riotx_android_secondary_dark</item>
         <item name="riotx_search_placeholder">@color/riotx_search_placeholder_dark</item>
         <item name="riotx_room_highlight">@color/riotx_room_highlight_dark</item>
diff --git a/vector/src/main/res/values/theme_light.xml b/vector/src/main/res/values/theme_light.xml
index c63dfa9057..9709172f9d 100644
--- a/vector/src/main/res/values/theme_light.xml
+++ b/vector/src/main/res/values/theme_light.xml
@@ -16,6 +16,7 @@
         <item name="riotx_header_panel_text_secondary">@color/riotx_header_panel_text_secondary_light</item>
         <item name="riotx_text_primary">@color/riotx_text_primary_light</item>
         <item name="riotx_text_secondary">@color/riotx_text_secondary_light</item>
+        <item name="riotx_text_primary_body_contrast">@color/riotx_text_primary_body_contrast_light</item>
         <item name="riotx_android_secondary">@color/riotx_android_secondary_light</item>
         <item name="riotx_search_placeholder">@color/riotx_search_placeholder_light</item>
         <item name="riotx_room_highlight">@color/riotx_room_highlight_light</item>
diff --git a/vector/src/main/res/xml/vector_settings_general.xml b/vector/src/main/res/xml/vector_settings_general.xml
index c49eca825a..11f16655a7 100644
--- a/vector/src/main/res/xml/vector_settings_general.xml
+++ b/vector/src/main/res/xml/vector_settings_general.xml
@@ -19,7 +19,7 @@
 
         <im.vector.riotx.core.preference.VectorPreference
             android:key="SETTINGS_CHANGE_PASSWORD_PREFERENCE_KEY"
-            android:summary="@string/password_hint"
+            android:summary="@string/change_password_summary"
             android:title="@string/settings_password" />
 
         <!-- Email will be added here -->
@@ -97,14 +97,13 @@
 
     </im.vector.riotx.core.preference.VectorPreferenceCategory>
 
-    <im.vector.riotx.core.preference.VectorPreferenceCategory
-        android:key="SETTINGS_DEACTIVATE_ACCOUNT_CATEGORY_KEY"
-        android:title="@string/settings_deactivate_account_section"
-        app:isPreferenceVisible="@bool/false_not_implemented">
+    <im.vector.riotx.core.preference.VectorPreferenceCategory android:title="@string/settings_deactivate_account_section">
 
         <im.vector.riotx.core.preference.VectorPreference
             android:key="SETTINGS_DEACTIVATE_ACCOUNT_KEY"
-            android:title="@string/settings_deactivate_my_account" />
+            android:persistent="false"
+            android:title="@string/settings_deactivate_my_account"
+            app:fragment="im.vector.riotx.features.settings.account.deactivation.DeactivateAccountFragment" />
 
     </im.vector.riotx.core.preference.VectorPreferenceCategory>
 
diff --git a/vector/src/main/res/xml/vector_settings_security_privacy.xml b/vector/src/main/res/xml/vector_settings_security_privacy.xml
index 19bc340500..f394e319c7 100644
--- a/vector/src/main/res/xml/vector_settings_security_privacy.xml
+++ b/vector/src/main/res/xml/vector_settings_security_privacy.xml
@@ -6,36 +6,33 @@
     <!-- ************ Cryptography section ************ -->
     <im.vector.riotx.core.preference.VectorPreferenceCategory
         android:key="SETTINGS_CRYPTOGRAPHY_PREFERENCE_KEY"
-        tools:isPreferenceVisible="true"
-        app:isPreferenceVisible="false"
         android:title="@string/settings_cryptography">
         <im.vector.riotx.core.preference.VectorPreference
             android:key="SETTINGS_ENCRYPTION_CROSS_SIGNING_PREFERENCE_KEY"
-            tools:icon="@drawable/ic_shield_trusted"
             android:persistent="false"
             android:title="@string/encryption_information_cross_signing_state"
-            tools:summary="@string/encryption_information_dg_xsigning_complete"
             app:fragment="im.vector.riotx.features.settings.crosssigning.CrossSigningSettingsFragment"
-            />
+            tools:icon="@drawable/ic_shield_trusted"
+            tools:summary="@string/encryption_information_dg_xsigning_complete" />
 
 
-<!--        <im.vector.riotx.core.preference.VectorPreference-->
-<!--            android:key="SETTINGS_ENCRYPTION_INFORMATION_DEVICE_NAME_PREFERENCE_KEY"-->
-<!--            android:title="@string/encryption_information_device_name" />-->
+        <!--        <im.vector.riotx.core.preference.VectorPreference-->
+        <!--            android:key="SETTINGS_ENCRYPTION_INFORMATION_DEVICE_NAME_PREFERENCE_KEY"-->
+        <!--            android:title="@string/encryption_information_device_name" />-->
 
-<!--        <im.vector.riotx.core.preference.VectorPreference-->
-<!--            android:key="SETTINGS_ENCRYPTION_INFORMATION_DEVICE_ID_PREFERENCE_KEY"-->
-<!--            android:title="@string/encryption_information_device_id" />-->
+        <!--        <im.vector.riotx.core.preference.VectorPreference-->
+        <!--            android:key="SETTINGS_ENCRYPTION_INFORMATION_DEVICE_ID_PREFERENCE_KEY"-->
+        <!--            android:title="@string/encryption_information_device_id" />-->
 
-<!--        <im.vector.riotx.core.preference.VectorPreference-->
-<!--            android:key="SETTINGS_ENCRYPTION_INFORMATION_DEVICE_KEY_PREFERENCE_KEY"-->
-<!--            android:title="@string/encryption_information_device_key" />-->
+        <!--        <im.vector.riotx.core.preference.VectorPreference-->
+        <!--            android:key="SETTINGS_ENCRYPTION_INFORMATION_DEVICE_KEY_PREFERENCE_KEY"-->
+        <!--            android:title="@string/encryption_information_device_key" />-->
 
         <im.vector.riotx.core.preference.VectorSwitchPreference
+            android:enabled="false"
             android:key="SETTINGS_ENCRYPTION_NEVER_SENT_TO_PREFERENCE_KEY"
             android:summary="@string/encryption_never_send_to_unverified_devices_summary"
-            android:title="@string/encryption_never_send_to_unverified_devices_title"
-            android:enabled="false" />
+            android:title="@string/encryption_never_send_to_unverified_devices_title" />
 
     </im.vector.riotx.core.preference.VectorPreferenceCategory>
 
@@ -85,4 +82,15 @@
 
     </im.vector.riotx.core.preference.VectorPreferenceCategory>
 
+    <im.vector.riotx.core.preference.VectorPreferenceCategory
+        android:title="@string/settings_other">
+
+        <im.vector.riotx.core.preference.VectorSwitchPreference
+            android:defaultValue="false"
+            android:key="SETTINGS_SECURITY_USE_FLAG_SECURE"
+            android:summary="@string/settings_security_prevent_screenshots_summary"
+            android:title="@string/settings_security_prevent_screenshots_title" />
+
+    </im.vector.riotx.core.preference.VectorPreferenceCategory>
+
 </androidx.preference.PreferenceScreen>
\ No newline at end of file
diff --git a/vector/src/sharedTest/java/im/vector/riotx/test/shared/TestRules.kt b/vector/src/sharedTest/java/im/vector/riotx/test/shared/TestRules.kt
new file mode 100644
index 0000000000..d5790ba497
--- /dev/null
+++ b/vector/src/sharedTest/java/im/vector/riotx/test/shared/TestRules.kt
@@ -0,0 +1,27 @@
+/*
+ * 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.riotx.test.shared
+
+import net.lachlanmckee.timberjunit.TimberTestRule
+
+fun createTimberTestRule(): TimberTestRule {
+    return TimberTestRule.builder()
+            .showThread(false)
+            .showTimestamp(false)
+            .onlyLogWhenTestFails(false)
+            .build()
+}