diff --git a/changelog.d/6961.wip b/changelog.d/6961.wip
new file mode 100644
index 0000000000..2d271da8c1
--- /dev/null
+++ b/changelog.d/6961.wip
@@ -0,0 +1 @@
+[Devices Management] Session overview screen
diff --git a/library/ui-strings/src/main/res/values/strings.xml b/library/ui-strings/src/main/res/values/strings.xml
index cbd56dc7ea..07ea6a74cf 100644
--- a/library/ui-strings/src/main/res/values/strings.xml
+++ b/library/ui-strings/src/main/res/values/strings.xml
@@ -3227,13 +3227,22 @@
     <string name="a11y_device_manager_device_type_unknown">Unknown device type</string>
     <string name="device_manager_verification_status_verified">Verified session</string>
     <string name="device_manager_verification_status_unverified">Unverified session</string>
-    <string name="device_manager_verification_status_detail_verified">Your current session is ready for secure messaging.</string>
-    <string name="device_manager_verification_status_detail_unverified">Verify your current session for enhanced secure messaging.</string>
+    <!-- TODO TO BE REMOVED: replaced by device_manager_verification_status_detail_current_session_verified -->
+    <string name="device_manager_verification_status_detail_verified" tools:ignore="UnusedResources">Your current session is ready for secure messaging.</string>
+    <!-- TODO TO BE REMOVED: replaced by device_manager_verification_status_detail_current_session_unverified -->
+    <string name="device_manager_verification_status_detail_unverified" tools:ignore="UnusedResources">Verify your current session for enhanced secure messaging.</string>
+    <string name="device_manager_verification_status_detail_current_session_verified">Your current session is ready for secure messaging.</string>
+    <string name="device_manager_verification_status_detail_other_session_verified">This session is ready for secure messaging.</string>
+    <string name="device_manager_verification_status_detail_current_session_unverified">Verify your current session for enhanced secure messaging.</string>
+    <string name="device_manager_verification_status_detail_other_session_unverified">Verify or sign out from this session for best security and reliability.</string>
     <string name="device_manager_verify_session">Verify Session</string>
     <string name="device_manager_view_details">View Details</string>
-    <string name="device_manager_header_section_current_session">Current Session</string>
+    <!-- TODO TO BE REMOVED: replaced by device_manager_current_session_title -->
+    <string name="device_manager_header_section_current_session" tools:ignore="UnusedResources">Current Session</string>
     <string name="device_manager_other_sessions_view_all">View All (%1$d)</string>
+    <!--  Examples: Verified · Last activity Yesterday at 6PM, Verified · Last activity Aug 31 at 5:47PM -->
     <string name="device_manager_other_sessions_description_verified">Verified · Last activity %1$s</string>
+    <!--  Examples: Unverified · Last activity Yesterday at 6PM, Unverified · Last activity Aug 31 at 5:47PM -->
     <string name="device_manager_other_sessions_description_unverified">Unverified · Last activity %1$s</string>
     <!--  Example: Inactive for 90+ days (Dec 25, 2021) -->
     <plurals name="device_manager_other_sessions_description_inactive">
@@ -3249,6 +3258,10 @@
         <item quantity="one">Consider signing out from old sessions (%1$d day or more) that you don’t use anymore.</item>
         <item quantity="other">Consider signing out from old sessions (%1$d days or more) that you don’t use anymore.</item>
     </plurals>
+    <string name="device_manager_current_session_title">Current Session</string>
+    <string name="device_manager_session_title">Session</string>
+    <!--  Examples: Last activity Yesterday at 6PM, Last activity Aug 31 at 5:47PM -->
+    <string name="device_manager_session_last_activity">Last activity %1$s</string>
 
     <!-- Note to translators: %s will be replaces with selected space name -->
     <string name="home_empty_space_no_rooms_title">%s\nis looking a little empty.</string>
diff --git a/library/ui-styles/src/main/res/values/stylable_devices_list_header_view.xml b/library/ui-styles/src/main/res/values/stylable_devices_list_header_view.xml
index f0807f89c6..97e0290815 100644
--- a/library/ui-styles/src/main/res/values/stylable_devices_list_header_view.xml
+++ b/library/ui-styles/src/main/res/values/stylable_devices_list_header_view.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <resources>
 
-    <declare-styleable name="DevicesListHeaderView">
+    <declare-styleable name="SessionsListHeaderView">
         <attr name="devicesListHeaderTitle" format="string" />
         <attr name="devicesListHeaderDescription" format="string" />
     </declare-styleable>
diff --git a/library/ui-styles/src/main/res/values/styles_devices_management.xml b/library/ui-styles/src/main/res/values/styles_devices_management.xml
index 2a63c2ed36..6fb236d3e6 100644
--- a/library/ui-styles/src/main/res/values/styles_devices_management.xml
+++ b/library/ui-styles/src/main/res/values/styles_devices_management.xml
@@ -7,6 +7,7 @@
 
     <style name="TextAppearance.Vector.Body.DevicesManagement">
         <item name="android:textColor">?vctr_content_secondary</item>
+        <item name="android:drawablePadding">12dp</item>
     </style>
 
 </resources>
diff --git a/matrix-sdk-android-flow/src/main/java/org/matrix/android/sdk/flow/FlowSession.kt b/matrix-sdk-android-flow/src/main/java/org/matrix/android/sdk/flow/FlowSession.kt
index f22cfa369a..80ed311901 100644
--- a/matrix-sdk-android-flow/src/main/java/org/matrix/android/sdk/flow/FlowSession.kt
+++ b/matrix-sdk-android-flow/src/main/java/org/matrix/android/sdk/flow/FlowSession.kt
@@ -72,7 +72,7 @@ class FlowSession(private val session: Session) {
     }
 
     fun liveMyDevicesInfo(): Flow<List<DeviceInfo>> {
-        return session.cryptoService().getLiveMyDevicesInfo().asFlow()
+        return session.cryptoService().getMyDevicesInfoLive().asFlow()
                 .startWith(session.coroutineDispatchers.io) {
                     session.cryptoService().getMyDevicesInfo()
                 }
diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/CryptoStoreHelper.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/CryptoStoreHelper.kt
index ba1afd4758..48cfbebe5b 100644
--- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/CryptoStoreHelper.kt
+++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/CryptoStoreHelper.kt
@@ -21,6 +21,7 @@ import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore
 import org.matrix.android.sdk.internal.crypto.store.db.RealmCryptoStore
 import org.matrix.android.sdk.internal.crypto.store.db.RealmCryptoStoreModule
 import org.matrix.android.sdk.internal.crypto.store.db.mapper.CrossSigningKeysMapper
+import org.matrix.android.sdk.internal.crypto.store.db.mapper.MyDeviceLastSeenInfoEntityMapper
 import org.matrix.android.sdk.internal.di.MoshiProvider
 import org.matrix.android.sdk.internal.util.time.DefaultClock
 import kotlin.random.Random
@@ -37,6 +38,7 @@ internal class CryptoStoreHelper {
                 userId = "userId_" + Random.nextInt(),
                 deviceId = "deviceId_sample",
                 clock = DefaultClock(),
+                myDeviceLastSeenInfoEntityMapper = MyDeviceLastSeenInfoEntityMapper()
         )
     }
 }
diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/E2eeSanityTests.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/E2eeSanityTests.kt
index 251c13ccbf..f883295495 100644
--- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/E2eeSanityTests.kt
+++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/E2eeSanityTests.kt
@@ -676,8 +676,8 @@ class E2eeSanityTests : InstrumentedTest {
         assertEquals("Decimal code should have matched", oldCode, newCode)
 
         // Assert that devices are verified
-        val newDeviceFromOldPov: CryptoDeviceInfo? = aliceSession.cryptoService().getDeviceInfo(aliceSession.myUserId, aliceNewSession.sessionParams.deviceId)
-        val oldDeviceFromNewPov: CryptoDeviceInfo? = aliceSession.cryptoService().getDeviceInfo(aliceSession.myUserId, aliceSession.sessionParams.deviceId)
+        val newDeviceFromOldPov: CryptoDeviceInfo? = aliceSession.cryptoService().getCryptoDeviceInfo(aliceSession.myUserId, aliceNewSession.sessionParams.deviceId)
+        val oldDeviceFromNewPov: CryptoDeviceInfo? = aliceSession.cryptoService().getCryptoDeviceInfo(aliceSession.myUserId, aliceSession.sessionParams.deviceId)
 
         Assert.assertTrue("new device should be verified from old point of view", newDeviceFromOldPov!!.isVerified)
         Assert.assertTrue("old device should be verified from new point of view", oldDeviceFromNewPov!!.isVerified)
diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/crosssigning/XSigningTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/crosssigning/XSigningTest.kt
index 8cb38ddc87..ef3fdfeeda 100644
--- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/crosssigning/XSigningTest.kt
+++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/crosssigning/XSigningTest.kt
@@ -193,7 +193,7 @@ class XSigningTest : InstrumentedTest {
             fail("Bob should see the new device")
         }
 
-        val bobSecondDevicePOVFirstDevice = bobSession.cryptoService().getDeviceInfo(bobUserId, bobSecondDeviceId)
+        val bobSecondDevicePOVFirstDevice = bobSession.cryptoService().getCryptoDeviceInfo(bobUserId, bobSecondDeviceId)
         assertNotNull("Bob Second device should be known and persisted from first", bobSecondDevicePOVFirstDevice)
 
         // Manually mark it as trusted from first session
diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/verification/SASTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/verification/SASTest.kt
index c2e74abc59..1bffbeeeaa 100644
--- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/verification/SASTest.kt
+++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/verification/SASTest.kt
@@ -521,9 +521,9 @@ class SASTest : InstrumentedTest {
         testHelper.await(bobSASLatch)
 
         // Assert that devices are verified
-        val bobDeviceInfoFromAlicePOV: CryptoDeviceInfo? = aliceSession.cryptoService().getDeviceInfo(bobUserId, bobDeviceId)
+        val bobDeviceInfoFromAlicePOV: CryptoDeviceInfo? = aliceSession.cryptoService().getCryptoDeviceInfo(bobUserId, bobDeviceId)
         val aliceDeviceInfoFromBobPOV: CryptoDeviceInfo? =
-                bobSession.cryptoService().getDeviceInfo(aliceSession.myUserId, aliceSession.cryptoService().getMyDevice().deviceId)
+                bobSession.cryptoService().getCryptoDeviceInfo(aliceSession.myUserId, aliceSession.cryptoService().getMyDevice().deviceId)
 
         assertTrue("alice device should be verified from bob point of view", aliceDeviceInfoFromBobPOV!!.isVerified)
         assertTrue("bob device should be verified from alice point of view", bobDeviceInfoFromAlicePOV!!.isVerified)
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt
index a5e05f69e0..e0e662c789 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt
@@ -40,6 +40,7 @@ import org.matrix.android.sdk.api.session.crypto.verification.VerificationServic
 import org.matrix.android.sdk.api.session.events.model.Content
 import org.matrix.android.sdk.api.session.events.model.Event
 import org.matrix.android.sdk.api.session.events.model.content.RoomKeyWithHeldContent
+import org.matrix.android.sdk.api.util.Optional
 import org.matrix.android.sdk.internal.crypto.model.SessionInfo
 
 interface CryptoService {
@@ -113,7 +114,19 @@ interface CryptoService {
 
     fun setRoomBlacklistUnverifiedDevices(roomId: String)
 
-    fun getDeviceInfo(userId: String, deviceId: String?): CryptoDeviceInfo?
+    fun getCryptoDeviceInfo(userId: String, deviceId: String?): CryptoDeviceInfo?
+
+    fun getCryptoDeviceInfo(deviceId: String, callback: MatrixCallback<DeviceInfo>)
+
+    fun getCryptoDeviceInfo(userId: String): List<CryptoDeviceInfo>
+
+    fun getLiveCryptoDeviceInfo(): LiveData<List<CryptoDeviceInfo>>
+
+    fun getLiveCryptoDeviceInfoWithId(deviceId: String): LiveData<Optional<CryptoDeviceInfo>>
+
+    fun getLiveCryptoDeviceInfo(userId: String): LiveData<List<CryptoDeviceInfo>>
+
+    fun getLiveCryptoDeviceInfo(userIds: List<String>): LiveData<List<CryptoDeviceInfo>>
 
     fun requestRoomKeyForEvent(event: Event)
 
@@ -127,9 +140,9 @@ interface CryptoService {
 
     fun getMyDevicesInfo(): List<DeviceInfo>
 
-    fun getLiveMyDevicesInfo(): LiveData<List<DeviceInfo>>
+    fun getMyDevicesInfoLive(): LiveData<List<DeviceInfo>>
 
-    fun getDeviceInfo(deviceId: String, callback: MatrixCallback<DeviceInfo>)
+    fun getMyDevicesInfoLive(deviceId: String): LiveData<Optional<DeviceInfo>>
 
     fun inboundGroupSessionsCount(onlyBackedUp: Boolean): Int
 
@@ -156,14 +169,6 @@ interface CryptoService {
 
     fun downloadKeys(userIds: List<String>, forceDownload: Boolean, callback: MatrixCallback<MXUsersDevicesMap<CryptoDeviceInfo>>)
 
-    fun getCryptoDeviceInfo(userId: String): List<CryptoDeviceInfo>
-
-    fun getLiveCryptoDeviceInfo(): LiveData<List<CryptoDeviceInfo>>
-
-    fun getLiveCryptoDeviceInfo(userId: String): LiveData<List<CryptoDeviceInfo>>
-
-    fun getLiveCryptoDeviceInfo(userIds: List<String>): LiveData<List<CryptoDeviceInfo>>
-
     fun addNewSessionListener(newSessionListener: NewSessionListener)
     fun removeSessionListener(listener: NewSessionListener)
 
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt
index 35c066dea8..8dd7c309c6 100755
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt
@@ -73,6 +73,7 @@ import org.matrix.android.sdk.api.session.room.model.RoomHistoryVisibilityConten
 import org.matrix.android.sdk.api.session.room.model.RoomMemberContent
 import org.matrix.android.sdk.api.session.room.model.shouldShareHistory
 import org.matrix.android.sdk.api.session.sync.model.SyncResponse
+import org.matrix.android.sdk.api.util.Optional
 import org.matrix.android.sdk.internal.crypto.actions.MegolmSessionDataImporter
 import org.matrix.android.sdk.internal.crypto.actions.SetDeviceVerificationAction
 import org.matrix.android.sdk.internal.crypto.algorithms.IMXEncrypting
@@ -273,23 +274,18 @@ internal class DefaultCryptoService @Inject constructor(
                 .executeBy(taskExecutor)
     }
 
-    override fun getLiveMyDevicesInfo(): LiveData<List<DeviceInfo>> {
+    override fun getMyDevicesInfoLive(): LiveData<List<DeviceInfo>> {
         return cryptoStore.getLiveMyDevicesInfo()
     }
 
+    override fun getMyDevicesInfoLive(deviceId: String): LiveData<Optional<DeviceInfo>> {
+        return cryptoStore.getLiveMyDevicesInfo(deviceId)
+    }
+
     override fun getMyDevicesInfo(): List<DeviceInfo> {
         return cryptoStore.getMyDevicesInfo()
     }
 
-    override fun getDeviceInfo(deviceId: String, callback: MatrixCallback<DeviceInfo>) {
-        getDeviceInfoTask
-                .configureWith(GetDeviceInfoTask.Params(deviceId)) {
-                    this.executionThread = TaskThread.CRYPTO
-                    this.callback = callback
-                }
-                .executeBy(taskExecutor)
-    }
-
     override fun inboundGroupSessionsCount(onlyBackedUp: Boolean): Int {
         return cryptoStore.inboundGroupSessionsCount(onlyBackedUp)
     }
@@ -513,7 +509,7 @@ internal class DefaultCryptoService @Inject constructor(
      * @param userId the user id
      * @param deviceId the device id
      */
-    override fun getDeviceInfo(userId: String, deviceId: String?): CryptoDeviceInfo? {
+    override fun getCryptoDeviceInfo(userId: String, deviceId: String?): CryptoDeviceInfo? {
         return if (userId.isNotEmpty() && !deviceId.isNullOrEmpty()) {
             cryptoStore.getUserDevice(userId, deviceId)
         } else {
@@ -521,6 +517,15 @@ internal class DefaultCryptoService @Inject constructor(
         }
     }
 
+    override fun getCryptoDeviceInfo(deviceId: String, callback: MatrixCallback<DeviceInfo>) {
+        getDeviceInfoTask
+                .configureWith(GetDeviceInfoTask.Params(deviceId)) {
+                    this.executionThread = TaskThread.CRYPTO
+                    this.callback = callback
+                }
+                .executeBy(taskExecutor)
+    }
+
     override fun getCryptoDeviceInfo(userId: String): List<CryptoDeviceInfo> {
         return cryptoStore.getUserDeviceList(userId).orEmpty()
     }
@@ -529,6 +534,10 @@ internal class DefaultCryptoService @Inject constructor(
         return cryptoStore.getLiveDeviceList()
     }
 
+    override fun getLiveCryptoDeviceInfoWithId(deviceId: String): LiveData<Optional<CryptoDeviceInfo>> {
+        return cryptoStore.getLiveDeviceWithId(deviceId)
+    }
+
     override fun getLiveCryptoDeviceInfo(userId: String): LiveData<List<CryptoDeviceInfo>> {
         return cryptoStore.getLiveDeviceList(userId)
     }
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCryptoStore.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCryptoStore.kt
index 0413fc730c..56eba25249 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCryptoStore.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCryptoStore.kt
@@ -238,10 +238,14 @@ internal interface IMXCryptoStore {
     // TODO temp
     fun getLiveDeviceList(): LiveData<List<CryptoDeviceInfo>>
 
+    fun getLiveDeviceWithId(deviceId: String): LiveData<Optional<CryptoDeviceInfo>>
+
     fun getMyDevicesInfo(): List<DeviceInfo>
 
     fun getLiveMyDevicesInfo(): LiveData<List<DeviceInfo>>
 
+    fun getLiveMyDevicesInfo(deviceId: String): LiveData<Optional<DeviceInfo>>
+
     fun saveMyDevicesInfo(info: List<DeviceInfo>)
 
     /**
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt
index f5468634cb..3b8fa4cacd 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt
@@ -55,6 +55,7 @@ import org.matrix.android.sdk.internal.crypto.model.OlmSessionWrapper
 import org.matrix.android.sdk.internal.crypto.model.OutboundGroupSessionWrapper
 import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore
 import org.matrix.android.sdk.internal.crypto.store.db.mapper.CrossSigningKeysMapper
+import org.matrix.android.sdk.internal.crypto.store.db.mapper.MyDeviceLastSeenInfoEntityMapper
 import org.matrix.android.sdk.internal.crypto.store.db.model.AuditTrailEntity
 import org.matrix.android.sdk.internal.crypto.store.db.model.AuditTrailEntityFields
 import org.matrix.android.sdk.internal.crypto.store.db.model.AuditTrailMapper
@@ -68,6 +69,7 @@ import org.matrix.android.sdk.internal.crypto.store.db.model.DeviceInfoEntity
 import org.matrix.android.sdk.internal.crypto.store.db.model.DeviceInfoEntityFields
 import org.matrix.android.sdk.internal.crypto.store.db.model.KeysBackupDataEntity
 import org.matrix.android.sdk.internal.crypto.store.db.model.MyDeviceLastSeenInfoEntity
+import org.matrix.android.sdk.internal.crypto.store.db.model.MyDeviceLastSeenInfoEntityFields
 import org.matrix.android.sdk.internal.crypto.store.db.model.OlmInboundGroupSessionEntity
 import org.matrix.android.sdk.internal.crypto.store.db.model.OlmInboundGroupSessionEntityFields
 import org.matrix.android.sdk.internal.crypto.store.db.model.OlmSessionEntity
@@ -112,6 +114,7 @@ internal class RealmCryptoStore @Inject constructor(
         @UserId private val userId: String,
         @DeviceId private val deviceId: String?,
         private val clock: Clock,
+        private val myDeviceLastSeenInfoEntityMapper: MyDeviceLastSeenInfoEntityMapper,
 ) : IMXCryptoStore {
 
     /* ==========================================================================================
@@ -578,6 +581,12 @@ internal class RealmCryptoStore @Inject constructor(
         }
     }
 
+    override fun getLiveDeviceWithId(deviceId: String): LiveData<Optional<CryptoDeviceInfo>> {
+        return Transformations.map(getLiveDeviceList()) { devices ->
+            devices.firstOrNull { it.deviceId == deviceId }.toOptional()
+        }
+    }
+
     override fun getMyDevicesInfo(): List<DeviceInfo> {
         return monarchy.fetchAllCopiedSync {
             it.where<MyDeviceLastSeenInfoEntity>()
@@ -596,17 +605,24 @@ internal class RealmCryptoStore @Inject constructor(
                 { realm: Realm ->
                     realm.where<MyDeviceLastSeenInfoEntity>()
                 },
-                { entity ->
-                    DeviceInfo(
-                            deviceId = entity.deviceId,
-                            lastSeenIp = entity.lastSeenIp,
-                            lastSeenTs = entity.lastSeenTs,
-                            displayName = entity.displayName
-                    )
-                }
+                { entity -> myDeviceLastSeenInfoEntityMapper.map(entity) }
         )
     }
 
+    override fun getLiveMyDevicesInfo(deviceId: String): LiveData<Optional<DeviceInfo>> {
+        val liveData = monarchy.findAllMappedWithChanges(
+                { realm: Realm ->
+                    realm.where<MyDeviceLastSeenInfoEntity>()
+                            .equalTo(MyDeviceLastSeenInfoEntityFields.DEVICE_ID, deviceId)
+                },
+                { entity -> myDeviceLastSeenInfoEntityMapper.map(entity) }
+        )
+
+        return Transformations.map(liveData) {
+            it.firstOrNull().toOptional()
+        }
+    }
+
     override fun saveMyDevicesInfo(info: List<DeviceInfo>) {
         val entities = info.map {
             MyDeviceLastSeenInfoEntity(
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/mapper/MyDeviceLastSeenInfoEntityMapper.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/mapper/MyDeviceLastSeenInfoEntityMapper.kt
new file mode 100644
index 0000000000..38a7569aab
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/mapper/MyDeviceLastSeenInfoEntityMapper.kt
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2022 The Matrix.org Foundation C.I.C.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.matrix.android.sdk.internal.crypto.store.db.mapper
+
+import org.matrix.android.sdk.api.session.crypto.model.DeviceInfo
+import org.matrix.android.sdk.internal.crypto.store.db.model.MyDeviceLastSeenInfoEntity
+import javax.inject.Inject
+
+internal class MyDeviceLastSeenInfoEntityMapper @Inject constructor() {
+
+    fun map(entity: MyDeviceLastSeenInfoEntity): DeviceInfo {
+        return DeviceInfo(
+                deviceId = entity.deviceId,
+                lastSeenIp = entity.lastSeenIp,
+                lastSeenTs = entity.lastSeenTs,
+                displayName = entity.displayName
+        )
+    }
+}
diff --git a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/crypto/store/db/mapper/MyDeviceLastSeenInfoEntityMapperTest.kt b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/crypto/store/db/mapper/MyDeviceLastSeenInfoEntityMapperTest.kt
new file mode 100644
index 0000000000..a27f430edc
--- /dev/null
+++ b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/crypto/store/db/mapper/MyDeviceLastSeenInfoEntityMapperTest.kt
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2022 The Matrix.org Foundation C.I.C.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.matrix.android.sdk.internal.crypto.store.db.mapper
+
+import org.amshove.kluent.shouldBeEqualTo
+import org.junit.Test
+import org.matrix.android.sdk.api.session.crypto.model.DeviceInfo
+import org.matrix.android.sdk.internal.crypto.store.db.model.MyDeviceLastSeenInfoEntity
+
+private const val A_DEVICE_ID = "device-id"
+private const val AN_IP_ADDRESS = "ip-address"
+private const val A_TIMESTAMP = 123L
+private const val A_DISPLAY_NAME = "display-name"
+
+class MyDeviceLastSeenInfoEntityMapperTest {
+
+    private val myDeviceLastSeenInfoEntityMapper = MyDeviceLastSeenInfoEntityMapper()
+
+    @Test
+    fun `given an entity when mapping to model then all fields are correctly mapped`() {
+        val entity = MyDeviceLastSeenInfoEntity(
+                deviceId = A_DEVICE_ID,
+                lastSeenIp = AN_IP_ADDRESS,
+                lastSeenTs = A_TIMESTAMP,
+                displayName = A_DISPLAY_NAME
+        )
+        val expectedDeviceInfo = DeviceInfo(
+                deviceId = A_DEVICE_ID,
+                lastSeenIp = AN_IP_ADDRESS,
+                lastSeenTs = A_TIMESTAMP,
+                displayName = A_DISPLAY_NAME
+        )
+
+        val deviceInfo = myDeviceLastSeenInfoEntityMapper.map(entity)
+
+        deviceInfo shouldBeEqualTo expectedDeviceInfo
+    }
+}
diff --git a/vector/src/main/AndroidManifest.xml b/vector/src/main/AndroidManifest.xml
index c4022576c3..cd2fd52b32 100644
--- a/vector/src/main/AndroidManifest.xml
+++ b/vector/src/main/AndroidManifest.xml
@@ -339,6 +339,7 @@
         <activity android:name=".features.call.dialpad.PstnDialActivity" />
         <activity android:name=".features.home.room.list.home.invites.InvitesActivity"/>
         <activity android:name=".features.home.room.list.home.release.ReleaseNotesActivity"/>
+        <activity android:name=".features.settings.devices.v2.overview.SessionOverviewActivity"/>
 
         <!-- Services -->
 
diff --git a/vector/src/main/java/im/vector/app/core/di/MavericksViewModelModule.kt b/vector/src/main/java/im/vector/app/core/di/MavericksViewModelModule.kt
index a40aeaaa15..40484f57e8 100644
--- a/vector/src/main/java/im/vector/app/core/di/MavericksViewModelModule.kt
+++ b/vector/src/main/java/im/vector/app/core/di/MavericksViewModelModule.kt
@@ -88,6 +88,7 @@ import im.vector.app.features.settings.account.deactivation.DeactivateAccountVie
 import im.vector.app.features.settings.crosssigning.CrossSigningSettingsViewModel
 import im.vector.app.features.settings.devices.DeviceVerificationInfoBottomSheetViewModel
 import im.vector.app.features.settings.devices.DevicesViewModel
+import im.vector.app.features.settings.devices.v2.overview.SessionOverviewViewModel
 import im.vector.app.features.settings.devtools.AccountDataViewModel
 import im.vector.app.features.settings.devtools.GossipingEventsPaperTrailViewModel
 import im.vector.app.features.settings.devtools.KeyRequestListViewModel
@@ -630,4 +631,9 @@ interface MavericksViewModelModule {
     @IntoMap
     @MavericksViewModelKey(ReleaseNotesViewModel::class)
     fun releaseNotesViewModel(factory: ReleaseNotesViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
+
+    @Binds
+    @IntoMap
+    @MavericksViewModelKey(SessionOverviewViewModel::class)
+    fun sessionOverviewViewModelFactory(factory: SessionOverviewViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
 }
diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/MessageInformationDataFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/MessageInformationDataFactory.kt
index 6d94837f88..b711bf37bd 100644
--- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/MessageInformationDataFactory.kt
+++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/MessageInformationDataFactory.kt
@@ -162,7 +162,7 @@ class MessageInformationDataFactory @Inject constructor(
                             .toModel<EncryptedEventContent>()
                             ?.deviceId
                             ?.let { deviceId ->
-                                session.cryptoService().getDeviceInfo(event.root.senderId ?: "", deviceId)
+                                session.cryptoService().getCryptoDeviceInfo(event.root.senderId ?: "", deviceId)
                             }
                     when {
                         sendingDevice == null -> {
diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsSecurityPrivacyFragment.kt b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsSecurityPrivacyFragment.kt
index 2b4d376f55..ecb1779a4a 100644
--- a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsSecurityPrivacyFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsSecurityPrivacyFragment.kt
@@ -585,7 +585,7 @@ class VectorSettingsSecurityPrivacyFragment :
         }
 
         // crypto section: device key (fingerprint)
-        val deviceInfo = session.cryptoService().getDeviceInfo(userId, deviceId)
+        val deviceInfo = session.cryptoService().getCryptoDeviceInfo(userId, deviceId)
 
         val fingerprint = deviceInfo?.fingerprint()
         if (fingerprint?.isNotEmpty() == true) {
diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/CurrentSessionCrossSigningInfo.kt b/vector/src/main/java/im/vector/app/features/settings/devices/CurrentSessionCrossSigningInfo.kt
new file mode 100644
index 0000000000..790de08823
--- /dev/null
+++ b/vector/src/main/java/im/vector/app/features/settings/devices/CurrentSessionCrossSigningInfo.kt
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2022 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.app.features.settings.devices
+
+/**
+ * Used to hold some info about the cross signing of the current Session.
+ */
+data class CurrentSessionCrossSigningInfo(
+        val deviceId: String?,
+        val isCrossSigningInitialized: Boolean,
+        val isCrossSigningVerified: Boolean,
+)
diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/DevicesViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/devices/DevicesViewModel.kt
index 3b5bcb61d9..82c346b09c 100644
--- a/vector/src/main/java/im/vector/app/features/settings/devices/DevicesViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/devices/DevicesViewModel.kt
@@ -101,6 +101,8 @@ class DevicesViewModel @AssistedInject constructor(
         private val stringProvider: StringProvider,
         private val matrix: Matrix,
         private val checkIfSessionIsInactiveUseCase: CheckIfSessionIsInactiveUseCase,
+        getCurrentSessionCrossSigningInfoUseCase: GetCurrentSessionCrossSigningInfoUseCase,
+        private val getEncryptionTrustLevelForDeviceUseCase: GetEncryptionTrustLevelForDeviceUseCase,
 ) : VectorViewModel<DevicesViewState, DevicesAction, DevicesViewEvents>(initialState), VerificationService.Listener {
 
     var uiaContinuation: Continuation<UIABaseAuth>? = null
@@ -116,8 +118,9 @@ class DevicesViewModel @AssistedInject constructor(
     private val refreshSource = PublishDataSource<Unit>()
 
     init {
-        val hasAccountCrossSigning = session.cryptoService().crossSigningService().isCrossSigningInitialized()
-        val accountCrossSigningIsTrusted = session.cryptoService().crossSigningService().isCrossSigningVerified()
+        val currentSessionCrossSigningInfo = getCurrentSessionCrossSigningInfoUseCase.execute()
+        val hasAccountCrossSigning = currentSessionCrossSigningInfo.isCrossSigningInitialized
+        val accountCrossSigningIsTrusted = currentSessionCrossSigningInfo.isCrossSigningVerified
 
         setState {
             copy(
@@ -143,12 +146,7 @@ class DevicesViewModel @AssistedInject constructor(
                     .sortedByDescending { it.lastSeenTs }
                     .map { deviceInfo ->
                         val cryptoDeviceInfo = cryptoList.firstOrNull { it.deviceId == deviceInfo.deviceId }
-                        val trustLevelForShield = computeTrustLevelForShield(
-                                currentSessionCrossTrusted = accountCrossSigningIsTrusted,
-                                legacyMode = !hasAccountCrossSigning,
-                                deviceTrustLevel = cryptoDeviceInfo?.trustLevel,
-                                isCurrentDevice = deviceInfo.deviceId == session.sessionParams.deviceId
-                        )
+                        val trustLevelForShield = getEncryptionTrustLevelForDeviceUseCase.execute(currentSessionCrossSigningInfo, cryptoDeviceInfo)
                         val isInactive = checkIfSessionIsInactiveUseCase.execute(deviceInfo.lastSeenTs ?: 0)
                         DeviceFullInfo(deviceInfo, cryptoDeviceInfo, trustLevelForShield, isInactive)
                     }
@@ -268,20 +266,6 @@ class DevicesViewModel @AssistedInject constructor(
         }
     }
 
-    private fun computeTrustLevelForShield(
-            currentSessionCrossTrusted: Boolean,
-            legacyMode: Boolean,
-            deviceTrustLevel: DeviceTrustLevel?,
-            isCurrentDevice: Boolean,
-    ): RoomEncryptionTrustLevel {
-        return TrustUtils.shieldForTrust(
-                currentDevice = isCurrentDevice,
-                trustMSK = currentSessionCrossTrusted,
-                legacyMode = legacyMode,
-                deviceTrustLevel = deviceTrustLevel
-        )
-    }
-
     private fun handleInteractiveVerification(action: DevicesAction.VerifyMyDevice) {
         val txID = session.cryptoService()
                 .verificationService()
diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/GetCurrentSessionCrossSigningInfoUseCase.kt b/vector/src/main/java/im/vector/app/features/settings/devices/GetCurrentSessionCrossSigningInfoUseCase.kt
new file mode 100644
index 0000000000..d07bd5daae
--- /dev/null
+++ b/vector/src/main/java/im/vector/app/features/settings/devices/GetCurrentSessionCrossSigningInfoUseCase.kt
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2022 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.app.features.settings.devices
+
+import im.vector.app.core.di.ActiveSessionHolder
+import javax.inject.Inject
+
+class GetCurrentSessionCrossSigningInfoUseCase @Inject constructor(
+        private val activeSessionHolder: ActiveSessionHolder,
+) {
+
+    fun execute(): CurrentSessionCrossSigningInfo {
+        val session = activeSessionHolder.getActiveSession()
+        val isCrossSigningInitialized = session.cryptoService().crossSigningService().isCrossSigningInitialized()
+        val isCrossSigningVerified = session.cryptoService().crossSigningService().isCrossSigningVerified()
+        return CurrentSessionCrossSigningInfo(
+                deviceId = session.sessionParams.deviceId,
+                isCrossSigningInitialized = isCrossSigningInitialized,
+                isCrossSigningVerified = isCrossSigningVerified
+        )
+    }
+}
diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/GetEncryptionTrustLevelForCurrentDeviceUseCase.kt b/vector/src/main/java/im/vector/app/features/settings/devices/GetEncryptionTrustLevelForCurrentDeviceUseCase.kt
new file mode 100644
index 0000000000..0d30aba318
--- /dev/null
+++ b/vector/src/main/java/im/vector/app/features/settings/devices/GetEncryptionTrustLevelForCurrentDeviceUseCase.kt
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2022 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.app.features.settings.devices
+
+import org.matrix.android.sdk.api.session.crypto.model.RoomEncryptionTrustLevel
+import javax.inject.Inject
+
+class GetEncryptionTrustLevelForCurrentDeviceUseCase @Inject constructor() {
+
+    fun execute(trustMSK: Boolean, legacyMode: Boolean): RoomEncryptionTrustLevel {
+        return if (legacyMode) {
+            // In legacy, current session is always trusted
+            RoomEncryptionTrustLevel.Trusted
+        } else {
+            // If current session doesn't trust MSK, show red shield for current device
+            if (trustMSK) {
+                RoomEncryptionTrustLevel.Trusted
+            } else {
+                RoomEncryptionTrustLevel.Warning
+            }
+        }
+    }
+}
diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/GetEncryptionTrustLevelForDeviceUseCase.kt b/vector/src/main/java/im/vector/app/features/settings/devices/GetEncryptionTrustLevelForDeviceUseCase.kt
new file mode 100644
index 0000000000..e5ef4b446b
--- /dev/null
+++ b/vector/src/main/java/im/vector/app/features/settings/devices/GetEncryptionTrustLevelForDeviceUseCase.kt
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2022 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.app.features.settings.devices
+
+import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo
+import org.matrix.android.sdk.api.session.crypto.model.RoomEncryptionTrustLevel
+import javax.inject.Inject
+
+class GetEncryptionTrustLevelForDeviceUseCase @Inject constructor(
+        private val getEncryptionTrustLevelForCurrentDeviceUseCase: GetEncryptionTrustLevelForCurrentDeviceUseCase,
+        private val getEncryptionTrustLevelForOtherDeviceUseCase: GetEncryptionTrustLevelForOtherDeviceUseCase,
+) {
+
+    fun execute(currentSessionCrossSigningInfo: CurrentSessionCrossSigningInfo, cryptoDeviceInfo: CryptoDeviceInfo?): RoomEncryptionTrustLevel {
+        val legacyMode = !currentSessionCrossSigningInfo.isCrossSigningInitialized
+        val trustMSK = currentSessionCrossSigningInfo.isCrossSigningVerified
+        val isCurrentDevice = !cryptoDeviceInfo?.deviceId.isNullOrEmpty() && cryptoDeviceInfo?.deviceId == currentSessionCrossSigningInfo.deviceId
+        val deviceTrustLevel = cryptoDeviceInfo?.trustLevel
+
+        return when {
+            isCurrentDevice -> getEncryptionTrustLevelForCurrentDeviceUseCase.execute(trustMSK, legacyMode)
+            else -> getEncryptionTrustLevelForOtherDeviceUseCase.execute(trustMSK, legacyMode, deviceTrustLevel)
+        }
+    }
+}
diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/GetEncryptionTrustLevelForOtherDeviceUseCase.kt b/vector/src/main/java/im/vector/app/features/settings/devices/GetEncryptionTrustLevelForOtherDeviceUseCase.kt
new file mode 100644
index 0000000000..11bc3a8ede
--- /dev/null
+++ b/vector/src/main/java/im/vector/app/features/settings/devices/GetEncryptionTrustLevelForOtherDeviceUseCase.kt
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2022 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.app.features.settings.devices
+
+import org.matrix.android.sdk.api.session.crypto.crosssigning.DeviceTrustLevel
+import org.matrix.android.sdk.api.session.crypto.model.RoomEncryptionTrustLevel
+import javax.inject.Inject
+
+class GetEncryptionTrustLevelForOtherDeviceUseCase @Inject constructor() {
+
+    fun execute(trustMSK: Boolean, legacyMode: Boolean, deviceTrustLevel: DeviceTrustLevel?): RoomEncryptionTrustLevel {
+        return if (legacyMode) {
+            // use local trust
+            if (deviceTrustLevel?.locallyVerified == true) {
+                RoomEncryptionTrustLevel.Trusted
+            } else {
+                RoomEncryptionTrustLevel.Warning
+            }
+        } else {
+            if (trustMSK) {
+                // use cross sign trust, put locally trusted in black
+                when {
+                    deviceTrustLevel?.crossSigningVerified == true -> RoomEncryptionTrustLevel.Trusted
+                    deviceTrustLevel?.locallyVerified == true -> RoomEncryptionTrustLevel.Default
+                    else -> RoomEncryptionTrustLevel.Warning
+                }
+            } else {
+                // The current session is untrusted, so displays others in black
+                // as we can't know the cross-signing state
+                RoomEncryptionTrustLevel.Default
+            }
+        }
+    }
+}
diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/TrustUtils.kt b/vector/src/main/java/im/vector/app/features/settings/devices/TrustUtils.kt
index da18154ea1..7709a63344 100644
--- a/vector/src/main/java/im/vector/app/features/settings/devices/TrustUtils.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/devices/TrustUtils.kt
@@ -19,6 +19,7 @@ package im.vector.app.features.settings.devices
 import org.matrix.android.sdk.api.session.crypto.crosssigning.DeviceTrustLevel
 import org.matrix.android.sdk.api.session.crypto.model.RoomEncryptionTrustLevel
 
+// TODO Replace usage by the use case GetEncryptionTrustLevelForDeviceUseCase
 object TrustUtils {
 
     fun shieldForTrust(
diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/VectorSettingsDevicesFragment.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/VectorSettingsDevicesFragment.kt
index 4bb1d1131b..dc72d4fe9c 100644
--- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/VectorSettingsDevicesFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/VectorSettingsDevicesFragment.kt
@@ -31,8 +31,11 @@ import com.airbnb.mvrx.fragmentViewModel
 import com.airbnb.mvrx.withState
 import dagger.hilt.android.AndroidEntryPoint
 import im.vector.app.R
+import im.vector.app.core.date.VectorDateFormatter
 import im.vector.app.core.dialogs.ManuallyVerifyDialog
 import im.vector.app.core.platform.VectorBaseFragment
+import im.vector.app.core.resources.ColorProvider
+import im.vector.app.core.resources.DrawableProvider
 import im.vector.app.databinding.FragmentSettingsDevicesBinding
 import im.vector.app.features.crypto.recover.SetupMode
 import im.vector.app.features.crypto.verification.VerificationBottomSheet
@@ -40,8 +43,11 @@ import im.vector.app.features.settings.devices.DeviceFullInfo
 import im.vector.app.features.settings.devices.DevicesAction
 import im.vector.app.features.settings.devices.DevicesViewEvents
 import im.vector.app.features.settings.devices.DevicesViewModel
+import im.vector.app.features.settings.devices.v2.list.OtherSessionsController
 import im.vector.app.features.settings.devices.v2.list.SESSION_IS_MARKED_AS_INACTIVE_AFTER_DAYS
 import im.vector.app.features.settings.devices.v2.list.SecurityRecommendationViewState
+import im.vector.app.features.settings.devices.v2.list.SessionInfoViewState
+import javax.inject.Inject
 
 /**
  * Display the list of the user's devices and sessions.
@@ -50,6 +56,14 @@ import im.vector.app.features.settings.devices.v2.list.SecurityRecommendationVie
 class VectorSettingsDevicesFragment :
         VectorBaseFragment<FragmentSettingsDevicesBinding>() {
 
+    @Inject lateinit var viewNavigator: VectorSettingsDevicesViewNavigator
+
+    @Inject lateinit var dateFormatter: VectorDateFormatter
+
+    @Inject lateinit var drawableProvider: DrawableProvider
+
+    @Inject lateinit var colorProvider: ColorProvider
+
     private val viewModel: DevicesViewModel by fragmentViewModel()
 
     override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentSettingsDevicesBinding {
@@ -72,10 +86,11 @@ class VectorSettingsDevicesFragment :
 
         initLearnMoreButtons()
         initWaitingView()
-        observerViewEvents()
+        initOtherSessionsView()
+        observeViewEvents()
     }
 
-    private fun observerViewEvents() {
+    private fun observeViewEvents() {
         viewModel.observeViewEvents {
             when (it) {
                 is DevicesViewEvents.Loading -> showLoading(it.message)
@@ -110,6 +125,14 @@ class VectorSettingsDevicesFragment :
         views.waitingView.waitingStatusText.isVisible = true
     }
 
+    private fun initOtherSessionsView() {
+        views.deviceListOtherSessions.setCallback(object : OtherSessionsController.Callback {
+            override fun onItemClicked(deviceId: String) {
+                navigateToSessionOverview(deviceId)
+            }
+        })
+    }
+
     override fun onDestroyView() {
         cleanUpLearnMoreButtonsListeners()
         super.onDestroyView()
@@ -196,16 +219,39 @@ class VectorSettingsDevicesFragment :
         currentDeviceInfo?.let {
             views.deviceListHeaderCurrentSession.isVisible = true
             views.deviceListCurrentSession.isVisible = true
-            views.deviceListCurrentSession.render(it)
+            val viewState = SessionInfoViewState(
+                    isCurrentSession = true,
+                    deviceFullInfo = it
+            )
+            views.deviceListCurrentSession.render(viewState, dateFormatter, drawableProvider, colorProvider)
+            views.deviceListCurrentSession.debouncedClicks {
+                currentDeviceInfo.deviceInfo.deviceId?.let { deviceId -> navigateToSessionOverview(deviceId) }
+            }
+            views.deviceListCurrentSession.viewDetailsButton.debouncedClicks {
+                currentDeviceInfo.deviceInfo.deviceId?.let { deviceId -> navigateToSessionOverview(deviceId) }
+            }
         } ?: run {
             hideCurrentSessionView()
         }
     }
 
+    private fun navigateToSessionOverview(deviceId: String) {
+        viewNavigator.navigateToSessionOverview(
+                context = requireActivity(),
+                deviceId = deviceId
+        )
+    }
+
     private fun hideCurrentSessionView() {
         views.deviceListHeaderCurrentSession.isVisible = false
         views.deviceListCurrentSession.isVisible = false
         views.deviceListDividerCurrentSession.isVisible = false
+        views.deviceListCurrentSession.debouncedClicks {
+            // do nothing
+        }
+        views.deviceListCurrentSession.viewDetailsButton.debouncedClicks {
+            // do nothing
+        }
     }
 
     private fun handleRequestStatus(unIgnoreRequest: Async<Unit>) {
diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/VectorSettingsDevicesViewNavigator.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/VectorSettingsDevicesViewNavigator.kt
new file mode 100644
index 0000000000..54eed3bc14
--- /dev/null
+++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/VectorSettingsDevicesViewNavigator.kt
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2022 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.app.features.settings.devices.v2
+
+import android.content.Context
+import im.vector.app.features.settings.devices.v2.overview.SessionOverviewActivity
+import javax.inject.Inject
+
+class VectorSettingsDevicesViewNavigator @Inject constructor() {
+
+    fun navigateToSessionOverview(context: Context, deviceId: String) {
+        context.startActivity(SessionOverviewActivity.newIntent(context, deviceId))
+    }
+}
diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/list/CurrentSessionView.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/list/CurrentSessionView.kt
deleted file mode 100644
index d6f81f4f79..0000000000
--- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/list/CurrentSessionView.kt
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (c) 2022 New Vector Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package im.vector.app.features.settings.devices.v2.list
-
-import android.content.Context
-import android.util.AttributeSet
-import androidx.constraintlayout.widget.ConstraintLayout
-import androidx.core.view.isVisible
-import im.vector.app.R
-import im.vector.app.databinding.ViewCurrentSessionBinding
-import im.vector.app.features.settings.devices.DeviceFullInfo
-import im.vector.app.features.themes.ThemeUtils
-import org.matrix.android.sdk.api.session.crypto.model.RoomEncryptionTrustLevel
-
-class CurrentSessionView @JvmOverloads constructor(
-        context: Context,
-        attrs: AttributeSet? = null,
-        defStyleAttr: Int = 0
-) : ConstraintLayout(context, attrs, defStyleAttr) {
-
-    private val views: ViewCurrentSessionBinding
-
-    init {
-        inflate(context, R.layout.view_current_session, this)
-        views = ViewCurrentSessionBinding.bind(this)
-    }
-
-    fun render(currentDeviceInfo: DeviceFullInfo) {
-        renderDeviceInfo(currentDeviceInfo.deviceInfo.displayName.orEmpty())
-        renderVerificationStatus(currentDeviceInfo.trustLevelForShield)
-    }
-
-    private fun renderVerificationStatus(trustLevelForShield: RoomEncryptionTrustLevel) {
-        views.currentSessionVerificationStatusImageView.render(trustLevelForShield)
-        if (trustLevelForShield == RoomEncryptionTrustLevel.Trusted) {
-            renderCrossSigningVerified()
-        } else {
-            renderCrossSigningUnverified()
-        }
-    }
-
-    private fun renderCrossSigningVerified() {
-        views.currentSessionVerificationStatusTextView.text = context.getString(R.string.device_manager_verification_status_verified)
-        views.currentSessionVerificationStatusTextView.setTextColor(ThemeUtils.getColor(context, R.attr.colorPrimary))
-        views.currentSessionVerificationStatusDetailTextView.text = context.getString(R.string.device_manager_verification_status_detail_verified)
-        views.currentSessionVerifySessionButton.isVisible = false
-    }
-
-    private fun renderCrossSigningUnverified() {
-        views.currentSessionVerificationStatusTextView.text = context.getString(R.string.device_manager_verification_status_unverified)
-        views.currentSessionVerificationStatusTextView.setTextColor(ThemeUtils.getColor(context, R.attr.colorError))
-        views.currentSessionVerificationStatusDetailTextView.text = context.getString(R.string.device_manager_verification_status_detail_unverified)
-        views.currentSessionVerifySessionButton.isVisible = true
-    }
-
-    // TODO. We don't have this info yet. Update later accordingly.
-    private fun renderDeviceInfo(sessionName: String) {
-        views.currentSessionDeviceTypeImageView.setImageResource(R.drawable.ic_device_type_mobile)
-        views.currentSessionDeviceTypeImageView.contentDescription = context.getString(R.string.a11y_device_manager_device_type_mobile)
-        views.currentSessionNameTextView.text = sessionName
-    }
-}
diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/list/OtherSessionItem.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/list/OtherSessionItem.kt
index e9376953e0..c73389d775 100644
--- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/list/OtherSessionItem.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/list/OtherSessionItem.kt
@@ -22,8 +22,10 @@ import android.widget.TextView
 import com.airbnb.epoxy.EpoxyAttribute
 import com.airbnb.epoxy.EpoxyModelClass
 import im.vector.app.R
+import im.vector.app.core.epoxy.ClickListener
 import im.vector.app.core.epoxy.VectorEpoxyHolder
 import im.vector.app.core.epoxy.VectorEpoxyModel
+import im.vector.app.core.epoxy.onClick
 import im.vector.app.core.resources.StringProvider
 import im.vector.app.core.ui.views.ShieldImageView
 import org.matrix.android.sdk.api.session.crypto.model.RoomEncryptionTrustLevel
@@ -49,8 +51,16 @@ abstract class OtherSessionItem : VectorEpoxyModel<OtherSessionItem.Holder>(R.la
     @EpoxyAttribute
     lateinit var stringProvider: StringProvider
 
+    @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash)
+    var clickListener: ClickListener? = null
+
     override fun bind(holder: Holder) {
         super.bind(holder)
+        holder.view.onClick(clickListener)
+        if (clickListener == null) {
+            holder.view.isClickable = false
+        }
+
         when (deviceType) {
             DeviceType.MOBILE -> {
                 holder.otherSessionDeviceTypeImageView.setImageResource(R.drawable.ic_device_type_mobile)
diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/list/OtherSessionsController.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/list/OtherSessionsController.kt
index 8a5ee05af7..6419d02fc9 100644
--- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/list/OtherSessionsController.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/list/OtherSessionsController.kt
@@ -35,6 +35,12 @@ class OtherSessionsController @Inject constructor(
         private val colorProvider: ColorProvider,
 ) : TypedEpoxyController<List<DeviceFullInfo>>() {
 
+    var callback: Callback? = null
+
+    interface Callback {
+        fun onItemClicked(deviceId: String)
+    }
+
     override fun buildModels(data: List<DeviceFullInfo>?) {
         val host = this
 
@@ -70,6 +76,7 @@ class OtherSessionsController @Inject constructor(
                     sessionDescription(description)
                     sessionDescriptionDrawable(descriptionDrawable)
                     stringProvider(this@OtherSessionsController.stringProvider)
+                    clickListener { device.deviceInfo.deviceId?.let { host.callback?.onItemClicked(it) } }
                 }
             }
         }
diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/list/OtherSessionsView.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/list/OtherSessionsView.kt
index 55978e61fd..682a9c6e64 100644
--- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/list/OtherSessionsView.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/list/OtherSessionsView.kt
@@ -49,7 +49,12 @@ class OtherSessionsView @JvmOverloads constructor(
         otherSessionsController.setData(devices)
     }
 
+    fun setCallback(callback: OtherSessionsController.Callback) {
+        otherSessionsController.callback = callback
+    }
+
     override fun onDetachedFromWindow() {
+        otherSessionsController.callback = null
         views.otherSessionsRecyclerView.cleanup()
         super.onDetachedFromWindow()
     }
diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/list/SessionInfoView.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/list/SessionInfoView.kt
new file mode 100644
index 0000000000..767f09482b
--- /dev/null
+++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/list/SessionInfoView.kt
@@ -0,0 +1,189 @@
+/*
+ * Copyright (c) 2022 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.app.features.settings.devices.v2.list
+
+import android.content.Context
+import android.util.AttributeSet
+import androidx.constraintlayout.widget.ConstraintLayout
+import androidx.core.view.isGone
+import androidx.core.view.isVisible
+import im.vector.app.R
+import im.vector.app.core.date.DateFormatKind
+import im.vector.app.core.date.VectorDateFormatter
+import im.vector.app.core.extensions.setTextWithColoredPart
+import im.vector.app.core.resources.ColorProvider
+import im.vector.app.core.resources.DrawableProvider
+import im.vector.app.databinding.ViewSessionInfoBinding
+import im.vector.app.features.themes.ThemeUtils
+import org.matrix.android.sdk.api.session.crypto.model.DeviceInfo
+import org.matrix.android.sdk.api.session.crypto.model.RoomEncryptionTrustLevel
+
+class SessionInfoView @JvmOverloads constructor(
+        context: Context,
+        attrs: AttributeSet? = null,
+        defStyleAttr: Int = 0
+) : ConstraintLayout(context, attrs, defStyleAttr) {
+
+    private val views: ViewSessionInfoBinding
+
+    var onLearnMoreClickListener: (() -> Unit)? = null
+
+    init {
+        inflate(context, R.layout.view_session_info, this)
+        views = ViewSessionInfoBinding.bind(this)
+    }
+
+    val viewDetailsButton = views.sessionInfoViewDetailsButton
+
+    fun render(
+            sessionInfoViewState: SessionInfoViewState,
+            dateFormatter: VectorDateFormatter,
+            drawableProvider: DrawableProvider,
+            colorProvider: ColorProvider,
+    ) {
+        renderDeviceInfo(sessionInfoViewState.deviceFullInfo.deviceInfo.displayName.orEmpty())
+        renderVerificationStatus(
+                sessionInfoViewState.deviceFullInfo.trustLevelForShield,
+                sessionInfoViewState.isCurrentSession,
+                sessionInfoViewState.isLearnMoreLinkVisible,
+        )
+        renderDeviceLastSeenDetails(
+                sessionInfoViewState.deviceFullInfo.isInactive,
+                sessionInfoViewState.deviceFullInfo.deviceInfo,
+                sessionInfoViewState.isLastSeenDetailsVisible,
+                dateFormatter,
+                drawableProvider,
+                colorProvider,
+        )
+        renderDetailsButton(sessionInfoViewState.isDetailsButtonVisible)
+    }
+
+    private fun renderVerificationStatus(
+            encryptionTrustLevel: RoomEncryptionTrustLevel,
+            isCurrentSession: Boolean,
+            hasLearnMoreLink: Boolean,
+    ) {
+        views.sessionInfoVerificationStatusImageView.render(encryptionTrustLevel)
+        if (encryptionTrustLevel == RoomEncryptionTrustLevel.Trusted) {
+            renderCrossSigningVerified(isCurrentSession)
+        } else {
+            renderCrossSigningUnverified(isCurrentSession)
+        }
+        if (hasLearnMoreLink) {
+            appendLearnMoreToVerificationStatus()
+        }
+    }
+
+    private fun appendLearnMoreToVerificationStatus() {
+        val status = views.sessionInfoVerificationStatusDetailTextView.text
+        val learnMore = context.getString(R.string.action_learn_more)
+        val stringBuilder = StringBuilder()
+        stringBuilder.append(status)
+        stringBuilder.append(" ")
+        stringBuilder.append(learnMore)
+
+        views.sessionInfoVerificationStatusDetailTextView.setTextWithColoredPart(
+                fullText = stringBuilder.toString(),
+                coloredPart = learnMore,
+                underline = false
+        ) {
+            onLearnMoreClickListener?.invoke()
+        }
+    }
+
+    private fun renderCrossSigningVerified(isCurrentSession: Boolean) {
+        views.sessionInfoVerificationStatusTextView.text = context.getString(R.string.device_manager_verification_status_verified)
+        views.sessionInfoVerificationStatusTextView.setTextColor(ThemeUtils.getColor(context, R.attr.colorPrimary))
+        val statusResId = if (isCurrentSession) {
+            R.string.device_manager_verification_status_detail_current_session_verified
+        } else {
+            R.string.device_manager_verification_status_detail_other_session_verified
+        }
+        views.sessionInfoVerificationStatusDetailTextView.text = context.getString(statusResId)
+        views.sessionInfoVerifySessionButton.isVisible = false
+    }
+
+    private fun renderCrossSigningUnverified(isCurrentSession: Boolean) {
+        views.sessionInfoVerificationStatusTextView.text = context.getString(R.string.device_manager_verification_status_unverified)
+        views.sessionInfoVerificationStatusTextView.setTextColor(ThemeUtils.getColor(context, R.attr.colorError))
+        val statusResId = if (isCurrentSession) {
+            R.string.device_manager_verification_status_detail_current_session_unverified
+        } else {
+            R.string.device_manager_verification_status_detail_other_session_unverified
+        }
+        views.sessionInfoVerificationStatusDetailTextView.text = context.getString(statusResId)
+        views.sessionInfoVerifySessionButton.isVisible = true
+    }
+
+    // TODO. We don't have this info yet. Update later accordingly.
+    private fun renderDeviceInfo(sessionName: String) {
+        views.sessionInfoDeviceTypeImageView.setImageResource(R.drawable.ic_device_type_mobile)
+        views.sessionInfoDeviceTypeImageView.contentDescription = context.getString(R.string.a11y_device_manager_device_type_mobile)
+        views.sessionInfoNameTextView.text = sessionName
+    }
+
+    private fun renderDeviceLastSeenDetails(
+            isInactive: Boolean,
+            deviceInfo: DeviceInfo,
+            isLastSeenDetailsVisible: Boolean,
+            dateFormatter: VectorDateFormatter,
+            drawableProvider: DrawableProvider,
+            colorProvider: ColorProvider,
+    ) {
+        deviceInfo.lastSeenTs
+                ?.takeIf { isLastSeenDetailsVisible }
+                ?.let { timestamp ->
+                    views.sessionInfoLastActivityTextView.isVisible = true
+                    views.sessionInfoLastActivityTextView.text = if (isInactive) {
+                        val formattedTs = dateFormatter.format(timestamp, DateFormatKind.TIMELINE_DAY_DIVIDER)
+                        context.resources.getQuantityString(
+                                R.plurals.device_manager_other_sessions_description_inactive,
+                                SESSION_IS_MARKED_AS_INACTIVE_AFTER_DAYS,
+                                SESSION_IS_MARKED_AS_INACTIVE_AFTER_DAYS,
+                                formattedTs
+                        )
+                    } else {
+                        val formattedTs = dateFormatter.format(timestamp, DateFormatKind.DEFAULT_DATE_AND_TIME)
+                        context.getString(R.string.device_manager_session_last_activity, formattedTs)
+                    }
+                    val drawable = if (isInactive) {
+                        val drawableColor = colorProvider.getColorFromAttribute(R.attr.vctr_content_secondary)
+                        drawableProvider.getDrawable(R.drawable.ic_inactive_sessions, drawableColor)
+                    } else {
+                        null
+                    }
+                    views.sessionInfoLastActivityTextView.setCompoundDrawablesWithIntrinsicBounds(drawable, null, null, null)
+                }
+                ?: run {
+                    views.sessionInfoLastActivityTextView.isGone = true
+                }
+
+        deviceInfo.lastSeenIp
+                ?.takeIf { isLastSeenDetailsVisible }
+                ?.let { ipAddress ->
+                    views.sessionInfoLastIPAddressTextView.isVisible = true
+                    views.sessionInfoLastIPAddressTextView.text = ipAddress
+                }
+                ?: run {
+                    views.sessionInfoLastIPAddressTextView.isGone = true
+                }
+    }
+
+    private fun renderDetailsButton(isDetailsButtonVisible: Boolean) {
+        views.sessionInfoViewDetailsButton.isVisible = isDetailsButtonVisible
+    }
+}
diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/list/SessionInfoViewState.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/list/SessionInfoViewState.kt
new file mode 100644
index 0000000000..22ad710676
--- /dev/null
+++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/list/SessionInfoViewState.kt
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2022 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.app.features.settings.devices.v2.list
+
+import im.vector.app.features.settings.devices.DeviceFullInfo
+
+data class SessionInfoViewState(
+        val isCurrentSession: Boolean,
+        val deviceFullInfo: DeviceFullInfo,
+        val isDetailsButtonVisible: Boolean = true,
+        val isLearnMoreLinkVisible: Boolean = false,
+        val isLastSeenDetailsVisible: Boolean = false,
+)
diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/list/DevicesListHeaderView.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/list/SessionsListHeaderView.kt
similarity index 74%
rename from vector/src/main/java/im/vector/app/features/settings/devices/v2/list/DevicesListHeaderView.kt
rename to vector/src/main/java/im/vector/app/features/settings/devices/v2/list/SessionsListHeaderView.kt
index d6c7dbe273..547ed93f24 100644
--- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/list/DevicesListHeaderView.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/list/SessionsListHeaderView.kt
@@ -25,15 +25,15 @@ import androidx.core.content.res.use
 import androidx.core.view.isVisible
 import im.vector.app.R
 import im.vector.app.core.extensions.setTextWithColoredPart
-import im.vector.app.databinding.ViewDevicesListHeaderBinding
+import im.vector.app.databinding.ViewSessionsListHeaderBinding
 
-class DevicesListHeaderView @JvmOverloads constructor(
+class SessionsListHeaderView @JvmOverloads constructor(
         context: Context,
         attrs: AttributeSet? = null,
         defStyleAttr: Int = 0
 ) : ConstraintLayout(context, attrs, defStyleAttr) {
 
-    private val binding = ViewDevicesListHeaderBinding.inflate(
+    private val binding = ViewSessionsListHeaderBinding.inflate(
             LayoutInflater.from(context),
             this
     )
@@ -43,7 +43,7 @@ class DevicesListHeaderView @JvmOverloads constructor(
     init {
         context.obtainStyledAttributes(
                 attrs,
-                R.styleable.DevicesListHeaderView,
+                R.styleable.SessionsListHeaderView,
                 0,
                 0
         ).use {
@@ -53,14 +53,14 @@ class DevicesListHeaderView @JvmOverloads constructor(
     }
 
     private fun setTitle(typedArray: TypedArray) {
-        val title = typedArray.getString(R.styleable.DevicesListHeaderView_devicesListHeaderTitle)
-        binding.devicesListHeaderTitle.text = title
+        val title = typedArray.getString(R.styleable.SessionsListHeaderView_devicesListHeaderTitle)
+        binding.sessionsListHeaderTitle.text = title
     }
 
     private fun setDescription(typedArray: TypedArray) {
-        val description = typedArray.getString(R.styleable.DevicesListHeaderView_devicesListHeaderDescription)
+        val description = typedArray.getString(R.styleable.SessionsListHeaderView_devicesListHeaderDescription)
         if (description.isNullOrEmpty()) {
-            binding.devicesListHeaderDescription.isVisible = false
+            binding.sessionsListHeaderDescription.isVisible = false
             return
         }
 
@@ -70,8 +70,8 @@ class DevicesListHeaderView @JvmOverloads constructor(
         stringBuilder.append(" ")
         stringBuilder.append(learnMore)
 
-        binding.devicesListHeaderDescription.isVisible = true
-        binding.devicesListHeaderDescription.setTextWithColoredPart(
+        binding.sessionsListHeaderDescription.isVisible = true
+        binding.sessionsListHeaderDescription.setTextWithColoredPart(
                 fullText = stringBuilder.toString(),
                 coloredPart = learnMore,
                 underline = false
diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/GetDeviceFullInfoUseCase.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/GetDeviceFullInfoUseCase.kt
new file mode 100644
index 0000000000..c3579b68c3
--- /dev/null
+++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/GetDeviceFullInfoUseCase.kt
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2022 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.app.features.settings.devices.v2.overview
+
+import androidx.lifecycle.asFlow
+import im.vector.app.core.di.ActiveSessionHolder
+import im.vector.app.features.settings.devices.DeviceFullInfo
+import im.vector.app.features.settings.devices.GetCurrentSessionCrossSigningInfoUseCase
+import im.vector.app.features.settings.devices.GetEncryptionTrustLevelForDeviceUseCase
+import im.vector.app.features.settings.devices.v2.list.CheckIfSessionIsInactiveUseCase
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.emptyFlow
+import org.matrix.android.sdk.api.util.Optional
+import org.matrix.android.sdk.api.util.toOptional
+import javax.inject.Inject
+
+class GetDeviceFullInfoUseCase @Inject constructor(
+        private val activeSessionHolder: ActiveSessionHolder,
+        private val getCurrentSessionCrossSigningInfoUseCase: GetCurrentSessionCrossSigningInfoUseCase,
+        private val getEncryptionTrustLevelForDeviceUseCase: GetEncryptionTrustLevelForDeviceUseCase,
+        private val checkIfSessionIsInactiveUseCase: CheckIfSessionIsInactiveUseCase,
+) {
+
+    fun execute(deviceId: String): Flow<Optional<DeviceFullInfo>> {
+        return activeSessionHolder.getSafeActiveSession()?.let { session ->
+            val currentSessionCrossSigningInfo = getCurrentSessionCrossSigningInfoUseCase.execute()
+            combine(
+                    session.cryptoService().getMyDevicesInfoLive(deviceId).asFlow(),
+                    session.cryptoService().getLiveCryptoDeviceInfoWithId(deviceId).asFlow()
+            ) { deviceInfo, cryptoDeviceInfo ->
+                val info = deviceInfo.getOrNull()
+                val cryptoInfo = cryptoDeviceInfo.getOrNull()
+                val fullInfo = if (info != null && cryptoInfo != null) {
+                    val roomEncryptionTrustLevel = getEncryptionTrustLevelForDeviceUseCase.execute(currentSessionCrossSigningInfo, cryptoInfo)
+                    val isInactive = checkIfSessionIsInactiveUseCase.execute(info.lastSeenTs ?: 0)
+                    DeviceFullInfo(
+                            deviceInfo = info,
+                            cryptoDeviceInfo = cryptoInfo,
+                            trustLevelForShield = roomEncryptionTrustLevel,
+                            isInactive = isInactive
+                    )
+                } else {
+                    null
+                }
+                fullInfo.toOptional()
+            }
+        } ?: emptyFlow()
+    }
+}
diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewAction.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewAction.kt
new file mode 100644
index 0000000000..c028c08ec4
--- /dev/null
+++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewAction.kt
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2020 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.app.features.settings.devices.v2.overview
+
+import im.vector.app.core.platform.VectorViewModelAction
+
+sealed class SessionOverviewAction : VectorViewModelAction
diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewActivity.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewActivity.kt
new file mode 100644
index 0000000000..015fcccf51
--- /dev/null
+++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewActivity.kt
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2022 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.app.features.settings.devices.v2.overview
+
+import android.content.Context
+import android.content.Intent
+import android.os.Bundle
+import com.airbnb.mvrx.Mavericks
+import dagger.hilt.android.AndroidEntryPoint
+import im.vector.app.core.extensions.addFragment
+import im.vector.app.core.platform.SimpleFragmentActivity
+
+/**
+ * Display the overview info about a Session.
+ */
+@AndroidEntryPoint
+class SessionOverviewActivity : SimpleFragmentActivity() {
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+
+        if (isFirstCreation()) {
+            addFragment(
+                    container = views.container,
+                    fragmentClass = SessionOverviewFragment::class.java,
+                    params = intent.getParcelableExtra(Mavericks.KEY_ARG)
+            )
+        }
+    }
+
+    companion object {
+        fun newIntent(context: Context, deviceId: String): Intent {
+            return Intent(context, SessionOverviewActivity::class.java).apply {
+                putExtra(Mavericks.KEY_ARG, SessionOverviewArgs(deviceId))
+            }
+        }
+    }
+}
diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewArgs.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewArgs.kt
new file mode 100644
index 0000000000..27c8d6fb2e
--- /dev/null
+++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewArgs.kt
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2022 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.app.features.settings.devices.v2.overview
+
+import android.os.Parcelable
+import kotlinx.parcelize.Parcelize
+
+@Parcelize
+data class SessionOverviewArgs(
+        val deviceId: String
+) : Parcelable
diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewFragment.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewFragment.kt
new file mode 100644
index 0000000000..a6bac6087b
--- /dev/null
+++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewFragment.kt
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2022 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.app.features.settings.devices.v2.overview
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.Toast
+import androidx.appcompat.app.AppCompatActivity
+import androidx.core.view.isGone
+import androidx.core.view.isVisible
+import com.airbnb.mvrx.Success
+import com.airbnb.mvrx.fragmentViewModel
+import com.airbnb.mvrx.withState
+import dagger.hilt.android.AndroidEntryPoint
+import im.vector.app.R
+import im.vector.app.core.date.VectorDateFormatter
+import im.vector.app.core.platform.VectorBaseFragment
+import im.vector.app.core.resources.ColorProvider
+import im.vector.app.core.resources.DrawableProvider
+import im.vector.app.databinding.FragmentSessionOverviewBinding
+import im.vector.app.features.settings.devices.DeviceFullInfo
+import im.vector.app.features.settings.devices.v2.list.SessionInfoViewState
+import javax.inject.Inject
+
+/**
+ * Display the overview info about a Session.
+ */
+@AndroidEntryPoint
+class SessionOverviewFragment :
+        VectorBaseFragment<FragmentSessionOverviewBinding>() {
+
+    @Inject lateinit var dateFormatter: VectorDateFormatter
+
+    @Inject lateinit var drawableProvider: DrawableProvider
+
+    @Inject lateinit var colorProvider: ColorProvider
+
+    private val viewModel: SessionOverviewViewModel by fragmentViewModel()
+
+    override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentSessionOverviewBinding {
+        return FragmentSessionOverviewBinding.inflate(inflater, container, false)
+    }
+
+    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+        super.onViewCreated(view, savedInstanceState)
+        initSessionInfoView()
+    }
+
+    private fun initSessionInfoView() {
+        views.sessionOverviewInfo.onLearnMoreClickListener = {
+            Toast.makeText(context, "Learn more verification status", Toast.LENGTH_LONG).show()
+        }
+    }
+
+    override fun onDestroyView() {
+        cleanUpSessionInfoView()
+        super.onDestroyView()
+    }
+
+    private fun cleanUpSessionInfoView() {
+        views.sessionOverviewInfo.onLearnMoreClickListener = null
+    }
+
+    override fun invalidate() = withState(viewModel) { state ->
+        updateToolbar(state.isCurrentSession)
+        if (state.deviceInfo is Success) {
+            renderSessionInfo(state.isCurrentSession, state.deviceInfo.invoke())
+        } else {
+            hideSessionInfo()
+        }
+    }
+
+    private fun updateToolbar(isCurrentSession: Boolean) {
+        val titleResId = if (isCurrentSession) R.string.device_manager_current_session_title else R.string.device_manager_session_title
+        (activity as? AppCompatActivity)
+                ?.supportActionBar
+                ?.setTitle(titleResId)
+    }
+
+    private fun renderSessionInfo(isCurrentSession: Boolean, deviceFullInfo: DeviceFullInfo) {
+        views.sessionOverviewInfo.isVisible = true
+        val viewState = SessionInfoViewState(
+                isCurrentSession = isCurrentSession,
+                deviceFullInfo = deviceFullInfo,
+                isDetailsButtonVisible = false,
+                isLearnMoreLinkVisible = true,
+                isLastSeenDetailsVisible = true,
+        )
+        views.sessionOverviewInfo.render(viewState, dateFormatter, drawableProvider, colorProvider)
+    }
+
+    private fun hideSessionInfo() {
+        views.sessionOverviewInfo.isGone = true
+    }
+}
diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewViewModel.kt
new file mode 100644
index 0000000000..1a1d3640a2
--- /dev/null
+++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewViewModel.kt
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2022 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.app.features.settings.devices.v2.overview
+
+import com.airbnb.mvrx.MavericksViewModelFactory
+import com.airbnb.mvrx.Success
+import dagger.assisted.Assisted
+import dagger.assisted.AssistedFactory
+import dagger.assisted.AssistedInject
+import im.vector.app.core.di.MavericksAssistedViewModelFactory
+import im.vector.app.core.di.hiltMavericksViewModelFactory
+import im.vector.app.core.platform.EmptyViewEvents
+import im.vector.app.core.platform.VectorViewModel
+import kotlinx.coroutines.flow.launchIn
+import kotlinx.coroutines.flow.mapNotNull
+import kotlinx.coroutines.flow.onEach
+import org.matrix.android.sdk.api.session.Session
+
+class SessionOverviewViewModel @AssistedInject constructor(
+        @Assisted val initialState: SessionOverviewViewState,
+        session: Session,
+        private val getDeviceFullInfoUseCase: GetDeviceFullInfoUseCase,
+) : VectorViewModel<SessionOverviewViewState, SessionOverviewAction, EmptyViewEvents>(initialState) {
+
+    companion object : MavericksViewModelFactory<SessionOverviewViewModel, SessionOverviewViewState> by hiltMavericksViewModelFactory()
+
+    @AssistedFactory
+    interface Factory : MavericksAssistedViewModelFactory<SessionOverviewViewModel, SessionOverviewViewState> {
+        override fun create(initialState: SessionOverviewViewState): SessionOverviewViewModel
+    }
+
+    init {
+        val currentDeviceId = session.sessionParams.deviceId.orEmpty()
+        setState {
+            copy(isCurrentSession = deviceId.isNotEmpty() && deviceId == currentDeviceId)
+        }
+
+        observeSessionInfo(initialState.deviceId)
+    }
+
+    private fun observeSessionInfo(deviceId: String) {
+        getDeviceFullInfoUseCase.execute(deviceId)
+                .mapNotNull { it.getOrNull() }
+                .onEach { setState { copy(deviceInfo = Success(it)) } }
+                .launchIn(viewModelScope)
+    }
+
+    override fun handle(action: SessionOverviewAction) {
+        TODO("Implement when adding the first action")
+    }
+}
diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewViewState.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewViewState.kt
new file mode 100644
index 0000000000..c9f5635cbd
--- /dev/null
+++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewViewState.kt
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2022 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.app.features.settings.devices.v2.overview
+
+import com.airbnb.mvrx.Async
+import com.airbnb.mvrx.MavericksState
+import com.airbnb.mvrx.Uninitialized
+import im.vector.app.features.settings.devices.DeviceFullInfo
+
+data class SessionOverviewViewState(
+        val deviceId: String,
+        val isCurrentSession: Boolean = false,
+        val deviceInfo: Async<DeviceFullInfo> = Uninitialized,
+) : MavericksState {
+    constructor(args: SessionOverviewArgs) : this(
+            deviceId = args.deviceId
+    )
+}
diff --git a/vector/src/main/res/layout/fragment_session_overview.xml b/vector/src/main/res/layout/fragment_session_overview.xml
new file mode 100644
index 0000000000..156e61673b
--- /dev/null
+++ b/vector/src/main/res/layout/fragment_session_overview.xml
@@ -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:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <im.vector.app.features.settings.devices.v2.list.SessionInfoView
+        android:id="@+id/sessionOverviewInfo"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_marginHorizontal="16dp"
+        android:layout_marginVertical="24dp"
+        android:visibility="gone"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+        tools:visibility="visible" />
+
+</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/vector/src/main/res/layout/fragment_settings_devices.xml b/vector/src/main/res/layout/fragment_settings_devices.xml
index 6710f345ce..9cefd6aa24 100644
--- a/vector/src/main/res/layout/fragment_settings_devices.xml
+++ b/vector/src/main/res/layout/fragment_settings_devices.xml
@@ -8,7 +8,7 @@
         android:layout_width="match_parent"
         android:layout_height="wrap_content">
 
-        <im.vector.app.features.settings.devices.v2.list.DevicesListHeaderView
+        <im.vector.app.features.settings.devices.v2.list.SessionsListHeaderView
             android:id="@+id/deviceListHeaderSectionSecurityRecommendations"
             android:layout_width="0dp"
             android:layout_height="wrap_content"
@@ -56,17 +56,17 @@
             app:layout_constraintStart_toStartOf="parent"
             app:layout_constraintTop_toBottomOf="@id/deviceListInactiveSessionsRecommendation" />
 
-        <im.vector.app.features.settings.devices.v2.list.DevicesListHeaderView
+        <im.vector.app.features.settings.devices.v2.list.SessionsListHeaderView
             android:id="@+id/deviceListHeaderCurrentSession"
             android:layout_width="0dp"
             android:layout_height="wrap_content"
             app:devicesListHeaderDescription=""
-            app:devicesListHeaderTitle="@string/device_manager_header_section_current_session"
+            app:devicesListHeaderTitle="@string/device_manager_current_session_title"
             app:layout_constraintEnd_toEndOf="parent"
             app:layout_constraintStart_toStartOf="parent"
             app:layout_constraintTop_toBottomOf="@id/deviceListSecurityRecommendationsDivider" />
 
-        <im.vector.app.features.settings.devices.v2.list.CurrentSessionView
+        <im.vector.app.features.settings.devices.v2.list.SessionInfoView
             android:id="@+id/deviceListCurrentSession"
             android:layout_width="0dp"
             android:layout_height="wrap_content"
@@ -86,7 +86,7 @@
             app:layout_constraintStart_toStartOf="parent"
             app:layout_constraintTop_toBottomOf="@id/deviceListCurrentSession" />
 
-        <im.vector.app.features.settings.devices.v2.list.DevicesListHeaderView
+        <im.vector.app.features.settings.devices.v2.list.SessionsListHeaderView
             android:id="@+id/deviceListHeaderOtherSessions"
             android:layout_width="0dp"
             android:layout_height="wrap_content"
diff --git a/vector/src/main/res/layout/item_other_session.xml b/vector/src/main/res/layout/item_other_session.xml
index 2c41ce6a56..2f93c2be5d 100644
--- a/vector/src/main/res/layout/item_other_session.xml
+++ b/vector/src/main/res/layout/item_other_session.xml
@@ -4,6 +4,7 @@
     xmlns:tools="http://schemas.android.com/tools"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
+    android:foreground="?selectableItemBackground"
     android:paddingTop="16dp">
 
     <ImageView
diff --git a/vector/src/main/res/layout/view_current_session.xml b/vector/src/main/res/layout/view_session_info.xml
similarity index 60%
rename from vector/src/main/res/layout/view_current_session.xml
rename to vector/src/main/res/layout/view_session_info.xml
index 91977eba40..18daae825a 100644
--- a/vector/src/main/res/layout/view_current_session.xml
+++ b/vector/src/main/res/layout/view_session_info.xml
@@ -8,7 +8,7 @@
     android:paddingBottom="16dp">
 
     <ImageView
-        android:id="@+id/currentSessionDeviceTypeImageView"
+        android:id="@+id/sessionInfoDeviceTypeImageView"
         android:layout_width="40dp"
         android:layout_height="40dp"
         android:layout_marginTop="16dp"
@@ -21,18 +21,18 @@
         tools:src="@drawable/ic_device_type_mobile" />
 
     <TextView
-        android:id="@+id/currentSessionNameTextView"
+        android:id="@+id/sessionInfoNameTextView"
         style="@style/TextAppearance.Vector.Subtitle.Medium.DevicesManagement"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_marginTop="4dp"
         app:layout_constraintEnd_toEndOf="parent"
         app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintTop_toBottomOf="@id/currentSessionDeviceTypeImageView"
+        app:layout_constraintTop_toBottomOf="@id/sessionInfoDeviceTypeImageView"
         tools:text="Element Mobile: Android" />
 
     <LinearLayout
-        android:id="@+id/currentSessionVerificationStatusContainer"
+        android:id="@+id/sessionInfoVerificationStatusContainer"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_marginTop="12dp"
@@ -40,17 +40,17 @@
         android:orientation="horizontal"
         app:layout_constraintEnd_toEndOf="parent"
         app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintTop_toBottomOf="@id/currentSessionNameTextView">
+        app:layout_constraintTop_toBottomOf="@id/sessionInfoNameTextView">
 
         <im.vector.app.core.ui.views.ShieldImageView
-            android:id="@+id/currentSessionVerificationStatusImageView"
+            android:id="@+id/sessionInfoVerificationStatusImageView"
             android:layout_width="16dp"
             android:layout_height="16dp"
             android:importantForAccessibility="no"
             tools:src="@drawable/ic_shield_trusted" />
 
         <TextView
-            android:id="@+id/currentSessionVerificationStatusTextView"
+            android:id="@+id/sessionInfoVerificationStatusTextView"
             style="@style/TextAppearance.Vector.Body"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
@@ -60,7 +60,7 @@
     </LinearLayout>
 
     <TextView
-        android:id="@+id/currentSessionVerificationStatusDetailTextView"
+        android:id="@+id/sessionInfoVerificationStatusDetailTextView"
         style="@style/TextAppearance.Vector.Body.DevicesManagement"
         android:layout_width="0dp"
         android:layout_height="wrap_content"
@@ -69,11 +69,40 @@
         android:gravity="center"
         app:layout_constraintEnd_toEndOf="parent"
         app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintTop_toBottomOf="@id/currentSessionVerificationStatusContainer"
-        tools:text="@string/device_manager_verification_status_detail_verified" />
+        app:layout_constraintTop_toBottomOf="@id/sessionInfoVerificationStatusContainer"
+        tools:text="@string/device_manager_verification_status_detail_current_session_verified" />
+
+    <TextView
+        android:id="@+id/sessionInfoLastActivityTextView"
+        style="@style/TextAppearance.Vector.Body.DevicesManagement"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_marginHorizontal="32dp"
+        android:layout_marginTop="12dp"
+        android:visibility="gone"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/sessionInfoVerificationStatusDetailTextView"
+        app:layout_constraintWidth="wrap_content_constrained"
+        tools:text="Last activity Fri 14:59"
+        tools:visibility="visible" />
+
+    <TextView
+        android:id="@+id/sessionInfoLastIPAddressTextView"
+        style="@style/TextAppearance.Vector.Body.DevicesManagement"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_marginHorizontal="32dp"
+        android:gravity="center"
+        android:visibility="gone"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/sessionInfoLastActivityTextView"
+        tools:text="81.235.41.100 (United Kingdom)"
+        tools:visibility="visible" />
 
     <Button
-        android:id="@+id/currentSessionVerifySessionButton"
+        android:id="@+id/sessionInfoVerifySessionButton"
         android:layout_width="0dp"
         android:layout_height="52dp"
         android:layout_marginHorizontal="24dp"
@@ -81,10 +110,10 @@
         android:text="@string/device_manager_verify_session"
         app:layout_constraintEnd_toEndOf="parent"
         app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintTop_toBottomOf="@id/currentSessionVerificationStatusDetailTextView" />
+        app:layout_constraintTop_toBottomOf="@id/sessionInfoLastIPAddressTextView" />
 
     <Button
-        android:id="@+id/currentSessionViewDetailsButton"
+        android:id="@+id/sessionInfoViewDetailsButton"
         style="@style/Widget.Vector.Button.Text"
         android:layout_width="0dp"
         android:layout_height="wrap_content"
@@ -93,6 +122,6 @@
         android:text="@string/device_manager_view_details"
         app:layout_constraintEnd_toEndOf="parent"
         app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintTop_toBottomOf="@id/currentSessionVerifySessionButton" />
+        app:layout_constraintTop_toBottomOf="@id/sessionInfoVerifySessionButton" />
 
 </androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/vector/src/main/res/layout/view_devices_list_header.xml b/vector/src/main/res/layout/view_sessions_list_header.xml
similarity index 83%
rename from vector/src/main/res/layout/view_devices_list_header.xml
rename to vector/src/main/res/layout/view_sessions_list_header.xml
index 492c3e7a12..d690ee4c87 100644
--- a/vector/src/main/res/layout/view_devices_list_header.xml
+++ b/vector/src/main/res/layout/view_sessions_list_header.xml
@@ -7,7 +7,7 @@
     tools:parentTag="androidx.constraintlayout.widget.ConstraintLayout">
 
     <TextView
-        android:id="@+id/devices_list_header_title"
+        android:id="@+id/sessions_list_header_title"
         style="@style/TextAppearance.Vector.Subtitle.Medium.DevicesManagement"
         android:layout_width="0dp"
         android:layout_height="wrap_content"
@@ -19,14 +19,14 @@
         tools:text="Other sessions" />
 
     <TextView
-        android:id="@+id/devices_list_header_description"
+        android:id="@+id/sessions_list_header_description"
         style="@style/TextAppearance.Vector.Body.DevicesManagement"
         android:layout_width="0dp"
         android:layout_height="wrap_content"
         android:layout_marginTop="18.5dp"
         android:layout_marginEnd="40dp"
         app:layout_constraintEnd_toEndOf="parent"
-        app:layout_constraintStart_toStartOf="@id/devices_list_header_title"
-        app:layout_constraintTop_toBottomOf="@id/devices_list_header_title"
+        app:layout_constraintStart_toStartOf="@id/sessions_list_header_title"
+        app:layout_constraintTop_toBottomOf="@id/sessions_list_header_title"
         tools:text="For best security, verify your sessions and sign out from any session that you don’t recognize or use anymore. Learn More." />
 </merge>
diff --git a/vector/src/test/java/im/vector/app/features/location/live/GetLiveLocationShareSummaryUseCaseTest.kt b/vector/src/test/java/im/vector/app/features/location/live/GetLiveLocationShareSummaryUseCaseTest.kt
index ed1bcebf16..89966b5317 100644
--- a/vector/src/test/java/im/vector/app/features/location/live/GetLiveLocationShareSummaryUseCaseTest.kt
+++ b/vector/src/test/java/im/vector/app/features/location/live/GetLiveLocationShareSummaryUseCaseTest.kt
@@ -18,7 +18,7 @@ package im.vector.app.features.location.live
 
 import im.vector.app.test.fakes.FakeFlowLiveDataConversions
 import im.vector.app.test.fakes.FakeSession
-import im.vector.app.test.fakes.givenAsFlowReturns
+import im.vector.app.test.fakes.givenAsFlow
 import io.mockk.unmockkAll
 import kotlinx.coroutines.flow.first
 import kotlinx.coroutines.test.runTest
@@ -28,7 +28,6 @@ import org.junit.Before
 import org.junit.Test
 import org.matrix.android.sdk.api.session.room.model.livelocation.LiveLocationShareAggregatedSummary
 import org.matrix.android.sdk.api.session.room.model.message.MessageBeaconLocationDataContent
-import org.matrix.android.sdk.api.util.Optional
 
 private const val A_ROOM_ID = "room_id"
 private const val AN_EVENT_ID = "event_id"
@@ -64,7 +63,7 @@ class GetLiveLocationShareSummaryUseCaseTest {
                 .getRoom(A_ROOM_ID)
                 .locationSharingService()
                 .givenLiveLocationShareSummaryReturns(AN_EVENT_ID, summary)
-                .givenAsFlowReturns(Optional(summary))
+                .givenAsFlow()
 
         val result = getLiveLocationShareSummaryUseCase.execute(A_ROOM_ID, AN_EVENT_ID).first()
 
@@ -77,7 +76,7 @@ class GetLiveLocationShareSummaryUseCaseTest {
                 .getRoom(A_ROOM_ID)
                 .locationSharingService()
                 .givenLiveLocationShareSummaryReturns(AN_EVENT_ID, null)
-                .givenAsFlowReturns(Optional(null))
+                .givenAsFlow()
 
         val result = getLiveLocationShareSummaryUseCase.execute(A_ROOM_ID, AN_EVENT_ID).first()
 
diff --git a/vector/src/test/java/im/vector/app/features/location/live/map/GetListOfUserLiveLocationUseCaseTest.kt b/vector/src/test/java/im/vector/app/features/location/live/map/GetListOfUserLiveLocationUseCaseTest.kt
index 420b8e6a06..6d24858915 100644
--- a/vector/src/test/java/im/vector/app/features/location/live/map/GetListOfUserLiveLocationUseCaseTest.kt
+++ b/vector/src/test/java/im/vector/app/features/location/live/map/GetListOfUserLiveLocationUseCaseTest.kt
@@ -19,7 +19,7 @@ package im.vector.app.features.location.live.map
 import im.vector.app.features.location.LocationData
 import im.vector.app.test.fakes.FakeFlowLiveDataConversions
 import im.vector.app.test.fakes.FakeSession
-import im.vector.app.test.fakes.givenAsFlowReturns
+import im.vector.app.test.fakes.givenAsFlow
 import io.mockk.coEvery
 import io.mockk.mockk
 import io.mockk.unmockkAll
@@ -81,7 +81,7 @@ class GetListOfUserLiveLocationUseCaseTest {
                 .getRoom(A_ROOM_ID)
                 .locationSharingService()
                 .givenRunningLiveLocationShareSummariesReturns(summaries)
-                .givenAsFlowReturns(summaries)
+                .givenAsFlow()
 
         val viewState1 = UserLiveLocationViewState(
                 matrixItem = MatrixItem.UserItem(id = "@userId1:matrix.org", displayName = "User 1", avatarUrl = ""),
diff --git a/vector/src/test/java/im/vector/app/features/settings/devices/GetCurrentSessionCrossSigningInfoUseCaseTest.kt b/vector/src/test/java/im/vector/app/features/settings/devices/GetCurrentSessionCrossSigningInfoUseCaseTest.kt
new file mode 100644
index 0000000000..7c8ee008eb
--- /dev/null
+++ b/vector/src/test/java/im/vector/app/features/settings/devices/GetCurrentSessionCrossSigningInfoUseCaseTest.kt
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2022 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.app.features.settings.devices
+
+import im.vector.app.test.fakes.FakeActiveSessionHolder
+import io.mockk.every
+import io.mockk.mockk
+import org.amshove.kluent.shouldBeEqualTo
+import org.junit.Test
+import org.matrix.android.sdk.api.auth.data.SessionParams
+
+private const val A_DEVICE_ID = "device-id"
+
+class GetCurrentSessionCrossSigningInfoUseCaseTest {
+
+    private val fakeActiveSessionHolder = FakeActiveSessionHolder()
+
+    private val getCurrentSessionCrossSigningInfoUseCase = GetCurrentSessionCrossSigningInfoUseCase(
+            activeSessionHolder = fakeActiveSessionHolder.instance
+    )
+
+    @Test
+    fun `given the active session when getting cross signing info then the result is correct`() {
+        val sessionParams = mockk<SessionParams>()
+        every { sessionParams.deviceId } returns A_DEVICE_ID
+        fakeActiveSessionHolder.fakeSession.givenSessionParams(sessionParams)
+        val isCrossSigningInitialized = true
+        fakeActiveSessionHolder.fakeSession
+                .fakeCryptoService
+                .fakeCrossSigningService
+                .givenIsCrossSigningInitializedReturns(isCrossSigningInitialized)
+        val isCrossSigningVerified = true
+        fakeActiveSessionHolder.fakeSession
+                .fakeCryptoService
+                .fakeCrossSigningService
+                .givenIsCrossSigningVerifiedReturns(isCrossSigningVerified)
+        val expectedResult = CurrentSessionCrossSigningInfo(
+                deviceId = A_DEVICE_ID,
+                isCrossSigningInitialized = isCrossSigningInitialized,
+                isCrossSigningVerified = isCrossSigningVerified
+        )
+
+        val result = getCurrentSessionCrossSigningInfoUseCase.execute()
+
+        result shouldBeEqualTo expectedResult
+    }
+}
diff --git a/vector/src/test/java/im/vector/app/features/settings/devices/GetEncryptionTrustLevelForCurrentDeviceUseCaseTest.kt b/vector/src/test/java/im/vector/app/features/settings/devices/GetEncryptionTrustLevelForCurrentDeviceUseCaseTest.kt
new file mode 100644
index 0000000000..830eab5dcb
--- /dev/null
+++ b/vector/src/test/java/im/vector/app/features/settings/devices/GetEncryptionTrustLevelForCurrentDeviceUseCaseTest.kt
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2022 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.app.features.settings.devices
+
+import org.amshove.kluent.shouldBeEqualTo
+import org.junit.Test
+import org.matrix.android.sdk.api.session.crypto.model.RoomEncryptionTrustLevel
+
+class GetEncryptionTrustLevelForCurrentDeviceUseCaseTest {
+
+    private val getEncryptionTrustLevelForCurrentDeviceUseCase = GetEncryptionTrustLevelForCurrentDeviceUseCase()
+
+    @Test
+    fun `given in legacy mode when computing trust level then device is trusted`() {
+        val trustMSK = false
+        val legacyMode = true
+
+        val result = getEncryptionTrustLevelForCurrentDeviceUseCase.execute(trustMSK = trustMSK, legacyMode = legacyMode)
+
+        result shouldBeEqualTo RoomEncryptionTrustLevel.Trusted
+    }
+
+    @Test
+    fun `given trustMSK is true and not in legacy mode when computing trust level then device is trusted`() {
+        val trustMSK = true
+        val legacyMode = false
+
+        val result = getEncryptionTrustLevelForCurrentDeviceUseCase.execute(trustMSK = trustMSK, legacyMode = legacyMode)
+
+        result shouldBeEqualTo RoomEncryptionTrustLevel.Trusted
+    }
+
+    @Test
+    fun `given trustMSK is false and not in legacy mode when computing trust level then device is unverified`() {
+        val trustMSK = false
+        val legacyMode = false
+
+        val result = getEncryptionTrustLevelForCurrentDeviceUseCase.execute(trustMSK = trustMSK, legacyMode = legacyMode)
+
+        result shouldBeEqualTo RoomEncryptionTrustLevel.Warning
+    }
+}
diff --git a/vector/src/test/java/im/vector/app/features/settings/devices/GetEncryptionTrustLevelForDeviceUseCaseTest.kt b/vector/src/test/java/im/vector/app/features/settings/devices/GetEncryptionTrustLevelForDeviceUseCaseTest.kt
new file mode 100644
index 0000000000..8d54b31ab4
--- /dev/null
+++ b/vector/src/test/java/im/vector/app/features/settings/devices/GetEncryptionTrustLevelForDeviceUseCaseTest.kt
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2022 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.app.features.settings.devices
+
+import io.mockk.every
+import io.mockk.mockk
+import io.mockk.verify
+import org.amshove.kluent.shouldBeEqualTo
+import org.junit.Test
+import org.matrix.android.sdk.api.session.crypto.crosssigning.DeviceTrustLevel
+import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo
+import org.matrix.android.sdk.api.session.crypto.model.RoomEncryptionTrustLevel
+
+private const val A_DEVICE_ID = "device-id"
+private const val A_DEVICE_ID_2 = "device-id-2"
+
+class GetEncryptionTrustLevelForDeviceUseCaseTest {
+
+    private val getEncryptionTrustLevelForCurrentDeviceUseCase = mockk<GetEncryptionTrustLevelForCurrentDeviceUseCase>()
+    private val getEncryptionTrustLevelForOtherDeviceUseCase = mockk<GetEncryptionTrustLevelForOtherDeviceUseCase>()
+
+    private val getEncryptionTrustLevelForDeviceUseCase = GetEncryptionTrustLevelForDeviceUseCase(
+            getEncryptionTrustLevelForCurrentDeviceUseCase = getEncryptionTrustLevelForCurrentDeviceUseCase,
+            getEncryptionTrustLevelForOtherDeviceUseCase = getEncryptionTrustLevelForOtherDeviceUseCase,
+    )
+
+    @Test
+    fun `given is current device when computing trust level then the correct sub use case result is returned`() {
+        val currentSessionCrossSigningInfo = givenCurrentSessionCrossSigningInfo(
+                deviceId = A_DEVICE_ID,
+                isCrossSigningInitialized = true,
+                isCrossSigningVerified = false
+        )
+        val cryptoDeviceInfo = givenCryptoDeviceInfo(
+                deviceId = A_DEVICE_ID,
+                trustLevel = null
+        )
+        val trustLevel = RoomEncryptionTrustLevel.Trusted
+        every { getEncryptionTrustLevelForCurrentDeviceUseCase.execute(any(), any()) } returns trustLevel
+
+        val result = getEncryptionTrustLevelForDeviceUseCase.execute(currentSessionCrossSigningInfo, cryptoDeviceInfo)
+
+        result shouldBeEqualTo trustLevel
+        verify {
+            getEncryptionTrustLevelForCurrentDeviceUseCase.execute(
+                    trustMSK = currentSessionCrossSigningInfo.isCrossSigningVerified,
+                    legacyMode = !currentSessionCrossSigningInfo.isCrossSigningInitialized
+            )
+        }
+    }
+
+    @Test
+    fun `given is not current device when computing trust level then the correct sub use case result is returned`() {
+        val currentSessionCrossSigningInfo = givenCurrentSessionCrossSigningInfo(
+                deviceId = A_DEVICE_ID,
+                isCrossSigningInitialized = true,
+                isCrossSigningVerified = false
+        )
+        val cryptoDeviceInfo = givenCryptoDeviceInfo(
+                deviceId = A_DEVICE_ID_2,
+                trustLevel = null
+        )
+        val trustLevel = RoomEncryptionTrustLevel.Trusted
+        every { getEncryptionTrustLevelForOtherDeviceUseCase.execute(any(), any(), any()) } returns trustLevel
+
+        val result = getEncryptionTrustLevelForDeviceUseCase.execute(currentSessionCrossSigningInfo, cryptoDeviceInfo)
+
+        result shouldBeEqualTo trustLevel
+        verify {
+            getEncryptionTrustLevelForOtherDeviceUseCase.execute(
+                    trustMSK = currentSessionCrossSigningInfo.isCrossSigningVerified,
+                    legacyMode = !currentSessionCrossSigningInfo.isCrossSigningInitialized,
+                    deviceTrustLevel = cryptoDeviceInfo.trustLevel
+            )
+        }
+    }
+
+    private fun givenCurrentSessionCrossSigningInfo(
+            deviceId: String?,
+            isCrossSigningInitialized: Boolean,
+            isCrossSigningVerified: Boolean
+    ): CurrentSessionCrossSigningInfo {
+        return CurrentSessionCrossSigningInfo(
+                deviceId = deviceId,
+                isCrossSigningInitialized = isCrossSigningInitialized,
+                isCrossSigningVerified = isCrossSigningVerified
+        )
+    }
+
+    private fun givenCryptoDeviceInfo(
+            deviceId: String,
+            trustLevel: DeviceTrustLevel?
+    ): CryptoDeviceInfo {
+        return CryptoDeviceInfo(
+                userId = "",
+                deviceId = deviceId,
+                trustLevel = trustLevel
+        )
+    }
+}
diff --git a/vector/src/test/java/im/vector/app/features/settings/devices/GetEncryptionTrustLevelForOtherDeviceUseCaseTest.kt b/vector/src/test/java/im/vector/app/features/settings/devices/GetEncryptionTrustLevelForOtherDeviceUseCaseTest.kt
new file mode 100644
index 0000000000..9dc87c2a16
--- /dev/null
+++ b/vector/src/test/java/im/vector/app/features/settings/devices/GetEncryptionTrustLevelForOtherDeviceUseCaseTest.kt
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2022 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.app.features.settings.devices
+
+import org.amshove.kluent.shouldBeEqualTo
+import org.junit.Test
+import org.matrix.android.sdk.api.session.crypto.crosssigning.DeviceTrustLevel
+import org.matrix.android.sdk.api.session.crypto.model.RoomEncryptionTrustLevel
+
+class GetEncryptionTrustLevelForOtherDeviceUseCaseTest {
+
+    private val getEncryptionTrustLevelForOtherDeviceUseCase = GetEncryptionTrustLevelForOtherDeviceUseCase()
+
+    @Test
+    fun `given in legacy mode and device locally verified when computing trust level then device is trusted`() {
+        val trustMSK = false
+        val legacyMode = true
+        val deviceTrustLevel = givenDeviceTrustLevel(locallyVerified = true, crossSigningVerified = false)
+
+        val result = getEncryptionTrustLevelForOtherDeviceUseCase.execute(trustMSK = trustMSK, legacyMode = legacyMode, deviceTrustLevel = deviceTrustLevel)
+
+        result shouldBeEqualTo RoomEncryptionTrustLevel.Trusted
+    }
+
+    @Test
+    fun `given in legacy mode and device not locally verified when computing trust level then device is unverified`() {
+        val trustMSK = false
+        val legacyMode = true
+        val deviceTrustLevel = givenDeviceTrustLevel(locallyVerified = false, crossSigningVerified = false)
+
+        val result = getEncryptionTrustLevelForOtherDeviceUseCase.execute(trustMSK = trustMSK, legacyMode = legacyMode, deviceTrustLevel = deviceTrustLevel)
+
+        result shouldBeEqualTo RoomEncryptionTrustLevel.Warning
+    }
+
+    @Test
+    fun `given trustMSK is true and not in legacy mode and device cross signing verified when computing trust level then device is trusted`() {
+        val trustMSK = true
+        val legacyMode = false
+        val deviceTrustLevel = givenDeviceTrustLevel(locallyVerified = false, crossSigningVerified = true)
+
+        val result = getEncryptionTrustLevelForOtherDeviceUseCase.execute(trustMSK = trustMSK, legacyMode = legacyMode, deviceTrustLevel = deviceTrustLevel)
+
+        result shouldBeEqualTo RoomEncryptionTrustLevel.Trusted
+    }
+
+    @Test
+    fun `given trustMSK is true and not in legacy mode and device locally verified when computing trust level then device has default trust level`() {
+        val trustMSK = true
+        val legacyMode = false
+        val deviceTrustLevel = givenDeviceTrustLevel(locallyVerified = true, crossSigningVerified = false)
+
+        val result = getEncryptionTrustLevelForOtherDeviceUseCase.execute(trustMSK = trustMSK, legacyMode = legacyMode, deviceTrustLevel = deviceTrustLevel)
+
+        result shouldBeEqualTo RoomEncryptionTrustLevel.Default
+    }
+
+    @Test
+    fun `given trustMSK is true and not in legacy mode and device not verified when computing trust level then device is unverified`() {
+        val trustMSK = true
+        val legacyMode = false
+        val deviceTrustLevel = givenDeviceTrustLevel(locallyVerified = false, crossSigningVerified = false)
+
+        val result = getEncryptionTrustLevelForOtherDeviceUseCase.execute(trustMSK = trustMSK, legacyMode = legacyMode, deviceTrustLevel = deviceTrustLevel)
+
+        result shouldBeEqualTo RoomEncryptionTrustLevel.Warning
+    }
+
+    @Test
+    fun `given trustMSK is false and not in legacy mode when computing trust level then device has default trust level`() {
+        val trustMSK = false
+        val legacyMode = false
+        val deviceTrustLevel = givenDeviceTrustLevel(locallyVerified = false, crossSigningVerified = false)
+
+        val result = getEncryptionTrustLevelForOtherDeviceUseCase.execute(trustMSK = trustMSK, legacyMode = legacyMode, deviceTrustLevel = deviceTrustLevel)
+
+        result shouldBeEqualTo RoomEncryptionTrustLevel.Default
+    }
+
+    private fun givenDeviceTrustLevel(locallyVerified: Boolean?, crossSigningVerified: Boolean): DeviceTrustLevel {
+        return DeviceTrustLevel(
+                crossSigningVerified = crossSigningVerified,
+                locallyVerified = locallyVerified
+        )
+    }
+}
diff --git a/vector/src/test/java/im/vector/app/features/settings/devices/v2/VectorSettingsDevicesViewNavigatorTest.kt b/vector/src/test/java/im/vector/app/features/settings/devices/v2/VectorSettingsDevicesViewNavigatorTest.kt
new file mode 100644
index 0000000000..2a4c53f34f
--- /dev/null
+++ b/vector/src/test/java/im/vector/app/features/settings/devices/v2/VectorSettingsDevicesViewNavigatorTest.kt
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2022 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.app.features.settings.devices.v2
+
+import android.content.Intent
+import im.vector.app.features.settings.devices.v2.overview.SessionOverviewActivity
+import im.vector.app.test.fakes.FakeContext
+import io.mockk.every
+import io.mockk.mockk
+import io.mockk.mockkObject
+import io.mockk.unmockkAll
+import io.mockk.verify
+import org.junit.After
+import org.junit.Before
+import org.junit.Test
+
+private const val A_SESSION_ID = "session_id"
+
+class VectorSettingsDevicesViewNavigatorTest {
+
+    private val context = FakeContext()
+    private val vectorSettingsDevicesViewNavigator = VectorSettingsDevicesViewNavigator()
+
+    @Before
+    fun setUp() {
+        mockkObject(SessionOverviewActivity.Companion)
+    }
+
+    @After
+    fun tearDown() {
+        unmockkAll()
+    }
+
+    @Test
+    fun `given a session id when navigating to overview then it starts the correct activity`() {
+        val intent = givenIntentForSessionOverview(A_SESSION_ID)
+        context.givenStartActivity(intent)
+
+        vectorSettingsDevicesViewNavigator.navigateToSessionOverview(context.instance, A_SESSION_ID)
+
+        verify {
+            context.instance.startActivity(intent)
+        }
+    }
+
+    private fun givenIntentForSessionOverview(sessionId: String): Intent {
+        val intent = mockk<Intent>()
+        every { SessionOverviewActivity.newIntent(context.instance, sessionId) } returns intent
+        return intent
+    }
+}
diff --git a/vector/src/test/java/im/vector/app/features/settings/devices/v2/overview/GetDeviceFullInfoUseCaseTest.kt b/vector/src/test/java/im/vector/app/features/settings/devices/v2/overview/GetDeviceFullInfoUseCaseTest.kt
new file mode 100644
index 0000000000..e3d62961a7
--- /dev/null
+++ b/vector/src/test/java/im/vector/app/features/settings/devices/v2/overview/GetDeviceFullInfoUseCaseTest.kt
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2022 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.app.features.settings.devices.v2.overview
+
+import androidx.lifecycle.MutableLiveData
+import androidx.lifecycle.asFlow
+import im.vector.app.features.settings.devices.CurrentSessionCrossSigningInfo
+import im.vector.app.features.settings.devices.DeviceFullInfo
+import im.vector.app.features.settings.devices.GetCurrentSessionCrossSigningInfoUseCase
+import im.vector.app.features.settings.devices.GetEncryptionTrustLevelForDeviceUseCase
+import im.vector.app.features.settings.devices.v2.list.CheckIfSessionIsInactiveUseCase
+import im.vector.app.test.fakes.FakeActiveSessionHolder
+import im.vector.app.test.fakes.FakeFlowLiveDataConversions
+import im.vector.app.test.fakes.givenAsFlow
+import io.mockk.every
+import io.mockk.mockk
+import io.mockk.unmockkAll
+import io.mockk.verify
+import kotlinx.coroutines.flow.firstOrNull
+import kotlinx.coroutines.test.runTest
+import org.amshove.kluent.shouldBeEqualTo
+import org.junit.After
+import org.junit.Before
+import org.junit.Test
+import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo
+import org.matrix.android.sdk.api.session.crypto.model.DeviceInfo
+import org.matrix.android.sdk.api.session.crypto.model.RoomEncryptionTrustLevel
+import org.matrix.android.sdk.api.util.Optional
+
+private const val A_DEVICE_ID = "device-id"
+private const val A_TIMESTAMP = 123L
+
+class GetDeviceFullInfoUseCaseTest {
+
+    private val fakeActiveSessionHolder = FakeActiveSessionHolder()
+    private val getCurrentSessionCrossSigningInfoUseCase = mockk<GetCurrentSessionCrossSigningInfoUseCase>()
+    private val getEncryptionTrustLevelForDeviceUseCase = mockk<GetEncryptionTrustLevelForDeviceUseCase>()
+    private val checkIfSessionIsInactiveUseCase = mockk<CheckIfSessionIsInactiveUseCase>()
+    private val fakeFlowLiveDataConversions = FakeFlowLiveDataConversions()
+
+    private val getDeviceFullInfoUseCase = GetDeviceFullInfoUseCase(
+            activeSessionHolder = fakeActiveSessionHolder.instance,
+            getCurrentSessionCrossSigningInfoUseCase = getCurrentSessionCrossSigningInfoUseCase,
+            getEncryptionTrustLevelForDeviceUseCase = getEncryptionTrustLevelForDeviceUseCase,
+            checkIfSessionIsInactiveUseCase = checkIfSessionIsInactiveUseCase,
+    )
+
+    @Before
+    fun setUp() {
+        fakeFlowLiveDataConversions.setup()
+    }
+
+    @After
+    fun tearDown() {
+        unmockkAll()
+    }
+
+    @Test
+    fun `given current session and info for device when getting device info then the result is correct`() = runTest {
+        val currentSessionCrossSigningInfo = givenCurrentSessionCrossSigningInfo()
+        val deviceInfo = DeviceInfo(
+                lastSeenTs = A_TIMESTAMP
+        )
+        fakeActiveSessionHolder.fakeSession.fakeCryptoService.myDevicesInfoWithIdLiveData = MutableLiveData(Optional(deviceInfo))
+        fakeActiveSessionHolder.fakeSession.fakeCryptoService.myDevicesInfoWithIdLiveData.givenAsFlow()
+        val cryptoDeviceInfo = CryptoDeviceInfo(deviceId = A_DEVICE_ID, userId = "")
+        fakeActiveSessionHolder.fakeSession.fakeCryptoService.cryptoDeviceInfoWithIdLiveData = MutableLiveData(Optional(cryptoDeviceInfo))
+        fakeActiveSessionHolder.fakeSession.fakeCryptoService.cryptoDeviceInfoWithIdLiveData.givenAsFlow()
+        val trustLevel = givenTrustLevel(currentSessionCrossSigningInfo, cryptoDeviceInfo)
+        val isInactive = false
+        every { checkIfSessionIsInactiveUseCase.execute(any()) } returns isInactive
+
+        val deviceFullInfo = getDeviceFullInfoUseCase.execute(A_DEVICE_ID).firstOrNull()
+
+        deviceFullInfo shouldBeEqualTo Optional(
+                DeviceFullInfo(
+                        deviceInfo = deviceInfo,
+                        cryptoDeviceInfo = cryptoDeviceInfo,
+                        trustLevelForShield = trustLevel,
+                        isInactive = isInactive,
+                )
+        )
+        verify { fakeActiveSessionHolder.instance.getSafeActiveSession() }
+        verify { getCurrentSessionCrossSigningInfoUseCase.execute() }
+        verify { getEncryptionTrustLevelForDeviceUseCase.execute(currentSessionCrossSigningInfo, cryptoDeviceInfo) }
+        verify { fakeActiveSessionHolder.fakeSession.fakeCryptoService.getMyDevicesInfoLive(A_DEVICE_ID).asFlow() }
+        verify { fakeActiveSessionHolder.fakeSession.fakeCryptoService.getLiveCryptoDeviceInfoWithId(A_DEVICE_ID).asFlow() }
+        verify { checkIfSessionIsInactiveUseCase.execute(A_TIMESTAMP) }
+    }
+
+    @Test
+    fun `given current session and no info for device when getting device info then the result is null`() = runTest {
+        givenCurrentSessionCrossSigningInfo()
+        fakeActiveSessionHolder.fakeSession.fakeCryptoService.myDevicesInfoWithIdLiveData = MutableLiveData(Optional(null))
+        fakeActiveSessionHolder.fakeSession.fakeCryptoService.myDevicesInfoWithIdLiveData.givenAsFlow()
+        fakeActiveSessionHolder.fakeSession.fakeCryptoService.cryptoDeviceInfoWithIdLiveData = MutableLiveData(Optional(null))
+        fakeActiveSessionHolder.fakeSession.fakeCryptoService.cryptoDeviceInfoWithIdLiveData.givenAsFlow()
+
+        val deviceFullInfo = getDeviceFullInfoUseCase.execute(A_DEVICE_ID).firstOrNull()
+
+        deviceFullInfo shouldBeEqualTo Optional(null)
+        verify { fakeActiveSessionHolder.instance.getSafeActiveSession() }
+        verify { fakeActiveSessionHolder.fakeSession.fakeCryptoService.getMyDevicesInfoLive(A_DEVICE_ID).asFlow() }
+        verify { fakeActiveSessionHolder.fakeSession.fakeCryptoService.getLiveCryptoDeviceInfoWithId(A_DEVICE_ID).asFlow() }
+    }
+
+    @Test
+    fun `given no current session when getting device info then the result is empty`() = runTest {
+        fakeActiveSessionHolder.givenGetSafeActiveSessionReturns(null)
+
+        val deviceFullInfo = getDeviceFullInfoUseCase.execute(A_DEVICE_ID).firstOrNull()
+
+        deviceFullInfo shouldBeEqualTo null
+        verify { fakeActiveSessionHolder.instance.getSafeActiveSession() }
+    }
+
+    private fun givenCurrentSessionCrossSigningInfo(): CurrentSessionCrossSigningInfo {
+        val currentSessionCrossSigningInfo = CurrentSessionCrossSigningInfo(
+                deviceId = A_DEVICE_ID,
+                isCrossSigningInitialized = true,
+                isCrossSigningVerified = false
+        )
+        every { getCurrentSessionCrossSigningInfoUseCase.execute() } returns currentSessionCrossSigningInfo
+        return currentSessionCrossSigningInfo
+    }
+
+    private fun givenTrustLevel(currentSessionCrossSigningInfo: CurrentSessionCrossSigningInfo, cryptoDeviceInfo: CryptoDeviceInfo?): RoomEncryptionTrustLevel {
+        val trustLevel = RoomEncryptionTrustLevel.Trusted
+        every { getEncryptionTrustLevelForDeviceUseCase.execute(currentSessionCrossSigningInfo, cryptoDeviceInfo) } returns trustLevel
+        return trustLevel
+    }
+}
diff --git a/vector/src/test/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewViewModelTest.kt b/vector/src/test/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewViewModelTest.kt
new file mode 100644
index 0000000000..735c553808
--- /dev/null
+++ b/vector/src/test/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewViewModelTest.kt
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2022 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.app.features.settings.devices.v2.overview
+
+import com.airbnb.mvrx.Success
+import com.airbnb.mvrx.test.MvRxTestRule
+import im.vector.app.features.settings.devices.DeviceFullInfo
+import im.vector.app.test.fakes.FakeSession
+import im.vector.app.test.test
+import io.mockk.every
+import io.mockk.mockk
+import io.mockk.verify
+import kotlinx.coroutines.flow.flowOf
+import kotlinx.coroutines.test.UnconfinedTestDispatcher
+import org.junit.Rule
+import org.junit.Test
+import org.matrix.android.sdk.api.auth.data.SessionParams
+import org.matrix.android.sdk.api.util.Optional
+
+private const val A_SESSION_ID = "session-id"
+
+class SessionOverviewViewModelTest {
+
+    @get:Rule
+    val mvRxTestRule = MvRxTestRule(testDispatcher = UnconfinedTestDispatcher())
+
+    private val args = SessionOverviewArgs(
+            deviceId = A_SESSION_ID
+    )
+    private val fakeSession = FakeSession()
+    private val getDeviceFullInfoUseCase = mockk<GetDeviceFullInfoUseCase>()
+
+    private fun createViewModel() = SessionOverviewViewModel(
+            initialState = SessionOverviewViewState(args),
+            session = fakeSession,
+            getDeviceFullInfoUseCase = getDeviceFullInfoUseCase
+    )
+
+    @Test
+    fun `given the viewModel has been initialized then viewState is updated with session info`() {
+        val sessionParams = givenIdForSession(A_SESSION_ID)
+        val deviceFullInfo = mockk<DeviceFullInfo>()
+        every { getDeviceFullInfoUseCase.execute(A_SESSION_ID) } returns flowOf(Optional(deviceFullInfo))
+        val expectedState = SessionOverviewViewState(
+                deviceId = A_SESSION_ID,
+                isCurrentSession = true,
+                deviceInfo = Success(deviceFullInfo)
+        )
+
+        val viewModel = createViewModel()
+
+        viewModel.test()
+                .assertLatestState { state -> state == expectedState }
+                .finish()
+        verify { sessionParams.deviceId }
+        verify { getDeviceFullInfoUseCase.execute(A_SESSION_ID) }
+    }
+
+    private fun givenIdForSession(deviceId: String): SessionParams {
+        val sessionParams = mockk<SessionParams>()
+        every { sessionParams.deviceId } returns deviceId
+        fakeSession.givenSessionParams(sessionParams)
+        return sessionParams
+    }
+}
diff --git a/vector/src/test/java/im/vector/app/test/TestCoroutineDispatchers.kt b/vector/src/test/java/im/vector/app/test/TestCoroutineDispatchers.kt
index fb3c1bb70a..c4f4c2a19a 100644
--- a/vector/src/test/java/im/vector/app/test/TestCoroutineDispatchers.kt
+++ b/vector/src/test/java/im/vector/app/test/TestCoroutineDispatchers.kt
@@ -19,7 +19,7 @@ package im.vector.app.test
 import kotlinx.coroutines.test.UnconfinedTestDispatcher
 import org.matrix.android.sdk.api.MatrixCoroutineDispatchers
 
-private val testDispatcher = UnconfinedTestDispatcher()
+internal val testDispatcher = UnconfinedTestDispatcher()
 
 internal val testCoroutineDispatchers = MatrixCoroutineDispatchers(
         io = testDispatcher,
diff --git a/vector/src/test/java/im/vector/app/test/fakes/FakeActiveSessionHolder.kt b/vector/src/test/java/im/vector/app/test/fakes/FakeActiveSessionHolder.kt
index 3065c18c30..bfc36ef06d 100644
--- a/vector/src/test/java/im/vector/app/test/fakes/FakeActiveSessionHolder.kt
+++ b/vector/src/test/java/im/vector/app/test/fakes/FakeActiveSessionHolder.kt
@@ -33,4 +33,8 @@ class FakeActiveSessionHolder(
     fun expectSetsActiveSession(session: Session) {
         justRun { instance.setActiveSession(session) }
     }
+
+    fun givenGetSafeActiveSessionReturns(session: Session?) {
+        every { instance.getSafeActiveSession() } returns session
+    }
 }
diff --git a/vector/src/test/java/im/vector/app/test/fakes/FakeContext.kt b/vector/src/test/java/im/vector/app/test/fakes/FakeContext.kt
index 329ac1bdae..d74ebcb678 100644
--- a/vector/src/test/java/im/vector/app/test/fakes/FakeContext.kt
+++ b/vector/src/test/java/im/vector/app/test/fakes/FakeContext.kt
@@ -18,11 +18,14 @@ package im.vector.app.test.fakes
 
 import android.content.ContentResolver
 import android.content.Context
+import android.content.Intent
 import android.net.ConnectivityManager
 import android.net.Uri
 import android.os.ParcelFileDescriptor
 import io.mockk.every
+import io.mockk.just
 import io.mockk.mockk
+import io.mockk.runs
 import java.io.OutputStream
 
 class FakeContext(
@@ -67,4 +70,8 @@ class FakeContext(
         connectivityManager.givenHasActiveConnection()
         givenService(Context.CONNECTIVITY_SERVICE, ConnectivityManager::class.java, connectivityManager.instance)
     }
+
+    fun givenStartActivity(intent: Intent) {
+        every { instance.startActivity(intent) } just runs
+    }
 }
diff --git a/vector/src/test/java/im/vector/app/test/fakes/FakeCrossSigningService.kt b/vector/src/test/java/im/vector/app/test/fakes/FakeCrossSigningService.kt
new file mode 100644
index 0000000000..e9a5365b1c
--- /dev/null
+++ b/vector/src/test/java/im/vector/app/test/fakes/FakeCrossSigningService.kt
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2022 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.app.test.fakes
+
+import io.mockk.every
+import io.mockk.mockk
+import org.matrix.android.sdk.api.session.crypto.crosssigning.CrossSigningService
+
+class FakeCrossSigningService : CrossSigningService by mockk() {
+
+    fun givenIsCrossSigningInitializedReturns(isInitialized: Boolean) {
+        every { isCrossSigningInitialized() } returns isInitialized
+    }
+
+    fun givenIsCrossSigningVerifiedReturns(isVerified: Boolean) {
+        every { isCrossSigningVerified() } returns isVerified
+    }
+}
diff --git a/vector/src/test/java/im/vector/app/test/fakes/FakeCryptoService.kt b/vector/src/test/java/im/vector/app/test/fakes/FakeCryptoService.kt
index ed571fc2f2..197ccf4cd2 100644
--- a/vector/src/test/java/im/vector/app/test/fakes/FakeCryptoService.kt
+++ b/vector/src/test/java/im/vector/app/test/fakes/FakeCryptoService.kt
@@ -20,11 +20,19 @@ import androidx.lifecycle.MutableLiveData
 import io.mockk.mockk
 import org.matrix.android.sdk.api.session.crypto.CryptoService
 import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo
+import org.matrix.android.sdk.api.session.crypto.model.DeviceInfo
+import org.matrix.android.sdk.api.util.Optional
 
-class FakeCryptoService : CryptoService by mockk() {
+class FakeCryptoService(
+        val fakeCrossSigningService: FakeCrossSigningService = FakeCrossSigningService()
+) : CryptoService by mockk() {
 
     var roomKeysExport = ByteArray(size = 1)
     var cryptoDeviceInfos = mutableMapOf<String, CryptoDeviceInfo>()
+    var cryptoDeviceInfoWithIdLiveData: MutableLiveData<Optional<CryptoDeviceInfo>> = MutableLiveData()
+    var myDevicesInfoWithIdLiveData: MutableLiveData<Optional<DeviceInfo>> = MutableLiveData()
+
+    override fun crossSigningService() = fakeCrossSigningService
 
     override suspend fun exportRoomKeys(password: String) = roomKeysExport
 
@@ -35,4 +43,8 @@ class FakeCryptoService : CryptoService by mockk() {
     override fun getLiveCryptoDeviceInfo(userIds: List<String>) = MutableLiveData(
             cryptoDeviceInfos.filterKeys { userIds.contains(it) }.values.toList()
     )
+
+    override fun getLiveCryptoDeviceInfoWithId(deviceId: String) = cryptoDeviceInfoWithIdLiveData
+
+    override fun getMyDevicesInfoLive(deviceId: String) = myDevicesInfoWithIdLiveData
 }
diff --git a/vector/src/test/java/im/vector/app/test/fakes/FakeFlowLiveDataConversions.kt b/vector/src/test/java/im/vector/app/test/fakes/FakeFlowLiveDataConversions.kt
index 9abbcc174d..956a86f32e 100644
--- a/vector/src/test/java/im/vector/app/test/fakes/FakeFlowLiveDataConversions.kt
+++ b/vector/src/test/java/im/vector/app/test/fakes/FakeFlowLiveDataConversions.kt
@@ -28,6 +28,6 @@ class FakeFlowLiveDataConversions {
     }
 }
 
-fun <T> LiveData<T>.givenAsFlowReturns(value: T) {
-    every { asFlow() } returns flowOf(value)
+fun <T> LiveData<T>.givenAsFlow() {
+    every { asFlow() } returns flowOf(value!!)
 }
diff --git a/vector/src/test/java/im/vector/app/test/fakes/FakeSession.kt b/vector/src/test/java/im/vector/app/test/fakes/FakeSession.kt
index ee016ecae3..71bcde5807 100644
--- a/vector/src/test/java/im/vector/app/test/fakes/FakeSession.kt
+++ b/vector/src/test/java/im/vector/app/test/fakes/FakeSession.kt
@@ -26,6 +26,7 @@ import io.mockk.coJustRun
 import io.mockk.every
 import io.mockk.mockk
 import io.mockk.mockkStatic
+import org.matrix.android.sdk.api.auth.data.SessionParams
 import org.matrix.android.sdk.api.session.Session
 import org.matrix.android.sdk.api.session.getRoomSummary
 import org.matrix.android.sdk.api.session.homeserver.HomeServerCapabilitiesService
@@ -71,6 +72,10 @@ class FakeSession(
         }
     }
 
+    fun givenSessionParams(sessionParams: SessionParams) {
+        every { this@FakeSession.sessionParams } returns sessionParams
+    }
+
     companion object {
 
         fun withRoomSummary(roomSummary: RoomSummary) = FakeSession().apply {