Continue removing runBlocking + some cleanup
This commit is contained in:
parent
d020d1f6e0
commit
ba540eb861
@ -66,7 +66,7 @@ interface CryptoService {
|
|||||||
|
|
||||||
suspend fun getUserDevices(userId: String): MutableList<CryptoDeviceInfo>
|
suspend fun getUserDevices(userId: String): MutableList<CryptoDeviceInfo>
|
||||||
|
|
||||||
fun getMyDevice(): CryptoDeviceInfo
|
suspend fun getMyDevice(): CryptoDeviceInfo
|
||||||
|
|
||||||
fun getGlobalBlacklistUnverifiedDevices(): Boolean
|
fun getGlobalBlacklistUnverifiedDevices(): Boolean
|
||||||
|
|
||||||
@ -104,10 +104,9 @@ interface CryptoService {
|
|||||||
|
|
||||||
fun isRoomEncrypted(roomId: String): Boolean
|
fun isRoomEncrypted(roomId: String): Boolean
|
||||||
|
|
||||||
fun encryptEventContent(eventContent: Content,
|
suspend fun encryptEventContent(eventContent: Content,
|
||||||
eventType: String,
|
eventType: String,
|
||||||
roomId: String,
|
roomId: String): MXEncryptEventContentResult
|
||||||
callback: MatrixCallback<MXEncryptEventContentResult>)
|
|
||||||
|
|
||||||
fun discardOutboundSession(roomId: String)
|
fun discardOutboundSession(roomId: String)
|
||||||
|
|
||||||
@ -151,7 +150,7 @@ interface CryptoService {
|
|||||||
* Perform any background tasks that can be done before a message is ready to
|
* Perform any background tasks that can be done before a message is ready to
|
||||||
* send, in order to speed up sending of the message.
|
* send, in order to speed up sending of the message.
|
||||||
*/
|
*/
|
||||||
fun prepareToEncrypt(roomId: String, callback: MatrixCallback<Unit>)
|
suspend fun prepareToEncrypt(roomId: String)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When LL all room members might not be loaded when setting up encryption.
|
* When LL all room members might not be loaded when setting up encryption.
|
||||||
|
@ -22,13 +22,13 @@ import androidx.lifecycle.LiveData
|
|||||||
import androidx.paging.PagedList
|
import androidx.paging.PagedList
|
||||||
import kotlinx.coroutines.CancellationException
|
import kotlinx.coroutines.CancellationException
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.NonCancellable
|
||||||
import kotlinx.coroutines.async
|
import kotlinx.coroutines.async
|
||||||
import kotlinx.coroutines.cancelChildren
|
import kotlinx.coroutines.cancelChildren
|
||||||
import kotlinx.coroutines.coroutineScope
|
import kotlinx.coroutines.coroutineScope
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.joinAll
|
import kotlinx.coroutines.joinAll
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.runBlocking
|
|
||||||
import kotlinx.coroutines.sync.Mutex
|
import kotlinx.coroutines.sync.Mutex
|
||||||
import kotlinx.coroutines.sync.withLock
|
import kotlinx.coroutines.sync.withLock
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
@ -76,7 +76,6 @@ import org.matrix.android.sdk.internal.crypto.tasks.SetDeviceNameTask
|
|||||||
import org.matrix.android.sdk.internal.crypto.verification.RustVerificationService
|
import org.matrix.android.sdk.internal.crypto.verification.RustVerificationService
|
||||||
import org.matrix.android.sdk.internal.di.DeviceId
|
import org.matrix.android.sdk.internal.di.DeviceId
|
||||||
import org.matrix.android.sdk.internal.di.UserId
|
import org.matrix.android.sdk.internal.di.UserId
|
||||||
import org.matrix.android.sdk.internal.extensions.foldToCallback
|
|
||||||
import org.matrix.android.sdk.internal.session.SessionScope
|
import org.matrix.android.sdk.internal.session.SessionScope
|
||||||
import org.matrix.android.sdk.internal.session.StreamEventsManager
|
import org.matrix.android.sdk.internal.session.StreamEventsManager
|
||||||
import org.matrix.android.sdk.internal.session.room.membership.LoadRoomMembersTask
|
import org.matrix.android.sdk.internal.session.room.membership.LoadRoomMembersTask
|
||||||
@ -219,8 +218,8 @@ internal class DefaultCryptoService @Inject constructor(
|
|||||||
return if (longFormat) "Rust SDK 0.3" else "0.3"
|
return if (longFormat) "Rust SDK 0.3" else "0.3"
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getMyDevice(): CryptoDeviceInfo {
|
override suspend fun getMyDevice(): CryptoDeviceInfo {
|
||||||
return runBlocking { olmMachine.ownDevice() }
|
return olmMachine.ownDevice()
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun fetchDevicesList(): List<DeviceInfo> {
|
override suspend fun fetchDevicesList(): List<DeviceInfo> {
|
||||||
@ -344,10 +343,14 @@ internal class DefaultCryptoService @Inject constructor(
|
|||||||
/**
|
/**
|
||||||
* Close the crypto
|
* Close the crypto
|
||||||
*/
|
*/
|
||||||
fun close() = runBlocking(coroutineDispatchers.crypto) {
|
fun close() {
|
||||||
cryptoCoroutineScope.coroutineContext.cancelChildren(CancellationException("Closing crypto module"))
|
cryptoCoroutineScope.coroutineContext.cancelChildren(CancellationException("Closing crypto module"))
|
||||||
|
cryptoCoroutineScope.launch {
|
||||||
|
withContext(coroutineDispatchers.crypto + NonCancellable) {
|
||||||
cryptoStore.close()
|
cryptoStore.close()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Always enabled on Matrix Android SDK2
|
// Always enabled on Matrix Android SDK2
|
||||||
override fun isCryptoEnabled() = true
|
override fun isCryptoEnabled() = true
|
||||||
@ -513,21 +516,17 @@ internal class DefaultCryptoService @Inject constructor(
|
|||||||
* @param eventContent the content of the event.
|
* @param eventContent the content of the event.
|
||||||
* @param eventType the type of the event.
|
* @param eventType the type of the event.
|
||||||
* @param roomId the room identifier the event will be sent.
|
* @param roomId the room identifier the event will be sent.
|
||||||
* @param callback the asynchronous callback
|
|
||||||
*/
|
*/
|
||||||
override fun encryptEventContent(eventContent: Content,
|
override suspend fun encryptEventContent(eventContent: Content,
|
||||||
eventType: String,
|
eventType: String,
|
||||||
roomId: String,
|
roomId: String): MXEncryptEventContentResult {
|
||||||
callback: MatrixCallback<MXEncryptEventContentResult>) {
|
|
||||||
// moved to crypto scope to have up to date values
|
// moved to crypto scope to have up to date values
|
||||||
cryptoCoroutineScope.launch(coroutineDispatchers.crypto) {
|
return withContext(coroutineDispatchers.crypto) {
|
||||||
val algorithm = getEncryptionAlgorithm(roomId)
|
val algorithm = getEncryptionAlgorithm(roomId)
|
||||||
|
|
||||||
if (algorithm != null) {
|
if (algorithm != null) {
|
||||||
val userIds = getRoomUserIds(roomId)
|
val userIds = getRoomUserIds(roomId)
|
||||||
val t0 = System.currentTimeMillis()
|
val t0 = System.currentTimeMillis()
|
||||||
Timber.tag(loggerTag.value).v("encryptEventContent() starts")
|
Timber.tag(loggerTag.value).v("encryptEventContent() starts")
|
||||||
runCatching {
|
|
||||||
measureTimeMillis {
|
measureTimeMillis {
|
||||||
preshareRoomKey(roomId, userIds)
|
preshareRoomKey(roomId, userIds)
|
||||||
}.also {
|
}.also {
|
||||||
@ -536,11 +535,10 @@ internal class DefaultCryptoService @Inject constructor(
|
|||||||
val content = encrypt(roomId, eventType, eventContent)
|
val content = encrypt(roomId, eventType, eventContent)
|
||||||
Timber.tag(loggerTag.value).v("## CRYPTO | encryptEventContent() : succeeds after ${System.currentTimeMillis() - t0} ms")
|
Timber.tag(loggerTag.value).v("## CRYPTO | encryptEventContent() : succeeds after ${System.currentTimeMillis() - t0} ms")
|
||||||
MXEncryptEventContentResult(content, EventType.ENCRYPTED)
|
MXEncryptEventContentResult(content, EventType.ENCRYPTED)
|
||||||
}.foldToCallback(callback)
|
|
||||||
} else {
|
} else {
|
||||||
val reason = String.format(MXCryptoError.UNABLE_TO_ENCRYPT_REASON, MXCryptoError.NO_MORE_ALGORITHM_REASON)
|
val reason = String.format(MXCryptoError.UNABLE_TO_ENCRYPT_REASON, MXCryptoError.NO_MORE_ALGORITHM_REASON)
|
||||||
Timber.tag(loggerTag.value).e("encryptEventContent() : failed $reason")
|
Timber.tag(loggerTag.value).e("encryptEventContent() : failed $reason")
|
||||||
callback.onFailure(Failure.CryptoError(MXCryptoError.Base(MXCryptoError.ErrorType.UNABLE_TO_ENCRYPT, reason)))
|
throw Failure.CryptoError(MXCryptoError.Base(MXCryptoError.ErrorType.UNABLE_TO_ENCRYPT, reason))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -707,26 +705,12 @@ internal class DefaultCryptoService @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun preshareRoomKey(roomId: String, roomMembers: List<String>) {
|
private suspend fun preshareRoomKey(roomId: String, roomMembers: List<String>) {
|
||||||
keyClaimLock.withLock {
|
claimMissingKeys(roomMembers)
|
||||||
val request = this.olmMachine.getMissingSessions(roomMembers)
|
val keyShareLock = roomKeyShareLocks.getOrPut(roomId) { Mutex() }
|
||||||
// This request can only be a keys claim request.
|
|
||||||
if (request != null) {
|
|
||||||
when (request) {
|
|
||||||
is Request.KeysClaim -> {
|
|
||||||
claimKeys(request)
|
|
||||||
}
|
|
||||||
else -> {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val keyShareLock = roomKeyShareLocks.getOrPut(roomId, { Mutex() })
|
|
||||||
var sharedKey = false
|
var sharedKey = false
|
||||||
|
|
||||||
keyShareLock.withLock {
|
keyShareLock.withLock {
|
||||||
coroutineScope {
|
coroutineScope {
|
||||||
this@DefaultCryptoService.olmMachine.shareRoomKey(roomId, roomMembers).map {
|
olmMachine.shareRoomKey(roomId, roomMembers).map {
|
||||||
when (it) {
|
when (it) {
|
||||||
is Request.ToDevice -> {
|
is Request.ToDevice -> {
|
||||||
sharedKey = true
|
sharedKey = true
|
||||||
@ -752,6 +736,18 @@ internal class DefaultCryptoService @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private suspend fun claimMissingKeys(roomMembers: List<String>) = keyClaimLock.withLock {
|
||||||
|
val request = this.olmMachine.getMissingSessions(roomMembers)
|
||||||
|
// This request can only be a keys claim request.
|
||||||
|
when (request) {
|
||||||
|
is Request.KeysClaim -> {
|
||||||
|
claimKeys(request)
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private suspend fun encrypt(roomId: String, eventType: String, content: Content): Content {
|
private suspend fun encrypt(roomId: String, eventType: String, content: Content): Content {
|
||||||
return olmMachine.encrypt(roomId, eventType, content)
|
return olmMachine.encrypt(roomId, eventType, content)
|
||||||
}
|
}
|
||||||
@ -810,7 +806,7 @@ internal class DefaultCryptoService @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun sendRoomMessage(request: Request.RoomMessage){
|
private suspend fun sendRoomMessage(request: Request.RoomMessage) {
|
||||||
try {
|
try {
|
||||||
requestSender.sendRoomMessage(request)
|
requestSender.sendRoomMessage(request)
|
||||||
} catch (throwable: Throwable) {
|
} catch (throwable: Throwable) {
|
||||||
@ -1083,18 +1079,16 @@ internal class DefaultCryptoService @Inject constructor(
|
|||||||
cryptoStore.logDbUsageInfo()
|
cryptoStore.logDbUsageInfo()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun prepareToEncrypt(roomId: String, callback: MatrixCallback<Unit>) {
|
override suspend fun prepareToEncrypt(roomId: String) {
|
||||||
cryptoCoroutineScope.launch(coroutineDispatchers.crypto) {
|
withContext(coroutineDispatchers.crypto) {
|
||||||
Timber.tag(loggerTag.value).d("prepareToEncrypt() roomId:$roomId Check room members up to date")
|
Timber.tag(loggerTag.value).d("prepareToEncrypt() roomId:$roomId Check room members up to date")
|
||||||
// Ensure to load all room members
|
// Ensure to load all room members
|
||||||
try {
|
try {
|
||||||
loadRoomMembersTask.execute(LoadRoomMembersTask.Params(roomId))
|
loadRoomMembersTask.execute(LoadRoomMembersTask.Params(roomId))
|
||||||
} catch (failure: Throwable) {
|
} catch (failure: Throwable) {
|
||||||
Timber.tag(loggerTag.value).e("prepareToEncrypt() : Failed to load room members")
|
Timber.tag(loggerTag.value).e("prepareToEncrypt() : Failed to load room members")
|
||||||
callback.onFailure(failure)
|
throw failure
|
||||||
return@launch
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val userIds = getRoomUserIds(roomId)
|
val userIds = getRoomUserIds(roomId)
|
||||||
|
|
||||||
val algorithm = getEncryptionAlgorithm(roomId)
|
val algorithm = getEncryptionAlgorithm(roomId)
|
||||||
@ -1102,19 +1096,13 @@ internal class DefaultCryptoService @Inject constructor(
|
|||||||
if (algorithm == null) {
|
if (algorithm == null) {
|
||||||
val reason = String.format(MXCryptoError.UNABLE_TO_ENCRYPT_REASON, MXCryptoError.NO_MORE_ALGORITHM_REASON)
|
val reason = String.format(MXCryptoError.UNABLE_TO_ENCRYPT_REASON, MXCryptoError.NO_MORE_ALGORITHM_REASON)
|
||||||
Timber.tag(loggerTag.value).e("prepareToEncrypt() : $reason")
|
Timber.tag(loggerTag.value).e("prepareToEncrypt() : $reason")
|
||||||
callback.onFailure(IllegalArgumentException("Missing algorithm"))
|
throw IllegalArgumentException("Missing algorithm")
|
||||||
return@launch
|
|
||||||
}
|
}
|
||||||
|
try {
|
||||||
runCatching {
|
|
||||||
preshareRoomKey(roomId, userIds)
|
preshareRoomKey(roomId, userIds)
|
||||||
}.fold(
|
}catch (failure: Throwable){
|
||||||
{ callback.onSuccess(Unit) },
|
Timber.tag(loggerTag.value).e("prepareToEncrypt() : Failed to PreshareRoomKey")
|
||||||
{
|
|
||||||
Timber.tag(loggerTag.value).e(it, "prepareToEncrypt() failed.")
|
|
||||||
callback.onFailure(it)
|
|
||||||
}
|
}
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,11 +22,9 @@ import org.matrix.android.sdk.api.session.events.model.toContent
|
|||||||
import org.matrix.android.sdk.api.session.room.send.SendState
|
import org.matrix.android.sdk.api.session.room.send.SendState
|
||||||
import org.matrix.android.sdk.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM
|
import org.matrix.android.sdk.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM
|
||||||
import org.matrix.android.sdk.internal.crypto.MXEventDecryptionResult
|
import org.matrix.android.sdk.internal.crypto.MXEventDecryptionResult
|
||||||
import org.matrix.android.sdk.internal.crypto.model.MXEncryptEventContentResult
|
|
||||||
import org.matrix.android.sdk.internal.database.mapper.ContentMapper
|
import org.matrix.android.sdk.internal.database.mapper.ContentMapper
|
||||||
import org.matrix.android.sdk.internal.session.room.send.LocalEchoRepository
|
import org.matrix.android.sdk.internal.session.room.send.LocalEchoRepository
|
||||||
import org.matrix.android.sdk.internal.task.Task
|
import org.matrix.android.sdk.internal.task.Task
|
||||||
import org.matrix.android.sdk.internal.util.awaitCallback
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
internal interface EncryptEventTask : Task<EncryptEventTask.Params, Event> {
|
internal interface EncryptEventTask : Task<EncryptEventTask.Params, Event> {
|
||||||
@ -56,11 +54,9 @@ internal class DefaultEncryptEventTask @Inject constructor(
|
|||||||
localMutableContent.remove(it)
|
localMutableContent.remove(it)
|
||||||
}
|
}
|
||||||
|
|
||||||
// try {
|
|
||||||
// let it throws
|
// let it throws
|
||||||
awaitCallback<MXEncryptEventContentResult> {
|
val result = cryptoService.encryptEventContent(localMutableContent, localEvent.type, params.roomId)
|
||||||
cryptoService.encryptEventContent(localMutableContent, localEvent.type, params.roomId, it)
|
|
||||||
}.let { result ->
|
|
||||||
val modifiedContent = HashMap(result.eventContent)
|
val modifiedContent = HashMap(result.eventContent)
|
||||||
params.keepKeys?.forEach { toKeep ->
|
params.keepKeys?.forEach { toKeep ->
|
||||||
localEvent.content?.get(toKeep)?.let {
|
localEvent.content?.get(toKeep)?.let {
|
||||||
@ -98,5 +94,4 @@ internal class DefaultEncryptEventTask @Inject constructor(
|
|||||||
content = safeResult.eventContent
|
content = safeResult.eventContent
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -49,7 +49,6 @@ import org.matrix.android.sdk.internal.session.room.state.SendStateTask
|
|||||||
import org.matrix.android.sdk.internal.session.room.summary.RoomSummaryDataSource
|
import org.matrix.android.sdk.internal.session.room.summary.RoomSummaryDataSource
|
||||||
import org.matrix.android.sdk.internal.session.search.SearchTask
|
import org.matrix.android.sdk.internal.session.search.SearchTask
|
||||||
import org.matrix.android.sdk.internal.session.space.DefaultSpace
|
import org.matrix.android.sdk.internal.session.space.DefaultSpace
|
||||||
import org.matrix.android.sdk.internal.util.awaitCallback
|
|
||||||
import java.security.InvalidParameterException
|
import java.security.InvalidParameterException
|
||||||
|
|
||||||
internal class DefaultRoom(override val roomId: String,
|
internal class DefaultRoom(override val roomId: String,
|
||||||
@ -117,9 +116,7 @@ internal class DefaultRoom(override val roomId: String,
|
|||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun prepareToEncrypt() {
|
override suspend fun prepareToEncrypt() {
|
||||||
awaitCallback<Unit> {
|
cryptoService.prepareToEncrypt(roomId)
|
||||||
cryptoService.prepareToEncrypt(roomId, it)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun enableEncryption(algorithm: String, force: Boolean) {
|
override suspend fun enableEncryption(algorithm: String, force: Boolean) {
|
||||||
|
@ -16,8 +16,6 @@
|
|||||||
package im.vector.app.features.crypto.verification
|
package im.vector.app.features.crypto.verification
|
||||||
|
|
||||||
import com.airbnb.mvrx.Async
|
import com.airbnb.mvrx.Async
|
||||||
import com.airbnb.mvrx.Fail
|
|
||||||
import com.airbnb.mvrx.Loading
|
|
||||||
import com.airbnb.mvrx.MavericksState
|
import com.airbnb.mvrx.MavericksState
|
||||||
import com.airbnb.mvrx.MavericksViewModelFactory
|
import com.airbnb.mvrx.MavericksViewModelFactory
|
||||||
import com.airbnb.mvrx.Success
|
import com.airbnb.mvrx.Success
|
||||||
@ -358,17 +356,11 @@ class VerificationBottomSheetViewModel @AssistedInject constructor(
|
|||||||
|
|
||||||
private fun handleRequestVerificationByDM(roomId: String?, otherUserId: String) {
|
private fun handleRequestVerificationByDM(roomId: String?, otherUserId: String) {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
if (roomId == null) {
|
|
||||||
val localId = LocalEcho.createLocalEchoId()
|
val localId = LocalEcho.createLocalEchoId()
|
||||||
setState {
|
val dmRoomId = roomId ?: session.createDirectRoom(otherUserId)
|
||||||
copy(
|
setState { copy(pendingLocalId = localId, roomId = dmRoomId) }
|
||||||
pendingLocalId = localId,
|
suspend {
|
||||||
pendingRequest = Loading()
|
session
|
||||||
)
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
val dmRoomId = session.createDirectRoom(otherUserId)
|
|
||||||
val pendingRequest = session
|
|
||||||
.cryptoService()
|
.cryptoService()
|
||||||
.verificationService()
|
.verificationService()
|
||||||
.requestKeyVerificationInDMs(
|
.requestKeyVerificationInDMs(
|
||||||
@ -377,25 +369,8 @@ class VerificationBottomSheetViewModel @AssistedInject constructor(
|
|||||||
dmRoomId,
|
dmRoomId,
|
||||||
localId
|
localId
|
||||||
)
|
)
|
||||||
setState {
|
}.execute {
|
||||||
copy(
|
copy(pendingRequest = it, roomId = dmRoomId)
|
||||||
roomId = dmRoomId,
|
|
||||||
pendingRequest = Success(pendingRequest)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
} catch (failure: Throwable) {
|
|
||||||
setState {
|
|
||||||
copy(pendingRequest = Fail(failure))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
val pendingRequest = session
|
|
||||||
.cryptoService()
|
|
||||||
.verificationService()
|
|
||||||
.requestKeyVerificationInDMs(supportedVerificationMethodsProvider.provide(), otherUserId, roomId)
|
|
||||||
setState {
|
|
||||||
copy(pendingRequest = Success(pendingRequest))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user