mirror of
https://github.com/element-hq/element-android
synced 2024-11-24 10:25:35 +03:00
Suspend api: continue moving away from callback
This commit is contained in:
parent
9c6fccab1d
commit
ed84e38a9b
14 changed files with 103 additions and 121 deletions
|
@ -64,7 +64,7 @@ interface CryptoService {
|
|||
|
||||
fun setDeviceVerification(trustLevel: DeviceTrustLevel, userId: String, deviceId: String)
|
||||
|
||||
fun getUserDevices(userId: String): MutableList<CryptoDeviceInfo>
|
||||
suspend fun getUserDevices(userId: String): MutableList<CryptoDeviceInfo>
|
||||
|
||||
fun getMyDevice(): CryptoDeviceInfo
|
||||
|
||||
|
@ -84,7 +84,7 @@ interface CryptoService {
|
|||
|
||||
fun setRoomBlacklistUnverifiedDevices(roomId: String)
|
||||
|
||||
fun getDeviceInfo(userId: String, deviceId: String?): CryptoDeviceInfo?
|
||||
suspend fun getDeviceInfo(userId: String, deviceId: String?): CryptoDeviceInfo?
|
||||
|
||||
fun reRequestRoomKeyForEvent(event: Event)
|
||||
|
||||
|
@ -92,7 +92,7 @@ interface CryptoService {
|
|||
|
||||
fun removeRoomKeysRequestListener(listener: GossipingRequestListener)
|
||||
|
||||
fun fetchDevicesList(callback: MatrixCallback<DevicesListResponse>)
|
||||
suspend fun fetchDevicesList(): List<DeviceInfo>
|
||||
|
||||
fun getMyDevicesInfo(): List<DeviceInfo>
|
||||
|
||||
|
@ -112,7 +112,7 @@ interface CryptoService {
|
|||
fun discardOutboundSession(roomId: String)
|
||||
|
||||
@Throws(MXCryptoError::class)
|
||||
fun decryptEvent(event: Event, timeline: String): MXEventDecryptionResult
|
||||
suspend fun decryptEvent(event: Event, timeline: String): MXEventDecryptionResult
|
||||
|
||||
fun decryptEventAsync(event: Event, timeline: String, callback: MatrixCallback<MXEventDecryptionResult>)
|
||||
|
||||
|
@ -122,7 +122,7 @@ interface CryptoService {
|
|||
|
||||
suspend fun downloadKeys(userIds: List<String>, forceDownload: Boolean = false): MXUsersDevicesMap<CryptoDeviceInfo>
|
||||
|
||||
fun getCryptoDeviceInfo(userId: String): List<CryptoDeviceInfo>
|
||||
suspend fun getCryptoDeviceInfo(userId: String): List<CryptoDeviceInfo>
|
||||
|
||||
fun getLiveCryptoDeviceInfo(userId: String): Flow<List<CryptoDeviceInfo>>
|
||||
|
||||
|
|
|
@ -66,7 +66,6 @@ import org.matrix.android.sdk.internal.crypto.model.event.RoomKeyContent
|
|||
import org.matrix.android.sdk.internal.crypto.model.event.RoomKeyWithHeldContent
|
||||
import org.matrix.android.sdk.internal.crypto.model.event.SecretSendEventContent
|
||||
import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo
|
||||
import org.matrix.android.sdk.internal.crypto.model.rest.DevicesListResponse
|
||||
import org.matrix.android.sdk.internal.crypto.model.rest.ForwardedRoomKeyContent
|
||||
import org.matrix.android.sdk.internal.crypto.repository.WarnOnUnknownDeviceRepository
|
||||
import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore
|
||||
|
@ -224,23 +223,12 @@ internal class DefaultCryptoService @Inject constructor(
|
|||
return runBlocking { olmMachine.ownDevice() }
|
||||
}
|
||||
|
||||
override fun fetchDevicesList(callback: MatrixCallback<DevicesListResponse>) {
|
||||
getDevicesTask
|
||||
.configureWith {
|
||||
// this.executionThread = TaskThread.CRYPTO
|
||||
this.callback = object : MatrixCallback<DevicesListResponse> {
|
||||
override fun onFailure(failure: Throwable) {
|
||||
callback.onFailure(failure)
|
||||
}
|
||||
|
||||
override fun onSuccess(data: DevicesListResponse) {
|
||||
// Save in local DB
|
||||
cryptoStore.saveMyDevicesInfo(data.devices.orEmpty())
|
||||
callback.onSuccess(data)
|
||||
}
|
||||
}
|
||||
}
|
||||
.executeBy(taskExecutor)
|
||||
override suspend fun fetchDevicesList(): List<DeviceInfo> {
|
||||
val devicesList = tryOrNull {
|
||||
getDevicesTask.execute(Unit).devices
|
||||
}.orEmpty()
|
||||
cryptoStore.saveMyDevicesInfo(devicesList)
|
||||
return devicesList
|
||||
}
|
||||
|
||||
override fun getLiveMyDevicesInfo(): LiveData<List<DeviceInfo>> {
|
||||
|
@ -301,10 +289,9 @@ internal class DefaultCryptoService @Inject constructor(
|
|||
*/
|
||||
fun start() {
|
||||
internalStart()
|
||||
// Just update
|
||||
fetchDevicesList(NoOpMatrixCallback())
|
||||
|
||||
cryptoCoroutineScope.launch(coroutineDispatchers.crypto) {
|
||||
// Just update
|
||||
fetchDevicesList()
|
||||
cryptoStore.tidyUpDataBase()
|
||||
}
|
||||
}
|
||||
|
@ -412,20 +399,13 @@ internal class DefaultCryptoService @Inject constructor(
|
|||
* @param userId the user id
|
||||
* @param deviceId the device id
|
||||
*/
|
||||
override fun getDeviceInfo(userId: String, deviceId: String?): CryptoDeviceInfo? {
|
||||
return if (userId.isNotEmpty() && !deviceId.isNullOrEmpty()) {
|
||||
runBlocking {
|
||||
this@DefaultCryptoService.olmMachine.getCryptoDeviceInfo(userId, deviceId)
|
||||
}
|
||||
} else {
|
||||
null
|
||||
}
|
||||
override suspend fun getDeviceInfo(userId: String, deviceId: String?): CryptoDeviceInfo? {
|
||||
if (userId.isEmpty() || deviceId.isNullOrEmpty()) return null
|
||||
return olmMachine.getCryptoDeviceInfo(userId, deviceId)
|
||||
}
|
||||
|
||||
override fun getCryptoDeviceInfo(userId: String): List<CryptoDeviceInfo> {
|
||||
return runBlocking {
|
||||
this@DefaultCryptoService.olmMachine.getCryptoDeviceInfo(userId)
|
||||
}
|
||||
override suspend fun getCryptoDeviceInfo(userId: String): List<CryptoDeviceInfo> {
|
||||
return olmMachine.getCryptoDeviceInfo(userId)
|
||||
}
|
||||
|
||||
override fun getLiveCryptoDeviceInfo(userId: String): Flow<List<CryptoDeviceInfo>> {
|
||||
|
@ -503,7 +483,7 @@ internal class DefaultCryptoService @Inject constructor(
|
|||
/**
|
||||
* @return the stored device keys for a user.
|
||||
*/
|
||||
override fun getUserDevices(userId: String): MutableList<CryptoDeviceInfo> {
|
||||
override suspend fun getUserDevices(userId: String): MutableList<CryptoDeviceInfo> {
|
||||
return this.getCryptoDeviceInfo(userId).toMutableList()
|
||||
}
|
||||
|
||||
|
@ -577,10 +557,8 @@ internal class DefaultCryptoService @Inject constructor(
|
|||
* @return the MXEventDecryptionResult data, or throw in case of error
|
||||
*/
|
||||
@Throws(MXCryptoError::class)
|
||||
override fun decryptEvent(event: Event, timeline: String): MXEventDecryptionResult {
|
||||
return runBlocking {
|
||||
olmMachine.decryptRoomEvent(event)
|
||||
}
|
||||
override suspend fun decryptEvent(event: Event, timeline: String): MXEventDecryptionResult {
|
||||
return olmMachine.decryptRoomEvent(event)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -362,11 +362,11 @@ internal class OlmMachine(
|
|||
suspend fun decryptRoomEvent(event: Event): MXEventDecryptionResult =
|
||||
withContext(Dispatchers.IO) {
|
||||
val adapter = MoshiProvider.providesMoshi().adapter(Event::class.java)
|
||||
val serializedEvent = adapter.toJson(event)
|
||||
try {
|
||||
if (event.roomId.isNullOrBlank()) {
|
||||
throw MXCryptoError.Base(MXCryptoError.ErrorType.MISSING_FIELDS, MXCryptoError.MISSING_FIELDS_REASON)
|
||||
}
|
||||
val serializedEvent = adapter.toJson(event)
|
||||
val decrypted = inner.decryptRoomEvent(serializedEvent, event.roomId)
|
||||
|
||||
val deserializationAdapter =
|
||||
|
|
|
@ -156,7 +156,7 @@ internal class DefaultFetchThreadTimelineTask @Inject constructor(
|
|||
* Invoke the event decryption mechanism for a specific event
|
||||
*/
|
||||
|
||||
private fun decryptIfNeeded(event: Event, roomId: String) {
|
||||
private suspend fun decryptIfNeeded(event: Event, roomId: String) {
|
||||
try {
|
||||
// Event from sync does not have roomId, so add it to the event first
|
||||
val result = cryptoService.decryptEvent(event.copy(roomId = roomId), "")
|
||||
|
|
|
@ -43,6 +43,7 @@ internal class RealmSendingEventsDataSource(
|
|||
private var roomEntity: RoomEntity? = null
|
||||
private var sendingTimelineEvents: RealmList<TimelineEventEntity>? = null
|
||||
private var frozenSendingTimelineEvents: RealmList<TimelineEventEntity>? = null
|
||||
private val builtEvents = ArrayList<TimelineEvent>()
|
||||
|
||||
private val sendingTimelineEventsListener = RealmChangeListener<RealmList<TimelineEventEntity>> { events ->
|
||||
uiEchoManager.onSentEventsInDatabase(events.map { it.eventId })
|
||||
|
|
|
@ -17,6 +17,7 @@ package org.matrix.android.sdk.internal.session.room.timeline
|
|||
|
||||
import io.realm.Realm
|
||||
import io.realm.RealmConfiguration
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.matrix.android.sdk.api.session.crypto.CryptoService
|
||||
import org.matrix.android.sdk.api.session.crypto.MXCryptoError
|
||||
import org.matrix.android.sdk.api.session.events.model.Event
|
||||
|
@ -126,7 +127,9 @@ internal class TimelineEventDecryptor @Inject constructor(
|
|||
return
|
||||
}
|
||||
try {
|
||||
val result = cryptoService.decryptEvent(request.event, timelineId)
|
||||
val result = runBlocking {
|
||||
cryptoService.decryptEvent(request.event, timelineId)
|
||||
}
|
||||
Timber.v("Successfully decrypted event ${event.eventId}")
|
||||
realm.executeTransaction {
|
||||
val eventId = event.eventId ?: return@executeTransaction
|
||||
|
|
|
@ -19,6 +19,7 @@ package org.matrix.android.sdk.internal.session.sync.handler.room
|
|||
import dagger.Lazy
|
||||
import io.realm.Realm
|
||||
import io.realm.kotlin.createObject
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.matrix.android.sdk.api.session.crypto.MXCryptoError
|
||||
import org.matrix.android.sdk.api.session.events.model.Event
|
||||
import org.matrix.android.sdk.api.session.events.model.EventType
|
||||
|
@ -343,7 +344,7 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle
|
|||
return roomEntity
|
||||
}
|
||||
|
||||
private suspend fun handleTimelineEvents(realm: Realm,
|
||||
private fun handleTimelineEvents(realm: Realm,
|
||||
roomId: String,
|
||||
roomEntity: RoomEntity,
|
||||
eventList: List<Event>,
|
||||
|
@ -458,7 +459,9 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle
|
|||
private fun decryptIfNeeded(event: Event, roomId: String) {
|
||||
try {
|
||||
// Event from sync does not have roomId, so add it to the event first
|
||||
val result = cryptoService.decryptEvent(event.copy(roomId = roomId), "")
|
||||
val result = runBlocking {
|
||||
cryptoService.decryptEvent(event.copy(roomId = roomId), "")
|
||||
}
|
||||
event.mxDecryptionResult = OlmDecryptionResult(
|
||||
payload = result.clearEvent,
|
||||
senderKey = result.senderCurve25519Key,
|
||||
|
|
|
@ -131,28 +131,29 @@ class VerificationBottomSheetViewModel @AssistedInject constructor(
|
|||
session.cryptoService().verificationService().getExistingTransaction(initialState.otherUserId, it) as? QrCodeVerificationTransaction
|
||||
}
|
||||
|
||||
val hasAnyOtherSession = session.cryptoService()
|
||||
.getCryptoDeviceInfo(session.myUserId)
|
||||
.any {
|
||||
it.deviceId != session.sessionParams.deviceId
|
||||
}
|
||||
viewModelScope.launch {
|
||||
|
||||
setState {
|
||||
copy(
|
||||
otherUserMxItem = userItem?.toMatrixItem(),
|
||||
sasTransactionState = sasTx?.state,
|
||||
qrTransactionState = qrTx?.state,
|
||||
transactionId = pr?.transactionId ?: initialState.verificationId,
|
||||
pendingRequest = if (pr != null) Success(pr) else Uninitialized,
|
||||
isMe = initialState.otherUserId == session.myUserId,
|
||||
currentDeviceCanCrossSign = session.cryptoService().crossSigningService().canCrossSign(),
|
||||
quadSContainsSecrets = session.sharedSecretStorageService.isRecoverySetup(),
|
||||
hasAnyOtherSession = hasAnyOtherSession
|
||||
)
|
||||
}
|
||||
val hasAnyOtherSession = session.cryptoService()
|
||||
.getCryptoDeviceInfo(session.myUserId)
|
||||
.any {
|
||||
it.deviceId != session.sessionParams.deviceId
|
||||
}
|
||||
|
||||
if (autoReady) {
|
||||
viewModelScope.launch {
|
||||
setState {
|
||||
copy(
|
||||
otherUserMxItem = userItem?.toMatrixItem(),
|
||||
sasTransactionState = sasTx?.state,
|
||||
qrTransactionState = qrTx?.state,
|
||||
transactionId = pr?.transactionId ?: initialState.verificationId,
|
||||
pendingRequest = if (pr != null) Success(pr) else Uninitialized,
|
||||
isMe = initialState.otherUserId == session.myUserId,
|
||||
currentDeviceCanCrossSign = session.cryptoService().crossSigningService().canCrossSign(),
|
||||
quadSContainsSecrets = session.sharedSecretStorageService.isRecoverySetup(),
|
||||
hasAnyOtherSession = hasAnyOtherSession
|
||||
)
|
||||
}
|
||||
|
||||
if (autoReady) {
|
||||
// TODO, can I be here in DM mode? in this case should test if roomID is null?
|
||||
session.cryptoService().verificationService()
|
||||
.readyPendingVerification(
|
||||
|
@ -480,7 +481,7 @@ class VerificationBottomSheetViewModel @AssistedInject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private fun handleTransactionUpdate(state: VerificationBottomSheetViewState, tx: VerificationTransaction){
|
||||
private fun handleTransactionUpdate(state: VerificationBottomSheetViewState, tx: VerificationTransaction) {
|
||||
viewModelScope.launch {
|
||||
if (state.selfVerificationMode && state.transactionId == null) {
|
||||
// is this an incoming with that user
|
||||
|
|
|
@ -32,10 +32,11 @@ import im.vector.app.core.platform.VectorViewModelAction
|
|||
import im.vector.app.features.settings.VectorPreferences
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.flow
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.flow.sample
|
||||
import org.matrix.android.sdk.api.NoOpMatrixCallback
|
||||
import kotlinx.coroutines.launch
|
||||
import org.matrix.android.sdk.api.extensions.orFalse
|
||||
import org.matrix.android.sdk.api.session.Session
|
||||
import org.matrix.android.sdk.api.util.MatrixItem
|
||||
|
@ -58,7 +59,7 @@ data class DeviceDetectionInfo(
|
|||
class UnknownDeviceDetectorSharedViewModel @AssistedInject constructor(@Assisted initialState: UnknownDevicesState,
|
||||
session: Session,
|
||||
private val vectorPreferences: VectorPreferences) :
|
||||
VectorViewModel<UnknownDevicesState, UnknownDeviceDetectorSharedViewModel.Action, EmptyViewEvents>(initialState) {
|
||||
VectorViewModel<UnknownDevicesState, UnknownDeviceDetectorSharedViewModel.Action, EmptyViewEvents>(initialState) {
|
||||
|
||||
sealed class Action : VectorViewModelAction {
|
||||
data class IgnoreDevice(val deviceIds: List<String>) : Action()
|
||||
|
@ -75,12 +76,6 @@ class UnknownDeviceDetectorSharedViewModel @AssistedInject constructor(@Assisted
|
|||
|
||||
init {
|
||||
|
||||
val currentSessionTs = session.cryptoService().getCryptoDeviceInfo(session.myUserId)
|
||||
.firstOrNull { it.deviceId == session.sessionParams.deviceId }
|
||||
?.firstTimeSeenLocalTs
|
||||
?: System.currentTimeMillis()
|
||||
Timber.v("## Detector - Current Session first time seen $currentSessionTs")
|
||||
|
||||
ignoredDeviceList.addAll(
|
||||
vectorPreferences.getUnknownDeviceDismissedList().also {
|
||||
Timber.v("## Detector - Remembered ignored list $it")
|
||||
|
@ -90,10 +85,12 @@ class UnknownDeviceDetectorSharedViewModel @AssistedInject constructor(@Assisted
|
|||
combine(
|
||||
session.flow().liveUserCryptoDevices(session.myUserId),
|
||||
session.flow().liveMyDevicesInfo(),
|
||||
session.flow().liveCrossSigningPrivateKeys()
|
||||
) { cryptoList, infoList, pInfo ->
|
||||
session.flow().liveCrossSigningPrivateKeys(),
|
||||
session.firstTimeDeviceSeen(),
|
||||
) { cryptoList, infoList, pInfo, firstTimeDeviceSeen ->
|
||||
// Timber.v("## Detector trigger ${cryptoList.map { "${it.deviceId} ${it.trustLevel}" }}")
|
||||
// Timber.v("## Detector trigger canCrossSign ${pInfo.get().selfSigned != null}")
|
||||
Timber.v("## Detector - Current Session first time seen $firstTimeDeviceSeen")
|
||||
infoList
|
||||
.filter { info ->
|
||||
// filter verified session, by checking the crypto device info
|
||||
|
@ -106,7 +103,7 @@ class UnknownDeviceDetectorSharedViewModel @AssistedInject constructor(@Assisted
|
|||
val deviceKnownSince = cryptoList.firstOrNull { it.deviceId == deviceInfo.deviceId }?.firstTimeSeenLocalTs ?: 0
|
||||
DeviceDetectionInfo(
|
||||
deviceInfo,
|
||||
deviceKnownSince > currentSessionTs + 60_000, // short window to avoid false positive,
|
||||
deviceKnownSince > firstTimeDeviceSeen + 60_000, // short window to avoid false positive,
|
||||
pInfo.getOrNull()?.selfSigned != null // adding this to pass distinct when cross sign change
|
||||
)
|
||||
}
|
||||
|
@ -125,12 +122,14 @@ class UnknownDeviceDetectorSharedViewModel @AssistedInject constructor(@Assisted
|
|||
.sample(5_000)
|
||||
.onEach {
|
||||
// If we have a new crypto device change, we might want to trigger refresh of device info
|
||||
session.cryptoService().fetchDevicesList(NoOpMatrixCallback())
|
||||
session.cryptoService().fetchDevicesList()
|
||||
}
|
||||
.launchIn(viewModelScope)
|
||||
|
||||
// trigger a refresh of lastSeen / last Ip
|
||||
session.cryptoService().fetchDevicesList(NoOpMatrixCallback())
|
||||
viewModelScope.launch {
|
||||
session.cryptoService().fetchDevicesList()
|
||||
}
|
||||
}
|
||||
|
||||
override fun handle(action: Action) {
|
||||
|
@ -154,4 +153,13 @@ class UnknownDeviceDetectorSharedViewModel @AssistedInject constructor(@Assisted
|
|||
vectorPreferences.storeUnknownDeviceDismissedList(ignoredDeviceList)
|
||||
super.onCleared()
|
||||
}
|
||||
|
||||
private fun Session.firstTimeDeviceSeen() = flow {
|
||||
val value = cryptoService().getCryptoDeviceInfo(myUserId)
|
||||
.firstOrNull { it.deviceId == sessionParams.deviceId }
|
||||
?.firstTimeSeenLocalTs
|
||||
?: System.currentTimeMillis()
|
||||
emit(value)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -164,11 +164,12 @@ class MessageActionsViewModel @AssistedInject constructor(@Assisted
|
|||
onEach(MessageActionState::timelineEvent, MessageActionState::actionPermissions) { timelineEvent, permissions ->
|
||||
val nonNullTimelineEvent = timelineEvent() ?: return@onEach
|
||||
eventIdFlow.tryEmit(nonNullTimelineEvent.eventId)
|
||||
val events = actionsForEvent(nonNullTimelineEvent, permissions)
|
||||
setState {
|
||||
copy(
|
||||
eventId = nonNullTimelineEvent.eventId,
|
||||
messageBody = computeMessageBody(nonNullTimelineEvent),
|
||||
actions = actionsForEvent(nonNullTimelineEvent, permissions)
|
||||
actions = events
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -246,7 +247,7 @@ class MessageActionsViewModel @AssistedInject constructor(@Assisted
|
|||
}
|
||||
}
|
||||
|
||||
private fun actionsForEvent(timelineEvent: TimelineEvent, actionPermissions: ActionPermissions): List<EventSharedAction> {
|
||||
private suspend fun actionsForEvent(timelineEvent: TimelineEvent, actionPermissions: ActionPermissions): List<EventSharedAction> {
|
||||
val messageContent = timelineEvent.getLastMessageContent()
|
||||
val msgType = messageContent?.msgType
|
||||
|
||||
|
@ -317,7 +318,7 @@ class MessageActionsViewModel @AssistedInject constructor(@Assisted
|
|||
// TODO sent by me or sufficient power level
|
||||
}
|
||||
|
||||
private fun ArrayList<EventSharedAction>.addActionsForSyncedState(timelineEvent: TimelineEvent,
|
||||
private suspend fun ArrayList<EventSharedAction>.addActionsForSyncedState(timelineEvent: TimelineEvent,
|
||||
actionPermissions: ActionPermissions,
|
||||
messageContent: MessageContent?,
|
||||
msgType: String?) {
|
||||
|
|
|
@ -139,20 +139,18 @@ class MessageInformationDataFactory @Inject constructor(private val session: Ses
|
|||
}
|
||||
}
|
||||
|
||||
private fun getE2EDecoration(roomSummary: RoomSummary?, event: TimelineEvent): E2EDecoration {
|
||||
private fun getE2EDecoration(roomSummary: RoomSummary?, event: TimelineEvent): E2EDecoration = runBlocking{
|
||||
if (event.root.sendState != SendState.SYNCED)
|
||||
return E2EDecoration.NONE
|
||||
return@runBlocking E2EDecoration.NONE
|
||||
if (!roomSummary?.isEncrypted.orFalse())
|
||||
return E2EDecoration.NONE
|
||||
val isUserVerified = runBlocking {
|
||||
session.cryptoService().crossSigningService().getUserCrossSigningKeys(event.root.senderId ?: "")?.isTrusted().orFalse()
|
||||
}
|
||||
return@runBlocking E2EDecoration.NONE
|
||||
val isUserVerified = session.cryptoService().crossSigningService().getUserCrossSigningKeys(event.root.senderId ?: "")?.isTrusted().orFalse()
|
||||
if (!isUserVerified) {
|
||||
return E2EDecoration.NONE
|
||||
return@runBlocking E2EDecoration.NONE
|
||||
}
|
||||
val ts = roomSummary?.encryptionEventTs ?: 0
|
||||
val eventTs = event.root.originServerTs ?: 0
|
||||
return if (event.isEncrypted()) {
|
||||
return@runBlocking if (event.isEncrypted()) {
|
||||
// Do not decorate failed to decrypt, or redaction (we lost sender device info)
|
||||
if (event.root.getClearType() == EventType.ENCRYPTED || event.root.isRedacted()) {
|
||||
E2EDecoration.NONE
|
||||
|
|
|
@ -190,7 +190,7 @@ class NotifiableEventResolver @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private fun TimelineEvent.attemptToDecryptIfNeeded(session: Session) {
|
||||
private suspend fun TimelineEvent.attemptToDecryptIfNeeded(session: Session) {
|
||||
if (root.isEncrypted() && root.mxDecryptionResult == null) {
|
||||
// TODO use a global event decryptor? attache to session and that listen to new sessionId?
|
||||
// for now decrypt sync
|
||||
|
|
|
@ -70,12 +70,10 @@ import kotlinx.coroutines.flow.launchIn
|
|||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.launch
|
||||
import me.gujun.android.span.span
|
||||
import org.matrix.android.sdk.api.MatrixCallback
|
||||
import org.matrix.android.sdk.api.extensions.getFingerprintHumanReadable
|
||||
import org.matrix.android.sdk.api.raw.RawService
|
||||
import org.matrix.android.sdk.internal.crypto.crosssigning.isVerified
|
||||
import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo
|
||||
import org.matrix.android.sdk.internal.crypto.model.rest.DevicesListResponse
|
||||
import javax.inject.Inject
|
||||
|
||||
class VectorSettingsSecurityPrivacyFragment @Inject constructor(
|
||||
|
@ -524,7 +522,7 @@ class VectorSettingsSecurityPrivacyFragment @Inject constructor(
|
|||
/**
|
||||
* Build the cryptography preference section.
|
||||
*/
|
||||
private fun refreshCryptographyPreference(devices: List<DeviceInfo>) {
|
||||
private suspend fun refreshCryptographyPreference(devices: List<DeviceInfo>) {
|
||||
showDeviceListPref.isEnabled = devices.isNotEmpty()
|
||||
showDeviceListPref.summary = resources.getQuantityString(R.plurals.settings_active_sessions_count, devices.size, devices.size)
|
||||
|
||||
|
@ -580,28 +578,19 @@ class VectorSettingsSecurityPrivacyFragment @Inject constructor(
|
|||
// ==============================================================================================================
|
||||
|
||||
private fun refreshMyDevice() {
|
||||
session.cryptoService().getUserDevices(session.myUserId).map {
|
||||
DeviceInfo(
|
||||
userId = session.myUserId,
|
||||
deviceId = it.deviceId,
|
||||
displayName = it.displayName()
|
||||
)
|
||||
}.let {
|
||||
refreshCryptographyPreference(it)
|
||||
viewLifecycleOwner.lifecycleScope.launchWhenResumed {
|
||||
session.cryptoService().getUserDevices(session.myUserId).map {
|
||||
DeviceInfo(
|
||||
userId = session.myUserId,
|
||||
deviceId = it.deviceId,
|
||||
displayName = it.displayName()
|
||||
)
|
||||
}.let {
|
||||
refreshCryptographyPreference(it)
|
||||
}
|
||||
// TODO Move to a ViewModel...
|
||||
val devicesList = session.cryptoService().fetchDevicesList()
|
||||
refreshCryptographyPreference(devicesList)
|
||||
}
|
||||
// TODO Move to a ViewModel...
|
||||
session.cryptoService().fetchDevicesList(object : MatrixCallback<DevicesListResponse> {
|
||||
override fun onSuccess(data: DevicesListResponse) {
|
||||
if (isAdded) {
|
||||
refreshCryptographyPreference(data.devices.orEmpty())
|
||||
}
|
||||
}
|
||||
|
||||
override fun onFailure(failure: Throwable) {
|
||||
if (isAdded) {
|
||||
refreshCryptographyPreference(emptyList())
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -147,7 +147,7 @@ class DevicesViewModel @AssistedInject constructor(
|
|||
.sample(5_000)
|
||||
.onEach {
|
||||
// If we have a new crypto device change, we might want to trigger refresh of device info
|
||||
session.cryptoService().fetchDevicesList(NoOpMatrixCallback())
|
||||
session.cryptoService().fetchDevicesList()
|
||||
}
|
||||
.launchIn(viewModelScope)
|
||||
|
||||
|
@ -160,7 +160,7 @@ class DevicesViewModel @AssistedInject constructor(
|
|||
|
||||
refreshSource.stream().throttleFirst(4_000)
|
||||
.onEach {
|
||||
session.cryptoService().fetchDevicesList(NoOpMatrixCallback())
|
||||
session.cryptoService().fetchDevicesList()
|
||||
session.cryptoService().downloadKeys(listOf(session.myUserId), true)
|
||||
}
|
||||
.launchIn(viewModelScope)
|
||||
|
|
Loading…
Reference in a new issue