Merge pull request #630 from vector-im/feature/crypto_lock
Fix dead lock on crypto
This commit is contained in:
commit
7890e83204
|
@ -134,7 +134,7 @@ data class Event(
|
|||
}
|
||||
|
||||
fun toContentStringWithIndent(): String {
|
||||
val contentMap = toContent()?.toMutableMap() ?: HashMap()
|
||||
val contentMap = toContent().toMutableMap()
|
||||
return JSONObject(contentMap).toString(4)
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,6 @@ package im.vector.matrix.android.internal.crypto
|
|||
import android.content.Context
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import arrow.core.Try
|
||||
import com.squareup.moshi.Types
|
||||
import com.zhuinden.monarchy.Monarchy
|
||||
import dagger.Lazy
|
||||
|
|
|
@ -38,9 +38,9 @@ internal class EnsureOlmSessionsForUsersAction @Inject constructor(private val o
|
|||
|
||||
devices.filter {
|
||||
// Don't bother setting up session to ourself
|
||||
it.identityKey() != olmDevice.deviceCurve25519Key &&
|
||||
it.identityKey() != olmDevice.deviceCurve25519Key
|
||||
// Don't bother setting up sessions with blocked users
|
||||
!it.isVerified
|
||||
&& !it.isVerified
|
||||
}
|
||||
}
|
||||
return ensureOlmSessionsForDevicesAction.handle(devicesByUser)
|
||||
|
|
|
@ -244,13 +244,6 @@ internal class MXMegolmDecryption(private val userId: String,
|
|||
keysClaimed = event.getKeysClaimed().toMutableMap()
|
||||
}
|
||||
|
||||
if (roomKeyContent.sessionId == null
|
||||
|| roomKeyContent.sessionKey == null
|
||||
|| roomKeyContent.roomId == null) {
|
||||
Timber.e("## invalid roomKeyContent")
|
||||
return
|
||||
}
|
||||
|
||||
val added = olmDevice.addInboundGroupSession(roomKeyContent.sessionId,
|
||||
roomKeyContent.sessionKey,
|
||||
roomKeyContent.roomId,
|
||||
|
|
|
@ -66,7 +66,7 @@ internal class MXOlmEncryption(
|
|||
)
|
||||
|
||||
messageEncrypter.encryptMessage(messageMap, deviceInfos)
|
||||
return messageMap.toContent()!!
|
||||
return messageMap.toContent()
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -21,7 +21,6 @@ import android.os.Looper
|
|||
import androidx.annotation.UiThread
|
||||
import androidx.annotation.VisibleForTesting
|
||||
import androidx.annotation.WorkerThread
|
||||
import arrow.core.Try
|
||||
import im.vector.matrix.android.api.MatrixCallback
|
||||
import im.vector.matrix.android.api.auth.data.Credentials
|
||||
import im.vector.matrix.android.api.failure.Failure
|
||||
|
@ -70,9 +69,6 @@ import org.matrix.olm.OlmPkMessage
|
|||
import timber.log.Timber
|
||||
import java.security.InvalidParameterException
|
||||
import javax.inject.Inject
|
||||
import kotlin.coroutines.resume
|
||||
import kotlin.coroutines.resumeWithException
|
||||
import kotlin.coroutines.suspendCoroutine
|
||||
import kotlin.random.Random
|
||||
|
||||
/**
|
||||
|
|
|
@ -38,23 +38,24 @@ internal class TimelineEventDecryptor(
|
|||
private val newSessionListener = object : NewSessionListener {
|
||||
override fun onNewSession(roomId: String?, senderKey: String, sessionId: String) {
|
||||
synchronized(unknownSessionsFailure) {
|
||||
val toDecryptAgain = ArrayList<String>()
|
||||
val eventIds = unknownSessionsFailure[sessionId]
|
||||
if (eventIds != null) toDecryptAgain.addAll(eventIds)
|
||||
if (toDecryptAgain.isNotEmpty()) {
|
||||
eventIds?.clear()
|
||||
toDecryptAgain.forEach {
|
||||
requestDecryption(it)
|
||||
}
|
||||
}
|
||||
unknownSessionsFailure[sessionId]
|
||||
.orEmpty()
|
||||
.toList()
|
||||
.also {
|
||||
unknownSessionsFailure[sessionId]?.clear()
|
||||
}
|
||||
}.forEach {
|
||||
requestDecryption(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private var executor: ExecutorService? = null
|
||||
|
||||
private val existingRequests = HashSet<String>()
|
||||
private val unknownSessionsFailure = HashMap<String, MutableList<String>>()
|
||||
// Set of eventIds which are currently decrypting
|
||||
private val existingRequests = mutableSetOf<String>()
|
||||
// sessionId -> list of eventIds
|
||||
private val unknownSessionsFailure = mutableMapOf<String, MutableList<String>>()
|
||||
|
||||
fun start() {
|
||||
executor = Executors.newSingleThreadExecutor()
|
||||
|
@ -65,11 +66,23 @@ internal class TimelineEventDecryptor(
|
|||
cryptoService.removeSessionListener(newSessionListener)
|
||||
executor?.shutdownNow()
|
||||
executor = null
|
||||
unknownSessionsFailure.clear()
|
||||
existingRequests.clear()
|
||||
synchronized(unknownSessionsFailure) {
|
||||
unknownSessionsFailure.clear()
|
||||
}
|
||||
synchronized(existingRequests) {
|
||||
existingRequests.clear()
|
||||
}
|
||||
}
|
||||
|
||||
fun requestDecryption(eventId: String) {
|
||||
synchronized(unknownSessionsFailure) {
|
||||
for (eventIds in unknownSessionsFailure.values) {
|
||||
if (eventId in eventIds) {
|
||||
Timber.d("Skip Decryption request for event $eventId, unknown session")
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
synchronized(existingRequests) {
|
||||
if (eventId in existingRequests) {
|
||||
Timber.d("Skip Decryption request for event $eventId, already requested")
|
||||
|
@ -77,14 +90,6 @@ internal class TimelineEventDecryptor(
|
|||
}
|
||||
existingRequests.add(eventId)
|
||||
}
|
||||
synchronized(unknownSessionsFailure) {
|
||||
for (it in unknownSessionsFailure.values) {
|
||||
if (eventId in it) {
|
||||
Timber.d("Skip Decryption request for event $eventId, unknown session")
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
executor?.execute {
|
||||
Realm.getInstance(realmConfiguration).use { realm ->
|
||||
processDecryptRequest(eventId, realm)
|
||||
|
@ -106,7 +111,7 @@ internal class TimelineEventDecryptor(
|
|||
eventEntity.setDecryptionResult(result)
|
||||
}
|
||||
} catch (e: MXCryptoError) {
|
||||
Timber.v("Failed to decrypt event $eventId $e")
|
||||
Timber.v(e, "Failed to decrypt event $eventId")
|
||||
if (e is MXCryptoError.Base && e.errorType == MXCryptoError.ErrorType.UNKNOWN_INBOUND_SESSION_ID) {
|
||||
// Keep track of unknown sessions to automatically try to decrypt on new session
|
||||
realm.executeTransaction {
|
||||
|
|
|
@ -213,10 +213,10 @@ class VectorFirebaseMessagingService : FirebaseMessagingService() {
|
|||
}
|
||||
} else {
|
||||
if (notifiableEvent is NotifiableMessageEvent) {
|
||||
if (notifiableEvent.senderName.isEmpty()) {
|
||||
if (notifiableEvent.senderName.isNullOrEmpty()) {
|
||||
notifiableEvent.senderName = data["sender_display_name"] ?: data["sender"] ?: ""
|
||||
}
|
||||
if (notifiableEvent.roomName.isEmpty()) {
|
||||
if (notifiableEvent.roomName.isNullOrEmpty()) {
|
||||
notifiableEvent.roomName = findRoomNameBestEffort(data, session) ?: ""
|
||||
}
|
||||
}
|
||||
|
|
|
@ -126,7 +126,7 @@ fun getFileExtension(fileUri: String): String? {
|
|||
* Size
|
||||
* ========================================================================================== */
|
||||
|
||||
fun getSizeOfFiles(context: Context, root: File): Int {
|
||||
fun getSizeOfFiles(root: File): Int {
|
||||
return root.walkTopDown()
|
||||
.onEnter {
|
||||
Timber.v("Get size of ${it.absolutePath}")
|
||||
|
|
|
@ -185,8 +185,7 @@ class VectorSettingsGeneralFragment : VectorSettingsBaseFragment() {
|
|||
|
||||
// clear medias cache
|
||||
findPreference<VectorPreference>(VectorPreferences.SETTINGS_CLEAR_MEDIA_CACHE_PREFERENCE_KEY)!!.let {
|
||||
val size = getSizeOfFiles(requireContext(),
|
||||
File(requireContext().cacheDir, DiskCache.Factory.DEFAULT_DISK_CACHE_DIR))
|
||||
val size = getSizeOfFiles(File(requireContext().cacheDir, DiskCache.Factory.DEFAULT_DISK_CACHE_DIR))
|
||||
|
||||
it.summary = TextUtils.formatFileSize(requireContext(), size.toLong())
|
||||
|
||||
|
@ -203,8 +202,7 @@ class VectorSettingsGeneralFragment : VectorSettingsBaseFragment() {
|
|||
// On BG thread
|
||||
Glide.get(requireContext()).clearDiskCache()
|
||||
|
||||
newSize = getSizeOfFiles(requireContext(),
|
||||
File(requireContext().cacheDir, DiskCache.Factory.DEFAULT_DISK_CACHE_DIR))
|
||||
newSize = getSizeOfFiles(File(requireContext().cacheDir, DiskCache.Factory.DEFAULT_DISK_CACHE_DIR))
|
||||
}
|
||||
|
||||
it.summary = TextUtils.formatFileSize(requireContext(), newSize.toLong())
|
||||
|
|
Loading…
Reference in New Issue