Merge pull request #367 from Dominaezzz/kotlinify-3

Some more kotlinification.
This commit is contained in:
Benoit Marty 2019-07-17 14:38:16 +02:00 committed by GitHub
commit 173452d38c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 37 additions and 54 deletions

View File

@ -21,7 +21,6 @@ package im.vector.matrix.android.internal.crypto
import android.content.Context import android.content.Context
import android.os.Handler import android.os.Handler
import android.os.Looper import android.os.Looper
import android.text.TextUtils
import arrow.core.Try import arrow.core.Try
import com.squareup.moshi.Types import com.squareup.moshi.Types
import com.zhuinden.monarchy.Monarchy import com.zhuinden.monarchy.Monarchy
@ -80,10 +79,9 @@ import im.vector.matrix.android.internal.util.fetchCopied
import kotlinx.coroutines.* import kotlinx.coroutines.*
import org.matrix.olm.OlmManager import org.matrix.olm.OlmManager
import timber.log.Timber import timber.log.Timber
import java.util.*
import java.util.concurrent.atomic.AtomicBoolean import java.util.concurrent.atomic.AtomicBoolean
import javax.inject.Inject import javax.inject.Inject
import kotlin.coroutines.EmptyCoroutineContext import kotlin.math.max


/** /**
* A `CryptoService` class instance manages the end-to-end crypto for a session. * A `CryptoService` class instance manages the end-to-end crypto for a session.
@ -248,7 +246,7 @@ internal class CryptoManager @Inject constructor(
return return
} }
isStarting.set(true) isStarting.set(true)
CoroutineScope(coroutineDispatchers.crypto).launch { GlobalScope.launch(coroutineDispatchers.crypto) {
internalStart(isInitialSync) internalStart(isInitialSync)
} }
} }
@ -315,7 +313,7 @@ internal class CryptoManager @Inject constructor(
* @param syncResponse the syncResponse * @param syncResponse the syncResponse
*/ */
fun onSyncCompleted(syncResponse: SyncResponse) { fun onSyncCompleted(syncResponse: SyncResponse) {
CoroutineScope(coroutineDispatchers.crypto).launch { GlobalScope.launch(coroutineDispatchers.crypto) {
if (syncResponse.deviceLists != null) { if (syncResponse.deviceLists != null) {
deviceListManager.handleDeviceListsChanges(syncResponse.deviceLists.changed, syncResponse.deviceLists.left) deviceListManager.handleDeviceListsChanges(syncResponse.deviceLists.changed, syncResponse.deviceLists.left)
} }
@ -340,7 +338,7 @@ internal class CryptoManager @Inject constructor(
* @return the device info, or null if not found / unsupported algorithm / crypto released * @return the device info, or null if not found / unsupported algorithm / crypto released
*/ */
override fun deviceWithIdentityKey(senderKey: String, algorithm: String): MXDeviceInfo? { override fun deviceWithIdentityKey(senderKey: String, algorithm: String): MXDeviceInfo? {
return if (!TextUtils.equals(algorithm, MXCRYPTO_ALGORITHM_MEGOLM) && !TextUtils.equals(algorithm, MXCRYPTO_ALGORITHM_OLM)) { return if (algorithm != MXCRYPTO_ALGORITHM_MEGOLM && algorithm != MXCRYPTO_ALGORITHM_OLM) {
// We only deal in olm keys // We only deal in olm keys
null null
} else cryptoStore.deviceWithIdentityKey(senderKey) } else cryptoStore.deviceWithIdentityKey(senderKey)
@ -353,8 +351,8 @@ internal class CryptoManager @Inject constructor(
* @param deviceId the device id * @param deviceId the device id
*/ */
override fun getDeviceInfo(userId: String, deviceId: String?): MXDeviceInfo? { override fun getDeviceInfo(userId: String, deviceId: String?): MXDeviceInfo? {
return if (!TextUtils.isEmpty(userId) && !TextUtils.isEmpty(deviceId)) { return if (userId.isNotEmpty() && !deviceId.isNullOrEmpty()) {
cryptoStore.getUserDevice(deviceId!!, userId) cryptoStore.getUserDevice(deviceId, userId)
} else { } else {
null null
} }
@ -439,7 +437,7 @@ internal class CryptoManager @Inject constructor(
// (for now at least. Maybe we should alert the user somehow?) // (for now at least. Maybe we should alert the user somehow?)
val existingAlgorithm = cryptoStore.getRoomAlgorithm(roomId) val existingAlgorithm = cryptoStore.getRoomAlgorithm(roomId)


if (!TextUtils.isEmpty(existingAlgorithm) && !TextUtils.equals(existingAlgorithm, algorithm)) { if (!existingAlgorithm.isNullOrEmpty() && existingAlgorithm != algorithm) {
Timber.e("## setEncryptionInRoom() : Ignoring m.room.encryption event which requests a change of config in $roomId") Timber.e("## setEncryptionInRoom() : Ignoring m.room.encryption event which requests a change of config in $roomId")
return false return false
} }
@ -535,7 +533,7 @@ internal class CryptoManager @Inject constructor(
eventType: String, eventType: String,
roomId: String, roomId: String,
callback: MatrixCallback<MXEncryptEventContentResult>) { callback: MatrixCallback<MXEncryptEventContentResult>) {
CoroutineScope(coroutineDispatchers.crypto).launch { GlobalScope.launch(coroutineDispatchers.crypto) {
if (!isStarted()) { if (!isStarted()) {
Timber.v("## encryptEventContent() : wait after e2e init") Timber.v("## encryptEventContent() : wait after e2e init")
internalStart(false) internalStart(false)
@ -601,7 +599,7 @@ internal class CryptoManager @Inject constructor(
* @param callback the callback to return data or null * @param callback the callback to return data or null
*/ */
override fun decryptEventAsync(event: Event, timeline: String, callback: MatrixCallback<MXEventDecryptionResult>) { override fun decryptEventAsync(event: Event, timeline: String, callback: MatrixCallback<MXEventDecryptionResult>) {
GlobalScope.launch(EmptyCoroutineContext) { GlobalScope.launch {
val result = withContext(coroutineDispatchers.crypto) { val result = withContext(coroutineDispatchers.crypto) {
internalDecryptEvent(event, timeline) internalDecryptEvent(event, timeline)
} }
@ -649,7 +647,7 @@ internal class CryptoManager @Inject constructor(
* @param event the event * @param event the event
*/ */
fun onToDeviceEvent(event: Event) { fun onToDeviceEvent(event: Event) {
CoroutineScope(coroutineDispatchers.crypto).launch { GlobalScope.launch(coroutineDispatchers.crypto) {
when (event.getClearType()) { when (event.getClearType()) {
EventType.ROOM_KEY, EventType.FORWARDED_ROOM_KEY -> { EventType.ROOM_KEY, EventType.FORWARDED_ROOM_KEY -> {
onRoomKeyEvent(event) onRoomKeyEvent(event)
@ -671,7 +669,7 @@ internal class CryptoManager @Inject constructor(
*/ */
private fun onRoomKeyEvent(event: Event) { private fun onRoomKeyEvent(event: Event) {
val roomKeyContent = event.getClearContent().toModel<RoomKeyContent>() ?: return val roomKeyContent = event.getClearContent().toModel<RoomKeyContent>() ?: return
if (TextUtils.isEmpty(roomKeyContent.roomId) || TextUtils.isEmpty(roomKeyContent.algorithm)) { if (roomKeyContent.roomId.isNullOrEmpty() || roomKeyContent.algorithm.isNullOrEmpty()) {
Timber.e("## onRoomKeyEvent() : missing fields") Timber.e("## onRoomKeyEvent() : missing fields")
return return
} }
@ -689,7 +687,7 @@ internal class CryptoManager @Inject constructor(
* @param event the encryption event. * @param event the encryption event.
*/ */
private fun onRoomEncryptionEvent(roomId: String, event: Event) { private fun onRoomEncryptionEvent(roomId: String, event: Event) {
CoroutineScope(coroutineDispatchers.crypto).launch { GlobalScope.launch(coroutineDispatchers.crypto) {
val params = LoadRoomMembersTask.Params(roomId) val params = LoadRoomMembersTask.Params(roomId)
loadRoomMembersTask loadRoomMembersTask
.execute(params) .execute(params)
@ -738,7 +736,7 @@ internal class CryptoManager @Inject constructor(
val membership = roomMember?.membership val membership = roomMember?.membership
if (membership == Membership.JOIN) { if (membership == Membership.JOIN) {
// make sure we are tracking the deviceList for this user. // make sure we are tracking the deviceList for this user.
deviceListManager.startTrackingDeviceList(Arrays.asList(userId)) deviceListManager.startTrackingDeviceList(listOf(userId))
} else if (membership == Membership.INVITE } else if (membership == Membership.INVITE
&& shouldEncryptForInvitedMembers(roomId) && shouldEncryptForInvitedMembers(roomId)
&& cryptoConfig.enableEncryptionForInvitedMembers) { && cryptoConfig.enableEncryptionForInvitedMembers) {
@ -747,7 +745,7 @@ internal class CryptoManager @Inject constructor(
// know what other servers are in the room at the time they've been invited. // know what other servers are in the room at the time they've been invited.
// They therefore will not send device updates if a user logs in whilst // They therefore will not send device updates if a user logs in whilst
// their state is invite. // their state is invite.
deviceListManager.startTrackingDeviceList(Arrays.asList(userId)) deviceListManager.startTrackingDeviceList(listOf(userId))
} }
} }
} }
@ -782,7 +780,11 @@ internal class CryptoManager @Inject constructor(
* @param callback the exported keys * @param callback the exported keys
*/ */
override fun exportRoomKeys(password: String, callback: MatrixCallback<ByteArray>) { override fun exportRoomKeys(password: String, callback: MatrixCallback<ByteArray>) {
exportRoomKeys(password, MXMegolmExportEncryption.DEFAULT_ITERATION_COUNT, callback) GlobalScope.launch(coroutineDispatchers.main) {
runCatching {
exportRoomKeys(password, MXMegolmExportEncryption.DEFAULT_ITERATION_COUNT)
}.fold(callback::onSuccess, callback::onFailure)
}
} }


/** /**
@ -792,31 +794,17 @@ internal class CryptoManager @Inject constructor(
* @param anIterationCount the encryption iteration count (0 means no encryption) * @param anIterationCount the encryption iteration count (0 means no encryption)
* @param callback the exported keys * @param callback the exported keys
*/ */
private fun exportRoomKeys(password: String, anIterationCount: Int, callback: MatrixCallback<ByteArray>) { private suspend fun exportRoomKeys(password: String, anIterationCount: Int): ByteArray {
GlobalScope.launch(coroutineDispatchers.main) { return withContext(coroutineDispatchers.crypto) {
withContext(coroutineDispatchers.crypto) { val iterationCount = max(0, anIterationCount)
Try {
val iterationCount = Math.max(0, anIterationCount)


val exportedSessions = ArrayList<MegolmSessionData>() val exportedSessions = cryptoStore.getInboundGroupSessions().mapNotNull { it.exportKeys() }

val inboundGroupSessions = cryptoStore.getInboundGroupSessions()

for (session in inboundGroupSessions) {
val megolmSessionData = session.exportKeys()

if (null != megolmSessionData) {
exportedSessions.add(megolmSessionData)
}
}


val adapter = MoshiProvider.providesMoshi() val adapter = MoshiProvider.providesMoshi()
.adapter(List::class.java) .adapter(List::class.java)


MXMegolmExportEncryption.encryptMegolmKeyFile(adapter.toJson(exportedSessions), password, iterationCount) MXMegolmExportEncryption.encryptMegolmKeyFile(adapter.toJson(exportedSessions), password, iterationCount)
} }
}.foldToCallback(callback)
}
} }


/** /**
@ -879,7 +867,7 @@ internal class CryptoManager @Inject constructor(
*/ */
fun checkUnknownDevices(userIds: List<String>, callback: MatrixCallback<Unit>) { fun checkUnknownDevices(userIds: List<String>, callback: MatrixCallback<Unit>) {
// force the refresh to ensure that the devices list is up-to-date // force the refresh to ensure that the devices list is up-to-date
CoroutineScope(coroutineDispatchers.crypto).launch { GlobalScope.launch(coroutineDispatchers.crypto) {
deviceListManager deviceListManager
.downloadKeys(userIds, true) .downloadKeys(userIds, true)
.fold( .fold(
@ -944,7 +932,7 @@ internal class CryptoManager @Inject constructor(
val roomIds = cryptoStore.getRoomsListBlacklistUnverifiedDevices().toMutableList() val roomIds = cryptoStore.getRoomsListBlacklistUnverifiedDevices().toMutableList()


if (add) { if (add) {
if (!roomIds.contains(roomId)) { if (roomId !in roomIds) {
roomIds.add(roomId) roomIds.add(roomId)
} }
} else { } else {
@ -1033,8 +1021,7 @@ internal class CryptoManager @Inject constructor(
val unknownDevices = MXUsersDevicesMap<MXDeviceInfo>() val unknownDevices = MXUsersDevicesMap<MXDeviceInfo>()
val userIds = devicesInRoom.userIds val userIds = devicesInRoom.userIds
for (userId in userIds) { for (userId in userIds) {
val deviceIds = devicesInRoom.getUserDeviceIds(userId) devicesInRoom.getUserDeviceIds(userId)?.forEach { deviceId ->
deviceIds?.forEach { deviceId ->
devicesInRoom.getObject(userId, deviceId) devicesInRoom.getObject(userId, deviceId)
?.takeIf { it.isUnknown } ?.takeIf { it.isUnknown }
?.let { ?.let {
@ -1047,7 +1034,7 @@ internal class CryptoManager @Inject constructor(
} }


override fun downloadKeys(userIds: List<String>, forceDownload: Boolean, callback: MatrixCallback<MXUsersDevicesMap<MXDeviceInfo>>) { override fun downloadKeys(userIds: List<String>, forceDownload: Boolean, callback: MatrixCallback<MXUsersDevicesMap<MXDeviceInfo>>) {
CoroutineScope(coroutineDispatchers.crypto).launch { GlobalScope.launch(coroutineDispatchers.crypto) {
deviceListManager deviceListManager
.downloadKeys(userIds, forceDownload) .downloadKeys(userIds, forceDownload)
.foldToCallback(callback) .foldToCallback(callback)

View File

@ -29,7 +29,6 @@ import im.vector.matrix.android.internal.crypto.actions.EnsureOlmSessionsForDevi
import im.vector.matrix.android.internal.crypto.actions.MessageEncrypter import im.vector.matrix.android.internal.crypto.actions.MessageEncrypter
import im.vector.matrix.android.internal.crypto.algorithms.IMXDecrypting import im.vector.matrix.android.internal.crypto.algorithms.IMXDecrypting
import im.vector.matrix.android.internal.crypto.keysbackup.KeysBackup import im.vector.matrix.android.internal.crypto.keysbackup.KeysBackup
import im.vector.matrix.android.internal.crypto.model.MXDeviceInfo
import im.vector.matrix.android.internal.crypto.model.MXUsersDevicesMap import im.vector.matrix.android.internal.crypto.model.MXUsersDevicesMap
import im.vector.matrix.android.internal.crypto.model.event.EncryptedEventContent import im.vector.matrix.android.internal.crypto.model.event.EncryptedEventContent
import im.vector.matrix.android.internal.crypto.model.event.RoomKeyContent import im.vector.matrix.android.internal.crypto.model.event.RoomKeyContent
@ -38,10 +37,9 @@ import im.vector.matrix.android.internal.crypto.model.rest.RoomKeyRequestBody
import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore
import im.vector.matrix.android.internal.crypto.tasks.SendToDeviceTask import im.vector.matrix.android.internal.crypto.tasks.SendToDeviceTask
import im.vector.matrix.android.internal.util.MatrixCoroutineDispatchers import im.vector.matrix.android.internal.util.MatrixCoroutineDispatchers
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import timber.log.Timber import timber.log.Timber
import java.util.*
import kotlin.collections.HashMap import kotlin.collections.HashMap


internal class MXMegolmDecryption(private val credentials: Credentials, internal class MXMegolmDecryption(private val credentials: Credentials,
@ -312,7 +310,7 @@ internal class MXMegolmDecryption(private val credentials: Credentials,
return return
} }
val userId = request.userId ?: return val userId = request.userId ?: return
CoroutineScope(coroutineDispatchers.crypto).launch { GlobalScope.launch(coroutineDispatchers.crypto) {
deviceListManager deviceListManager
.downloadKeys(listOf(userId), false) .downloadKeys(listOf(userId), false)
.flatMap { .flatMap {
@ -321,8 +319,7 @@ internal class MXMegolmDecryption(private val credentials: Credentials,
if (deviceInfo == null) { if (deviceInfo == null) {
throw RuntimeException() throw RuntimeException()
} else { } else {
val devicesByUser = HashMap<String, List<MXDeviceInfo>>() val devicesByUser = mapOf(userId to listOf(deviceInfo))
devicesByUser[userId] = ArrayList(Arrays.asList(deviceInfo))
ensureOlmSessionsForDevicesAction ensureOlmSessionsForDevicesAction
.handle(devicesByUser) .handle(devicesByUser)
.flatMap { .flatMap {
@ -336,8 +333,7 @@ internal class MXMegolmDecryption(private val credentials: Credentials,
Timber.v("## shareKeysWithDevice() : sharing keys for session" + Timber.v("## shareKeysWithDevice() : sharing keys for session" +
" ${body?.senderKey}|${body?.sessionId} with device $userId:$deviceId") " ${body?.senderKey}|${body?.sessionId} with device $userId:$deviceId")


val payloadJson = HashMap<String, Any>() val payloadJson = mutableMapOf<String, Any>("type" to EventType.FORWARDED_ROOM_KEY)
payloadJson["type"] = EventType.FORWARDED_ROOM_KEY


olmDevice.getInboundGroupSession(body?.sessionId, body?.senderKey, body?.roomId) olmDevice.getInboundGroupSession(body?.sessionId, body?.senderKey, body?.roomId)
.fold( .fold(
@ -350,7 +346,7 @@ internal class MXMegolmDecryption(private val credentials: Credentials,
} }
) )


val encodedPayload = messageEncrypter.encryptMessage(payloadJson, Arrays.asList(deviceInfo)) val encodedPayload = messageEncrypter.encryptMessage(payloadJson, listOf(deviceInfo))
val sendToDeviceMap = MXUsersDevicesMap<Any>() val sendToDeviceMap = MXUsersDevicesMap<Any>()
sendToDeviceMap.setObject(userId, deviceId, encodedPayload) sendToDeviceMap.setObject(userId, deviceId, encodedPayload)
Timber.v("## shareKeysWithDevice() : sending to $userId:$deviceId") Timber.v("## shareKeysWithDevice() : sending to $userId:$deviceId")

View File

@ -40,7 +40,7 @@ import im.vector.matrix.android.internal.session.SessionScope
import im.vector.matrix.android.internal.task.TaskExecutor import im.vector.matrix.android.internal.task.TaskExecutor
import im.vector.matrix.android.internal.task.configureWith import im.vector.matrix.android.internal.task.configureWith
import im.vector.matrix.android.internal.util.MatrixCoroutineDispatchers import im.vector.matrix.android.internal.util.MatrixCoroutineDispatchers
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import timber.log.Timber import timber.log.Timber
import java.util.* import java.util.*
@ -71,7 +71,7 @@ internal class DefaultSasVerificationService @Inject constructor(private val cre


// Event received from the sync // Event received from the sync
fun onToDeviceEvent(event: Event) { fun onToDeviceEvent(event: Event) {
CoroutineScope(coroutineDispatchers.crypto).launch { GlobalScope.launch(coroutineDispatchers.crypto) {
when (event.getClearType()) { when (event.getClearType()) {
EventType.KEY_VERIFICATION_START -> { EventType.KEY_VERIFICATION_START -> {
onStartRequestReceived(event) onStartRequestReceived(event)