mirror of
https://github.com/element-hq/element-android
synced 2024-11-27 03:48:12 +03:00
Remove all async thread
This commit is contained in:
parent
c66e82c4ae
commit
de4662b9d5
12 changed files with 558 additions and 902 deletions
|
@ -43,11 +43,11 @@ interface CryptoService {
|
|||
|
||||
fun getKeysBackupService(): KeysBackupService
|
||||
|
||||
fun isRoomBlacklistUnverifiedDevices(roomId: String, callback: MatrixCallback<Boolean>?)
|
||||
fun isRoomBlacklistUnverifiedDevices(roomId: String?): Boolean
|
||||
|
||||
fun setWarnOnUnknownDevices(warn: Boolean)
|
||||
|
||||
fun setDeviceVerification(verificationStatus: Int, deviceId: String, userId: String, callback: MatrixCallback<Unit>)
|
||||
fun setDeviceVerification(verificationStatus: Int, deviceId: String, userId: String)
|
||||
|
||||
fun getUserDevices(userId: String): MutableList<MXDeviceInfo>
|
||||
|
||||
|
@ -57,11 +57,11 @@ interface CryptoService {
|
|||
|
||||
fun getMyDevice(): MXDeviceInfo
|
||||
|
||||
fun getGlobalBlacklistUnverifiedDevices(callback: MatrixCallback<Boolean>?)
|
||||
fun getGlobalBlacklistUnverifiedDevices() : Boolean
|
||||
|
||||
fun setGlobalBlacklistUnverifiedDevices(block: Boolean, callback: MatrixCallback<Unit>?)
|
||||
fun setGlobalBlacklistUnverifiedDevices(block: Boolean)
|
||||
|
||||
fun setRoomUnBlacklistUnverifiedDevices(roomId: String, callback: MatrixCallback<Unit>)
|
||||
fun setRoomUnBlacklistUnverifiedDevices(roomId: String)
|
||||
|
||||
fun getDeviceTrackingStatus(userId: String): Int
|
||||
|
||||
|
@ -69,9 +69,9 @@ interface CryptoService {
|
|||
|
||||
fun exportRoomKeys(password: String, callback: MatrixCallback<ByteArray>)
|
||||
|
||||
fun setRoomBlacklistUnverifiedDevices(roomId: String, callback: MatrixCallback<Unit>)
|
||||
fun setRoomBlacklistUnverifiedDevices(roomId: String)
|
||||
|
||||
fun getDeviceInfo(userId: String, deviceId: String?, callback: MatrixCallback<MXDeviceInfo?>)
|
||||
fun getDeviceInfo(userId: String, deviceId: String?): MXDeviceInfo?
|
||||
|
||||
fun reRequestRoomKeyForEvent(event: Event)
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@ import android.os.Looper
|
|||
private const val THREAD_ENCRYPT_NAME = "Crypto_Encrypt_Thread"
|
||||
private const val THREAD_DECRYPT_NAME = "Crypto_Decrypt_Thread"
|
||||
|
||||
// TODO Remove and replace by Task
|
||||
internal object CryptoAsyncHelper {
|
||||
|
||||
private var uiHandler: Handler? = null
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -55,9 +55,6 @@ internal class DeviceListManager(private val mCryptoStore: IMXCryptoStore,
|
|||
// tells if there is a download keys request in progress
|
||||
private var mIsDownloadingKeys = false
|
||||
|
||||
// Internal listener
|
||||
private lateinit var mCryptoListener: DeviceListCryptoListener
|
||||
|
||||
/**
|
||||
* Creator
|
||||
*
|
||||
|
@ -330,13 +327,12 @@ internal class DeviceListManager(private val mCryptoStore: IMXCryptoStore,
|
|||
}
|
||||
}
|
||||
|
||||
if (!mCryptoListener.hasBeenReleased()) {
|
||||
val callback = promise.mCallback
|
||||
val callback = promise.mCallback
|
||||
|
||||
if (null != callback) {
|
||||
CryptoAsyncHelper.getUiHandler().post { callback.onSuccess(usersDevicesInfoMap) }
|
||||
}
|
||||
if (null != callback) {
|
||||
CryptoAsyncHelper.getUiHandler().post { callback.onSuccess(usersDevicesInfoMap) }
|
||||
}
|
||||
|
||||
promisesToRemove.add(promise)
|
||||
}
|
||||
}
|
||||
|
@ -703,15 +699,6 @@ internal class DeviceListManager(private val mCryptoStore: IMXCryptoStore,
|
|||
})
|
||||
}
|
||||
|
||||
fun setCryptoInternalListener(listener: DeviceListCryptoListener) {
|
||||
mCryptoListener = listener
|
||||
}
|
||||
|
||||
|
||||
interface DeviceListCryptoListener {
|
||||
fun hasBeenReleased(): Boolean
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
/**
|
||||
|
|
|
@ -16,21 +16,20 @@
|
|||
|
||||
package im.vector.matrix.android.internal.crypto
|
||||
|
||||
import android.os.Handler
|
||||
import android.text.TextUtils
|
||||
import im.vector.matrix.android.api.auth.data.Credentials
|
||||
import im.vector.matrix.android.api.session.crypto.keyshare.RoomKeysRequestListener
|
||||
import im.vector.matrix.android.api.session.events.model.Event
|
||||
import im.vector.matrix.android.api.session.events.model.toModel
|
||||
import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore
|
||||
import im.vector.matrix.android.internal.crypto.model.rest.RoomKeyShare
|
||||
import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore
|
||||
import timber.log.Timber
|
||||
import java.util.*
|
||||
|
||||
internal class IncomingRoomKeyRequestManager(
|
||||
val mCredentials: Credentials,
|
||||
val mCryptoStore: IMXCryptoStore,
|
||||
val mRoomDecryptorProvider: RoomDecryptorProvider) {
|
||||
private val mCredentials: Credentials,
|
||||
private val mCryptoStore: IMXCryptoStore,
|
||||
private val mRoomDecryptorProvider: RoomDecryptorProvider) {
|
||||
|
||||
|
||||
// list of IncomingRoomKeyRequests/IncomingRoomKeyRequestCancellations
|
||||
|
@ -39,7 +38,7 @@ internal class IncomingRoomKeyRequestManager(
|
|||
private val mReceivedRoomKeyRequestCancellations = ArrayList<IncomingRoomKeyRequestCancellation>()
|
||||
|
||||
// the listeners
|
||||
val mRoomKeysRequestListeners: MutableSet<RoomKeysRequestListener> = HashSet<RoomKeysRequestListener>()
|
||||
val mRoomKeysRequestListeners: MutableSet<RoomKeysRequestListener> = HashSet()
|
||||
|
||||
init {
|
||||
mReceivedRoomKeyRequests.addAll(mCryptoStore.getPendingIncomingRoomKeyRequests())
|
||||
|
@ -52,27 +51,19 @@ internal class IncomingRoomKeyRequestManager(
|
|||
* @param event the announcement event.
|
||||
*/
|
||||
fun onRoomKeyRequestEvent(event: Event) {
|
||||
val roomKeyShare = event.content.toModel<RoomKeyShare>()!!
|
||||
val roomKeyShare = event.content.toModel<RoomKeyShare>()
|
||||
|
||||
if (null != roomKeyShare.action) {
|
||||
when (roomKeyShare.action) {
|
||||
RoomKeyShare.ACTION_SHARE_REQUEST -> synchronized(mReceivedRoomKeyRequests) {
|
||||
mReceivedRoomKeyRequests.add(IncomingRoomKeyRequest(event))
|
||||
}
|
||||
RoomKeyShare.ACTION_SHARE_CANCELLATION -> synchronized(mReceivedRoomKeyRequestCancellations) {
|
||||
mReceivedRoomKeyRequestCancellations.add(IncomingRoomKeyRequestCancellation(event))
|
||||
}
|
||||
else -> Timber.e("## onRoomKeyRequestEvent() : unsupported action " + roomKeyShare.action!!)
|
||||
when (roomKeyShare?.action) {
|
||||
RoomKeyShare.ACTION_SHARE_REQUEST -> synchronized(mReceivedRoomKeyRequests) {
|
||||
mReceivedRoomKeyRequests.add(IncomingRoomKeyRequest(event))
|
||||
}
|
||||
RoomKeyShare.ACTION_SHARE_CANCELLATION -> synchronized(mReceivedRoomKeyRequestCancellations) {
|
||||
mReceivedRoomKeyRequestCancellations.add(IncomingRoomKeyRequestCancellation(event))
|
||||
}
|
||||
else -> Timber.e("## onRoomKeyRequestEvent() : unsupported action " + roomKeyShare?.action)
|
||||
}
|
||||
}
|
||||
|
||||
private lateinit var encryptingThreadHandler: Handler
|
||||
|
||||
fun setEncryptingThreadHandler(encryptingThreadHandler: Handler) {
|
||||
this.encryptingThreadHandler = encryptingThreadHandler
|
||||
}
|
||||
|
||||
/**
|
||||
* Process any m.room_key_request events which were queued up during the
|
||||
* current sync.
|
||||
|
@ -129,13 +120,11 @@ internal class IncomingRoomKeyRequestManager(
|
|||
}
|
||||
|
||||
request.mShare = Runnable {
|
||||
encryptingThreadHandler.post {
|
||||
decryptor.shareKeysWithDevice(request)
|
||||
mCryptoStore.deleteIncomingRoomKeyRequest(request)
|
||||
}
|
||||
decryptor.shareKeysWithDevice(request)
|
||||
mCryptoStore.deleteIncomingRoomKeyRequest(request)
|
||||
}
|
||||
|
||||
request.mIgnore = Runnable { encryptingThreadHandler.post { mCryptoStore.deleteIncomingRoomKeyRequest(request) } }
|
||||
request.mIgnore = Runnable { mCryptoStore.deleteIncomingRoomKeyRequest(request) }
|
||||
|
||||
// if the device is verified already, share the keys
|
||||
val device = mCryptoStore.getUserDevice(deviceId!!, userId)
|
||||
|
|
|
@ -20,11 +20,11 @@ package im.vector.matrix.android.internal.crypto
|
|||
import android.os.Handler
|
||||
import im.vector.matrix.android.api.MatrixCallback
|
||||
import im.vector.matrix.android.api.session.events.model.EventType
|
||||
import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore
|
||||
import im.vector.matrix.android.internal.crypto.model.MXUsersDevicesMap
|
||||
import im.vector.matrix.android.internal.crypto.model.rest.RoomKeyRequestBody
|
||||
import im.vector.matrix.android.internal.crypto.model.rest.RoomKeyShareCancellation
|
||||
import im.vector.matrix.android.internal.crypto.model.rest.RoomKeyShareRequest
|
||||
import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore
|
||||
import im.vector.matrix.android.internal.crypto.tasks.SendToDeviceTask
|
||||
import im.vector.matrix.android.internal.task.TaskExecutor
|
||||
import im.vector.matrix.android.internal.task.configureWith
|
||||
|
@ -36,9 +36,6 @@ internal class MXOutgoingRoomKeyRequestManager(
|
|||
private val mSendToDeviceTask: SendToDeviceTask,
|
||||
private val mTaskExecutor: TaskExecutor) {
|
||||
|
||||
// working handler (should not be the UI thread)
|
||||
private lateinit var mWorkingHandler: Handler
|
||||
|
||||
// running
|
||||
var mClientRunning: Boolean = false
|
||||
|
||||
|
@ -49,10 +46,6 @@ internal class MXOutgoingRoomKeyRequestManager(
|
|||
// of mSendOutgoingRoomKeyRequestsTimer
|
||||
private var mSendOutgoingRoomKeyRequestsRunning: Boolean = false
|
||||
|
||||
fun setWorkingHandler(encryptingThreadHandler: Handler) {
|
||||
mWorkingHandler = encryptingThreadHandler
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the client is started. Sets background processes running.
|
||||
*/
|
||||
|
@ -90,14 +83,12 @@ internal class MXOutgoingRoomKeyRequestManager(
|
|||
* @param recipients recipients
|
||||
*/
|
||||
fun sendRoomKeyRequest(requestBody: RoomKeyRequestBody?, recipients: List<Map<String, String>>) {
|
||||
mWorkingHandler.post {
|
||||
val req = mCryptoStore.getOrAddOutgoingRoomKeyRequest(
|
||||
OutgoingRoomKeyRequest(requestBody, recipients, makeTxnId(), OutgoingRoomKeyRequest.RequestState.UNSENT))
|
||||
val req = mCryptoStore.getOrAddOutgoingRoomKeyRequest(
|
||||
OutgoingRoomKeyRequest(requestBody, recipients, makeTxnId(), OutgoingRoomKeyRequest.RequestState.UNSENT))
|
||||
|
||||
|
||||
if (req!!.mState === OutgoingRoomKeyRequest.RequestState.UNSENT) {
|
||||
startTimer()
|
||||
}
|
||||
if (req!!.mState === OutgoingRoomKeyRequest.RequestState.UNSENT) {
|
||||
startTimer()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -154,21 +145,19 @@ internal class MXOutgoingRoomKeyRequestManager(
|
|||
* Start the background timer to send queued requests, if the timer isn't already running.
|
||||
*/
|
||||
private fun startTimer() {
|
||||
mWorkingHandler.post(Runnable {
|
||||
if (mSendOutgoingRoomKeyRequestsRunning) {
|
||||
return
|
||||
}
|
||||
|
||||
Handler().postDelayed(Runnable {
|
||||
if (mSendOutgoingRoomKeyRequestsRunning) {
|
||||
Timber.d("## startTimer() : RoomKeyRequestSend already in progress!")
|
||||
return@Runnable
|
||||
}
|
||||
|
||||
mWorkingHandler.postDelayed(Runnable {
|
||||
if (mSendOutgoingRoomKeyRequestsRunning) {
|
||||
Timber.d("## startTimer() : RoomKeyRequestSend already in progress!")
|
||||
return@Runnable
|
||||
}
|
||||
|
||||
mSendOutgoingRoomKeyRequestsRunning = true
|
||||
sendOutgoingRoomKeyRequests()
|
||||
}, SEND_KEY_REQUESTS_DELAY_MS.toLong())
|
||||
})
|
||||
mSendOutgoingRoomKeyRequestsRunning = true
|
||||
sendOutgoingRoomKeyRequests()
|
||||
}, SEND_KEY_REQUESTS_DELAY_MS.toLong())
|
||||
}
|
||||
|
||||
// look for and send any queued requests. Runs itself recursively until
|
||||
|
@ -215,17 +204,15 @@ internal class MXOutgoingRoomKeyRequestManager(
|
|||
|
||||
sendMessageToDevices(requestMessage, request.mRecipients, request.mRequestId, object : MatrixCallback<Unit> {
|
||||
private fun onDone(state: OutgoingRoomKeyRequest.RequestState) {
|
||||
mWorkingHandler.post {
|
||||
if (request.mState !== OutgoingRoomKeyRequest.RequestState.UNSENT) {
|
||||
Timber.d("## sendOutgoingRoomKeyRequest() : Cannot update room key request from UNSENT as it was already updated to " + request.mState)
|
||||
} else {
|
||||
request.mState = state
|
||||
mCryptoStore.updateOutgoingRoomKeyRequest(request)
|
||||
}
|
||||
|
||||
mSendOutgoingRoomKeyRequestsRunning = false
|
||||
startTimer()
|
||||
if (request.mState !== OutgoingRoomKeyRequest.RequestState.UNSENT) {
|
||||
Timber.d("## sendOutgoingRoomKeyRequest() : Cannot update room key request from UNSENT as it was already updated to " + request.mState)
|
||||
} else {
|
||||
request.mState = state
|
||||
mCryptoStore.updateOutgoingRoomKeyRequest(request)
|
||||
}
|
||||
|
||||
mSendOutgoingRoomKeyRequestsRunning = false
|
||||
startTimer()
|
||||
}
|
||||
|
||||
override fun onSuccess(data: Unit) {
|
||||
|
@ -256,11 +243,9 @@ internal class MXOutgoingRoomKeyRequestManager(
|
|||
|
||||
sendMessageToDevices(roomKeyShareCancellation, request.mRecipients, request.mCancellationTxnId, object : MatrixCallback<Unit> {
|
||||
private fun onDone() {
|
||||
mWorkingHandler.post {
|
||||
mCryptoStore.deleteOutgoingRoomKeyRequest(request.mRequestId)
|
||||
mSendOutgoingRoomKeyRequestsRunning = false
|
||||
startTimer()
|
||||
}
|
||||
mCryptoStore.deleteOutgoingRoomKeyRequest(request.mRequestId)
|
||||
mSendOutgoingRoomKeyRequestsRunning = false
|
||||
startTimer()
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -154,10 +154,8 @@ internal class MXMegolmEncryption : IMXEncrypting {
|
|||
override fun onSuccess(devicesInRoom: MXUsersDevicesMap<MXDeviceInfo>) {
|
||||
ensureOutboundSession(devicesInRoom, object : MatrixCallback<MXOutboundSessionInfo> {
|
||||
override fun onSuccess(data: MXOutboundSessionInfo) {
|
||||
mCrypto!!.encryptingThreadHandler.post {
|
||||
Timber.d("## encryptEventContent () processPendingEncryptions after " + (System.currentTimeMillis() - t0) + "ms")
|
||||
processPendingEncryptions(data)
|
||||
}
|
||||
Timber.d("## encryptEventContent () processPendingEncryptions after " + (System.currentTimeMillis() - t0) + "ms")
|
||||
processPendingEncryptions(data)
|
||||
}
|
||||
|
||||
override fun onFailure(failure: Throwable) {
|
||||
|
@ -178,12 +176,12 @@ internal class MXMegolmEncryption : IMXEncrypting {
|
|||
* @return the session description
|
||||
*/
|
||||
private fun prepareNewSessionInRoom(): MXOutboundSessionInfo {
|
||||
val sessionId = olmDevice!!.createOutboundGroupSession()
|
||||
val sessionId = olmDevice.createOutboundGroupSession()
|
||||
|
||||
val keysClaimedMap = HashMap<String, String>()
|
||||
keysClaimedMap["ed25519"] = olmDevice.deviceEd25519Key!!
|
||||
|
||||
olmDevice.addInboundGroupSession(sessionId!!, olmDevice.getSessionKey(sessionId)!!, mRoomId!!, olmDevice.deviceCurve25519Key!!,
|
||||
olmDevice.addInboundGroupSession(sessionId!!, olmDevice.getSessionKey(sessionId)!!, mRoomId, olmDevice.deviceCurve25519Key!!,
|
||||
ArrayList(), keysClaimedMap, false)
|
||||
|
||||
mKeysBackup.maybeBackupKeys()
|
||||
|
@ -296,12 +294,10 @@ internal class MXMegolmEncryption : IMXEncrypting {
|
|||
Timber.d("## shareKey() ; userId $userIds")
|
||||
shareUserDevicesKey(session, subMap, object : MatrixCallback<Unit> {
|
||||
override fun onSuccess(data: Unit) {
|
||||
mCrypto!!.encryptingThreadHandler.post {
|
||||
for (userId in userIds) {
|
||||
devicesByUsers.remove(userId)
|
||||
}
|
||||
shareKey(session, devicesByUsers, callback)
|
||||
for (userId in userIds) {
|
||||
devicesByUsers.remove(userId)
|
||||
}
|
||||
shareKey(session, devicesByUsers, callback)
|
||||
}
|
||||
|
||||
override fun onFailure(failure: Throwable) {
|
||||
|
@ -326,7 +322,7 @@ internal class MXMegolmEncryption : IMXEncrypting {
|
|||
|
||||
val submap = HashMap<String, Any>()
|
||||
submap["algorithm"] = MXCRYPTO_ALGORITHM_MEGOLM
|
||||
submap["room_id"] = mRoomId!!
|
||||
submap["room_id"] = mRoomId
|
||||
submap["session_id"] = session.mSessionId
|
||||
submap["session_key"] = sessionKey!!
|
||||
submap["chain_index"] = chainIndex
|
||||
|
@ -338,88 +334,84 @@ internal class MXMegolmEncryption : IMXEncrypting {
|
|||
val t0 = System.currentTimeMillis()
|
||||
Timber.d("## shareUserDevicesKey() : starts")
|
||||
|
||||
mCrypto!!.ensureOlmSessionsForDevices(devicesByUser, object : MatrixCallback<MXUsersDevicesMap<MXOlmSessionResult>> {
|
||||
override fun onSuccess(results: MXUsersDevicesMap<MXOlmSessionResult>) {
|
||||
mCrypto!!.encryptingThreadHandler.post {
|
||||
Timber.d("## shareUserDevicesKey() : ensureOlmSessionsForDevices succeeds after "
|
||||
+ (System.currentTimeMillis() - t0) + " ms")
|
||||
val contentMap = MXUsersDevicesMap<Any>()
|
||||
mCrypto.ensureOlmSessionsForDevices(devicesByUser, object : MatrixCallback<MXUsersDevicesMap<MXOlmSessionResult>> {
|
||||
override fun onSuccess(data: MXUsersDevicesMap<MXOlmSessionResult>) {
|
||||
Timber.d("## shareUserDevicesKey() : ensureOlmSessionsForDevices succeeds after "
|
||||
+ (System.currentTimeMillis() - t0) + " ms")
|
||||
val contentMap = MXUsersDevicesMap<Any>()
|
||||
|
||||
var haveTargets = false
|
||||
val userIds = results.userIds
|
||||
var haveTargets = false
|
||||
val userIds = data.userIds
|
||||
|
||||
for (userId in userIds) {
|
||||
val devicesToShareWith = devicesByUser[userId]
|
||||
for (userId in userIds) {
|
||||
val devicesToShareWith = devicesByUser[userId]
|
||||
|
||||
for ((deviceID) in devicesToShareWith!!) {
|
||||
for ((deviceID) in devicesToShareWith!!) {
|
||||
|
||||
val sessionResult = results.getObject(deviceID, userId)
|
||||
val sessionResult = data.getObject(deviceID, userId)
|
||||
|
||||
if (null == sessionResult || null == sessionResult.mSessionId) {
|
||||
// no session with this device, probably because there
|
||||
// were no one-time keys.
|
||||
//
|
||||
// we could send them a to_device message anyway, as a
|
||||
// signal that they have missed out on the key sharing
|
||||
// message because of the lack of keys, but there's not
|
||||
// much point in that really; it will mostly serve to clog
|
||||
// up to_device inboxes.
|
||||
//
|
||||
// ensureOlmSessionsForUsers has already done the logging,
|
||||
// so just skip it.
|
||||
continue
|
||||
}
|
||||
|
||||
Timber.d("## shareUserDevicesKey() : Sharing keys with device $userId:$deviceID")
|
||||
//noinspection ArraysAsListWithZeroOrOneArgument,ArraysAsListWithZeroOrOneArgument
|
||||
contentMap.setObject(mCrypto!!.encryptMessage(payload, Arrays.asList(sessionResult.mDevice)), userId, deviceID)
|
||||
haveTargets = true
|
||||
if (null == sessionResult || null == sessionResult.mSessionId) {
|
||||
// no session with this device, probably because there
|
||||
// were no one-time keys.
|
||||
//
|
||||
// we could send them a to_device message anyway, as a
|
||||
// signal that they have missed out on the key sharing
|
||||
// message because of the lack of keys, but there's not
|
||||
// much point in that really; it will mostly serve to clog
|
||||
// up to_device inboxes.
|
||||
//
|
||||
// ensureOlmSessionsForUsers has already done the logging,
|
||||
// so just skip it.
|
||||
continue
|
||||
}
|
||||
|
||||
Timber.d("## shareUserDevicesKey() : Sharing keys with device $userId:$deviceID")
|
||||
//noinspection ArraysAsListWithZeroOrOneArgument,ArraysAsListWithZeroOrOneArgument
|
||||
contentMap.setObject(mCrypto.encryptMessage(payload, Arrays.asList(sessionResult.mDevice)), userId, deviceID)
|
||||
haveTargets = true
|
||||
}
|
||||
}
|
||||
|
||||
if (haveTargets && !mCrypto!!.hasBeenReleased()) {
|
||||
val t0 = System.currentTimeMillis()
|
||||
Timber.d("## shareUserDevicesKey() : has target")
|
||||
if (haveTargets) {
|
||||
val t0 = System.currentTimeMillis()
|
||||
Timber.d("## shareUserDevicesKey() : has target")
|
||||
|
||||
mSendToDeviceTask.configureWith(SendToDeviceTask.Params(EventType.ENCRYPTED, contentMap))
|
||||
.dispatchTo(object : MatrixCallback<Unit> {
|
||||
override fun onSuccess(data: Unit) {
|
||||
mCrypto!!.encryptingThreadHandler.post {
|
||||
Timber.d("## shareUserDevicesKey() : sendToDevice succeeds after "
|
||||
+ (System.currentTimeMillis() - t0) + " ms")
|
||||
mSendToDeviceTask.configureWith(SendToDeviceTask.Params(EventType.ENCRYPTED, contentMap))
|
||||
.dispatchTo(object : MatrixCallback<Unit> {
|
||||
override fun onSuccess(data: Unit) {
|
||||
Timber.d("## shareUserDevicesKey() : sendToDevice succeeds after "
|
||||
+ (System.currentTimeMillis() - t0) + " ms")
|
||||
|
||||
// Add the devices we have shared with to session.sharedWithDevices.
|
||||
// we deliberately iterate over devicesByUser (ie, the devices we
|
||||
// attempted to share with) rather than the contentMap (those we did
|
||||
// share with), because we don't want to try to claim a one-time-key
|
||||
// for dead devices on every message.
|
||||
for (userId in devicesByUser.keys) {
|
||||
val devicesToShareWith = devicesByUser[userId]
|
||||
// Add the devices we have shared with to session.sharedWithDevices.
|
||||
// we deliberately iterate over devicesByUser (ie, the devices we
|
||||
// attempted to share with) rather than the contentMap (those we did
|
||||
// share with), because we don't want to try to claim a one-time-key
|
||||
// for dead devices on every message.
|
||||
for (userId in devicesByUser.keys) {
|
||||
val devicesToShareWith = devicesByUser[userId]
|
||||
|
||||
for ((deviceId) in devicesToShareWith!!) {
|
||||
session.mSharedWithDevices.setObject(chainIndex, userId, deviceId)
|
||||
}
|
||||
}
|
||||
|
||||
CryptoAsyncHelper.getUiHandler().post {
|
||||
callback?.onSuccess(Unit)
|
||||
}
|
||||
for ((deviceId) in devicesToShareWith!!) {
|
||||
session.mSharedWithDevices.setObject(chainIndex, userId, deviceId)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onFailure(failure: Throwable) {
|
||||
Timber.e(failure, "## shareUserDevicesKey() : sendToDevice")
|
||||
|
||||
callback?.onFailure(failure)
|
||||
CryptoAsyncHelper.getUiHandler().post {
|
||||
callback?.onSuccess(Unit)
|
||||
}
|
||||
})
|
||||
.executeBy(mTaskExecutor)
|
||||
} else {
|
||||
Timber.d("## shareUserDevicesKey() : no need to sharekey")
|
||||
}
|
||||
|
||||
if (null != callback) {
|
||||
CryptoAsyncHelper.getUiHandler().post { callback.onSuccess(Unit) }
|
||||
}
|
||||
override fun onFailure(failure: Throwable) {
|
||||
Timber.e(failure, "## shareUserDevicesKey() : sendToDevice")
|
||||
|
||||
callback?.onFailure(failure)
|
||||
}
|
||||
})
|
||||
.executeBy(mTaskExecutor)
|
||||
} else {
|
||||
Timber.d("## shareUserDevicesKey() : no need to sharekey")
|
||||
|
||||
if (null != callback) {
|
||||
CryptoAsyncHelper.getUiHandler().post { callback.onSuccess(Unit) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -443,7 +435,7 @@ internal class MXMegolmEncryption : IMXEncrypting {
|
|||
for (queuedEncryption in queuedEncryptions) {
|
||||
val payloadJson = HashMap<String, Any>()
|
||||
|
||||
payloadJson["room_id"] = mRoomId!!
|
||||
payloadJson["room_id"] = mRoomId
|
||||
payloadJson["type"] = queuedEncryption.mEventType!!
|
||||
payloadJson["content"] = queuedEncryption.mEventContent!!
|
||||
|
||||
|
@ -487,54 +479,50 @@ internal class MXMegolmEncryption : IMXEncrypting {
|
|||
// with them, which means that they will have announced any new devices via
|
||||
// an m.new_device.
|
||||
mDeviceListManager.downloadKeys(userIds, false, object : MatrixCallback<MXUsersDevicesMap<MXDeviceInfo>> {
|
||||
override fun onSuccess(devices: MXUsersDevicesMap<MXDeviceInfo>) {
|
||||
mCrypto!!.encryptingThreadHandler.post {
|
||||
val encryptToVerifiedDevicesOnly = mCrypto!!.globalBlacklistUnverifiedDevices || mCrypto!!.isRoomBlacklistUnverifiedDevices(mRoomId)
|
||||
override fun onSuccess(data: MXUsersDevicesMap<MXDeviceInfo>) {
|
||||
val encryptToVerifiedDevicesOnly = mCrypto.getGlobalBlacklistUnverifiedDevices() || mCrypto.isRoomBlacklistUnverifiedDevices(mRoomId)
|
||||
|
||||
val devicesInRoom = MXUsersDevicesMap<MXDeviceInfo>()
|
||||
val unknownDevices = MXUsersDevicesMap<MXDeviceInfo>()
|
||||
val devicesInRoom = MXUsersDevicesMap<MXDeviceInfo>()
|
||||
val unknownDevices = MXUsersDevicesMap<MXDeviceInfo>()
|
||||
|
||||
val userIds = devices.userIds
|
||||
for (userId in data.userIds) {
|
||||
val deviceIds = data.getUserDeviceIds(userId)
|
||||
|
||||
for (userId in userIds) {
|
||||
val deviceIds = devices.getUserDeviceIds(userId)
|
||||
for (deviceId in deviceIds!!) {
|
||||
val deviceInfo = data.getObject(deviceId, userId)
|
||||
|
||||
for (deviceId in deviceIds!!) {
|
||||
val deviceInfo = devices.getObject(deviceId, userId)
|
||||
|
||||
if (mCrypto!!.warnOnUnknownDevices() && deviceInfo!!.isUnknown) {
|
||||
// The device is not yet known by the user
|
||||
unknownDevices.setObject(deviceInfo, userId, deviceId)
|
||||
continue
|
||||
}
|
||||
|
||||
if (deviceInfo!!.isBlocked) {
|
||||
// Remove any blocked devices
|
||||
continue
|
||||
}
|
||||
|
||||
if (!deviceInfo.isVerified && encryptToVerifiedDevicesOnly) {
|
||||
continue
|
||||
}
|
||||
|
||||
if (TextUtils.equals(deviceInfo.identityKey(), olmDevice.deviceCurve25519Key)) {
|
||||
// Don't bother sending to ourself
|
||||
continue
|
||||
}
|
||||
|
||||
devicesInRoom.setObject(deviceInfo, userId, deviceId)
|
||||
if (mCrypto.warnOnUnknownDevices() && deviceInfo!!.isUnknown) {
|
||||
// The device is not yet known by the user
|
||||
unknownDevices.setObject(deviceInfo, userId, deviceId)
|
||||
continue
|
||||
}
|
||||
|
||||
if (deviceInfo!!.isBlocked) {
|
||||
// Remove any blocked devices
|
||||
continue
|
||||
}
|
||||
|
||||
if (!deviceInfo.isVerified && encryptToVerifiedDevicesOnly) {
|
||||
continue
|
||||
}
|
||||
|
||||
if (TextUtils.equals(deviceInfo.identityKey(), olmDevice.deviceCurve25519Key)) {
|
||||
// Don't bother sending to ourself
|
||||
continue
|
||||
}
|
||||
|
||||
devicesInRoom.setObject(deviceInfo, userId, deviceId)
|
||||
}
|
||||
}
|
||||
|
||||
CryptoAsyncHelper.getUiHandler().post {
|
||||
// Check if any of these devices are not yet known to the user.
|
||||
// if so, warn the user so they can verify or ignore.
|
||||
if (0 != unknownDevices.map.size) {
|
||||
callback.onFailure(Failure.CryptoError(MXCryptoError(MXCryptoError.UNKNOWN_DEVICES_CODE,
|
||||
MXCryptoError.UNABLE_TO_ENCRYPT, MXCryptoError.UNKNOWN_DEVICES_REASON, unknownDevices)))
|
||||
} else {
|
||||
callback.onSuccess(devicesInRoom)
|
||||
}
|
||||
CryptoAsyncHelper.getUiHandler().post {
|
||||
// Check if any of these devices are not yet known to the user.
|
||||
// if so, warn the user so they can verify or ignore.
|
||||
if (0 != unknownDevices.map.size) {
|
||||
callback.onFailure(Failure.CryptoError(MXCryptoError(MXCryptoError.UNKNOWN_DEVICES_CODE,
|
||||
MXCryptoError.UNABLE_TO_ENCRYPT, MXCryptoError.UNKNOWN_DEVICES_REASON, unknownDevices)))
|
||||
} else {
|
||||
callback.onSuccess(devicesInRoom)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -701,8 +701,4 @@ internal class RealmCryptoStore(private val enableFileEncryption: Boolean = fals
|
|||
}
|
||||
.toMutableList()
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val LOG_TAG = "RealmCryptoStore"
|
||||
}
|
||||
}
|
|
@ -29,10 +29,10 @@ import im.vector.matrix.android.api.session.events.model.EventType
|
|||
import im.vector.matrix.android.api.session.events.model.toModel
|
||||
import im.vector.matrix.android.internal.crypto.CryptoAsyncHelper
|
||||
import im.vector.matrix.android.internal.crypto.DeviceListManager
|
||||
import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore
|
||||
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.rest.*
|
||||
import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore
|
||||
import im.vector.matrix.android.internal.crypto.tasks.SendToDeviceTask
|
||||
import im.vector.matrix.android.internal.task.TaskExecutor
|
||||
import im.vector.matrix.android.internal.task.configureWith
|
||||
|
@ -59,9 +59,10 @@ internal class DefaultSasVerificationService(private val mCredentials: Credentia
|
|||
|
||||
// Event received from the sync
|
||||
fun onToDeviceEvent(event: Event) {
|
||||
CryptoAsyncHelper.getDecryptBackgroundHandler().post { // TODO We are already in a BG thread
|
||||
CryptoAsyncHelper.getDecryptBackgroundHandler().post {
|
||||
// TODO We are already in a BG thread
|
||||
when (event.type) {
|
||||
EventType.KEY_VERIFICATION_START -> {
|
||||
EventType.KEY_VERIFICATION_START -> {
|
||||
onStartRequestReceived(event)
|
||||
}
|
||||
EventType.KEY_VERIFICATION_CANCEL -> {
|
||||
|
@ -70,13 +71,13 @@ internal class DefaultSasVerificationService(private val mCredentials: Credentia
|
|||
EventType.KEY_VERIFICATION_ACCEPT -> {
|
||||
onAcceptReceived(event)
|
||||
}
|
||||
EventType.KEY_VERIFICATION_KEY -> {
|
||||
EventType.KEY_VERIFICATION_KEY -> {
|
||||
onKeyReceived(event)
|
||||
}
|
||||
EventType.KEY_VERIFICATION_MAC -> {
|
||||
EventType.KEY_VERIFICATION_MAC -> {
|
||||
onMacReceived(event)
|
||||
}
|
||||
else -> {
|
||||
else -> {
|
||||
//ignore
|
||||
}
|
||||
}
|
||||
|
@ -131,24 +132,15 @@ internal class DefaultSasVerificationService(private val mCredentials: Credentia
|
|||
override fun markedLocallyAsManuallyVerified(userId: String, deviceID: String) {
|
||||
mCryptoListener.setDeviceVerification(MXDeviceInfo.DEVICE_VERIFICATION_VERIFIED,
|
||||
deviceID,
|
||||
userId,
|
||||
object : MatrixCallback<Unit> {
|
||||
override fun onSuccess(data: Unit) {
|
||||
uiHandler.post {
|
||||
listeners.forEach {
|
||||
try {
|
||||
it.markedAsManuallyVerified(userId, deviceID)
|
||||
} catch (e: Throwable) {
|
||||
Timber.e(e, "## Error while notifying listeners")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
userId)
|
||||
|
||||
override fun onFailure(failure: Throwable) {
|
||||
Timber.e(failure, "## Manual verification failed in state")
|
||||
}
|
||||
})
|
||||
listeners.forEach {
|
||||
try {
|
||||
it.markedAsManuallyVerified(userId, deviceID)
|
||||
} catch (e: Throwable) {
|
||||
Timber.e(e, "## Error while notifying listeners")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun onStartRequestReceived(event: Event) {
|
||||
|
@ -435,12 +427,12 @@ internal class DefaultSasVerificationService(private val mCredentials: Credentia
|
|||
mCryptoListener = listener
|
||||
}
|
||||
|
||||
fun setDeviceVerification(verificationStatus: Int, deviceId: String, userId: String, callback: MatrixCallback<Unit>) {
|
||||
mCryptoListener.setDeviceVerification(verificationStatus, deviceId, userId, callback)
|
||||
fun setDeviceVerification(verificationStatus: Int, deviceId: String, userId: String) {
|
||||
mCryptoListener.setDeviceVerification(verificationStatus, deviceId, userId)
|
||||
}
|
||||
|
||||
interface SasCryptoListener {
|
||||
fun setDeviceVerification(verificationStatus: Int, deviceId: String, userId: String, callback: MatrixCallback<Unit>)
|
||||
fun setDeviceVerification(verificationStatus: Int, deviceId: String, userId: String)
|
||||
fun getMyDevice(): MXDeviceInfo
|
||||
}
|
||||
}
|
|
@ -239,33 +239,15 @@ internal abstract class SASVerificationTransaction(
|
|||
|
||||
setDeviceVerified(
|
||||
otherDeviceId ?: "",
|
||||
otherUserId,
|
||||
success = {
|
||||
state = SasVerificationTxState.Verified
|
||||
},
|
||||
error = {
|
||||
//mmm what to do?, looks like this is never called
|
||||
}
|
||||
)
|
||||
otherUserId)
|
||||
|
||||
state = SasVerificationTxState.Verified
|
||||
}
|
||||
|
||||
private fun setDeviceVerified(deviceId: String, userId: String, success: () -> Unit, error: () -> Unit) {
|
||||
private fun setDeviceVerified(deviceId: String, userId: String) {
|
||||
mSasVerificationService.setDeviceVerification(MXDeviceInfo.DEVICE_VERIFICATION_VERIFIED,
|
||||
deviceId,
|
||||
userId,
|
||||
object : MatrixCallback<Unit> {
|
||||
|
||||
override fun onSuccess(data: Unit) {
|
||||
//We good
|
||||
Timber.d("## SAS verification complete and device status updated for id:$transactionId")
|
||||
success()
|
||||
}
|
||||
|
||||
override fun onFailure(failure: Throwable) {
|
||||
Timber.e(failure, "## SAS verification [$transactionId] failed in state : $state")
|
||||
error()
|
||||
}
|
||||
})
|
||||
userId)
|
||||
}
|
||||
|
||||
override fun cancel() {
|
||||
|
|
|
@ -257,16 +257,16 @@ internal class DefaultSession(override val sessionParams: SessionParams) : Sessi
|
|||
return cryptoService.getKeysBackupService()
|
||||
}
|
||||
|
||||
override fun isRoomBlacklistUnverifiedDevices(roomId: String, callback: MatrixCallback<Boolean>?) {
|
||||
cryptoService.isRoomBlacklistUnverifiedDevices(roomId, callback)
|
||||
override fun isRoomBlacklistUnverifiedDevices(roomId: String?): Boolean {
|
||||
return cryptoService.isRoomBlacklistUnverifiedDevices(roomId)
|
||||
}
|
||||
|
||||
override fun setWarnOnUnknownDevices(warn: Boolean) {
|
||||
cryptoService.setWarnOnUnknownDevices(warn)
|
||||
}
|
||||
|
||||
override fun setDeviceVerification(verificationStatus: Int, deviceId: String, userId: String, callback: MatrixCallback<Unit>) {
|
||||
cryptoService.setDeviceVerification(verificationStatus, deviceId, userId, callback)
|
||||
override fun setDeviceVerification(verificationStatus: Int, deviceId: String, userId: String) {
|
||||
cryptoService.setDeviceVerification(verificationStatus, deviceId, userId)
|
||||
}
|
||||
|
||||
override fun getUserDevices(userId: String): MutableList<MXDeviceInfo> {
|
||||
|
@ -293,16 +293,16 @@ internal class DefaultSession(override val sessionParams: SessionParams) : Sessi
|
|||
return cryptoService.inboundGroupSessionsCount(onlyBackedUp)
|
||||
}
|
||||
|
||||
override fun getGlobalBlacklistUnverifiedDevices(callback: MatrixCallback<Boolean>?) {
|
||||
cryptoService.getGlobalBlacklistUnverifiedDevices(callback)
|
||||
override fun getGlobalBlacklistUnverifiedDevices(): Boolean {
|
||||
return cryptoService.getGlobalBlacklistUnverifiedDevices()
|
||||
}
|
||||
|
||||
override fun setGlobalBlacklistUnverifiedDevices(block: Boolean, callback: MatrixCallback<Unit>?) {
|
||||
cryptoService.setGlobalBlacklistUnverifiedDevices(block, callback)
|
||||
override fun setGlobalBlacklistUnverifiedDevices(block: Boolean) {
|
||||
cryptoService.setGlobalBlacklistUnverifiedDevices(block)
|
||||
}
|
||||
|
||||
override fun setRoomUnBlacklistUnverifiedDevices(roomId: String, callback: MatrixCallback<Unit>) {
|
||||
cryptoService.setRoomUnBlacklistUnverifiedDevices(roomId, callback)
|
||||
override fun setRoomUnBlacklistUnverifiedDevices(roomId: String) {
|
||||
cryptoService.setRoomUnBlacklistUnverifiedDevices(roomId)
|
||||
}
|
||||
|
||||
override fun getDeviceTrackingStatus(userId: String): Int {
|
||||
|
@ -317,12 +317,12 @@ internal class DefaultSession(override val sessionParams: SessionParams) : Sessi
|
|||
cryptoService.exportRoomKeys(password, callback)
|
||||
}
|
||||
|
||||
override fun setRoomBlacklistUnverifiedDevices(roomId: String, callback: MatrixCallback<Unit>) {
|
||||
cryptoService.setRoomBlacklistUnverifiedDevices(roomId, callback)
|
||||
override fun setRoomBlacklistUnverifiedDevices(roomId: String) {
|
||||
cryptoService.setRoomBlacklistUnverifiedDevices(roomId)
|
||||
}
|
||||
|
||||
override fun getDeviceInfo(userId: String, deviceId: String?, callback: MatrixCallback<MXDeviceInfo?>) {
|
||||
cryptoService.getDeviceInfo(userId, deviceId, callback)
|
||||
override fun getDeviceInfo(userId: String, deviceId: String?): MXDeviceInfo? {
|
||||
return cryptoService.getDeviceInfo(userId, deviceId)
|
||||
}
|
||||
|
||||
override fun reRequestRoomKeyForEvent(event: Event) {
|
||||
|
|
|
@ -47,7 +47,6 @@ import im.vector.matrix.android.api.MatrixCallback
|
|||
import im.vector.matrix.android.api.extensions.getFingerprintHumanReadable
|
||||
import im.vector.matrix.android.api.extensions.sortByLastSeen
|
||||
import im.vector.matrix.android.api.session.Session
|
||||
import im.vector.matrix.android.internal.crypto.model.MXDeviceInfo
|
||||
import im.vector.matrix.android.internal.crypto.model.rest.DeviceInfo
|
||||
import im.vector.matrix.android.internal.crypto.model.rest.DevicesListResponse
|
||||
import im.vector.riotredesign.R
|
||||
|
@ -2210,42 +2209,26 @@ class VectorSettingsPreferencesFragment : VectorPreferenceFragment(), SharedPref
|
|||
|
||||
// crypto section: device key (fingerprint)
|
||||
if (!TextUtils.isEmpty(deviceId) && !TextUtils.isEmpty(userId)) {
|
||||
mSession.getDeviceInfo(userId, deviceId, object : MatrixCallback<MXDeviceInfo?> {
|
||||
override fun onSuccess(data: MXDeviceInfo?) {
|
||||
if (null != data && !TextUtils.isEmpty(data.fingerprint()) && null != activity) {
|
||||
cryptoInfoTextPreference.summary = data.getFingerprintHumanReadable()
|
||||
val deviceInfo = mSession.getDeviceInfo(userId, deviceId)
|
||||
|
||||
cryptoInfoTextPreference.setOnPreferenceClickListener {
|
||||
data.fingerprint()?.let {
|
||||
copyToClipboard(requireActivity(), it)
|
||||
}
|
||||
true
|
||||
}
|
||||
if (null != deviceInfo && !TextUtils.isEmpty(deviceInfo.fingerprint())) {
|
||||
cryptoInfoTextPreference.summary = deviceInfo.getFingerprintHumanReadable()
|
||||
|
||||
cryptoInfoTextPreference.setOnPreferenceClickListener {
|
||||
deviceInfo.fingerprint()?.let {
|
||||
copyToClipboard(requireActivity(), it)
|
||||
}
|
||||
true
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
sendToUnverifiedDevicesPref.isChecked = false
|
||||
|
||||
mSession.getGlobalBlacklistUnverifiedDevices(object : MatrixCallback<Boolean> {
|
||||
override fun onSuccess(data: Boolean) {
|
||||
sendToUnverifiedDevicesPref.isChecked = data
|
||||
}
|
||||
})
|
||||
sendToUnverifiedDevicesPref.isChecked = mSession.getGlobalBlacklistUnverifiedDevices()
|
||||
|
||||
sendToUnverifiedDevicesPref.onPreferenceClickListener = Preference.OnPreferenceClickListener {
|
||||
mSession.getGlobalBlacklistUnverifiedDevices(object : MatrixCallback<Boolean> {
|
||||
override fun onSuccess(data: Boolean) {
|
||||
if (sendToUnverifiedDevicesPref.isChecked != data) {
|
||||
mSession.setGlobalBlacklistUnverifiedDevices(sendToUnverifiedDevicesPref.isChecked, object : MatrixCallback<Unit> {
|
||||
override fun onSuccess(data: Unit) {
|
||||
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
mSession.setGlobalBlacklistUnverifiedDevices(sendToUnverifiedDevicesPref.isChecked)
|
||||
|
||||
true
|
||||
}
|
||||
|
@ -2871,8 +2854,6 @@ if (sharedDataItems.isNotEmpty() && thisActivity != null) {
|
|||
* ========================================================================================== */
|
||||
|
||||
companion object {
|
||||
private val LOG_TAG = VectorSettingsPreferencesFragment::class.java.simpleName
|
||||
|
||||
// arguments indexes
|
||||
private const val ARG_MATRIX_ID = "VectorSettingsPreferencesFragment.ARG_MATRIX_ID"
|
||||
|
||||
|
|
Loading…
Reference in a new issue