forked from GitHub-Mirror/riotX-android
Crypto: WIP cleaning
This commit is contained in:
parent
3f7d20ec5b
commit
784d55c16c
@ -46,11 +46,11 @@ android {
|
|||||||
debug {
|
debug {
|
||||||
// Set to true to log privacy or sensible data, such as token
|
// Set to true to log privacy or sensible data, such as token
|
||||||
// TODO Set to false
|
// TODO Set to false
|
||||||
buildConfigField "boolean", "LOG_PRIVATE_DATA", "true"
|
buildConfigField "boolean", "LOG_PRIVATE_DATA", "false"
|
||||||
|
|
||||||
// Set to BODY instead of NONE to enable logging
|
// Set to BODY instead of NONE to enable logging
|
||||||
//TODO Revert BODY
|
//TODO Revert BODY
|
||||||
buildConfigField "okhttp3.logging.HttpLoggingInterceptor.Level", "OKHTTP_LOGGING_LEVEL", "okhttp3.logging.HttpLoggingInterceptor.Level.BODY"
|
buildConfigField "okhttp3.logging.HttpLoggingInterceptor.Level", "OKHTTP_LOGGING_LEVEL", "okhttp3.logging.HttpLoggingInterceptor.Level.HEADERS"
|
||||||
}
|
}
|
||||||
|
|
||||||
release {
|
release {
|
||||||
|
@ -57,11 +57,8 @@ import im.vector.matrix.android.internal.crypto.model.rest.KeysUploadResponse
|
|||||||
import im.vector.matrix.android.internal.crypto.model.rest.RoomKeyRequestBody
|
import im.vector.matrix.android.internal.crypto.model.rest.RoomKeyRequestBody
|
||||||
import im.vector.matrix.android.internal.crypto.repository.WarnOnUnknownDeviceRepository
|
import im.vector.matrix.android.internal.crypto.repository.WarnOnUnknownDeviceRepository
|
||||||
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.ClaimOneTimeKeysForUsersDeviceTask
|
|
||||||
import im.vector.matrix.android.internal.crypto.tasks.DeleteDeviceTask
|
import im.vector.matrix.android.internal.crypto.tasks.DeleteDeviceTask
|
||||||
import im.vector.matrix.android.internal.crypto.tasks.GetDevicesTask
|
import im.vector.matrix.android.internal.crypto.tasks.GetDevicesTask
|
||||||
import im.vector.matrix.android.internal.crypto.tasks.GetKeyChangesTask
|
|
||||||
import im.vector.matrix.android.internal.crypto.tasks.SendToDeviceTask
|
|
||||||
import im.vector.matrix.android.internal.crypto.tasks.SetDeviceNameTask
|
import im.vector.matrix.android.internal.crypto.tasks.SetDeviceNameTask
|
||||||
import im.vector.matrix.android.internal.crypto.tasks.UploadKeysTask
|
import im.vector.matrix.android.internal.crypto.tasks.UploadKeysTask
|
||||||
import im.vector.matrix.android.internal.crypto.verification.DefaultSasVerificationService
|
import im.vector.matrix.android.internal.crypto.verification.DefaultSasVerificationService
|
||||||
@ -80,74 +77,71 @@ import timber.log.Timber
|
|||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A `MXCrypto` class instance manages the end-to-end crypto for a MXSession instance.
|
* A `CryptoService` class instance manages the end-to-end crypto for a session.
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* Messages posted by the user are automatically redirected to MXCrypto in order to be encrypted
|
* Messages posted by the user are automatically redirected to CryptoService in order to be encrypted
|
||||||
* before sending.
|
* before sending.
|
||||||
* In the other hand, received events goes through MXCrypto for decrypting.
|
* In the other hand, received events goes through CryptoService for decrypting.
|
||||||
* MXCrypto maintains all necessary keys and their sharing with other devices required for the crypto.
|
* CryptoService maintains all necessary keys and their sharing with other devices required for the crypto.
|
||||||
* Specially, it tracks all room membership changes events in order to do keys updates.
|
* Specially, it tracks all room membership changes events in order to do keys updates.
|
||||||
*/
|
*/
|
||||||
internal class CryptoManager(
|
internal class CryptoManager(
|
||||||
// The credentials,
|
// The credentials,
|
||||||
private val mCredentials: Credentials,
|
private val credentials: Credentials,
|
||||||
private val mMyDeviceInfoHolder: MyDeviceInfoHolder,
|
private val myDeviceInfoHolder: MyDeviceInfoHolder,
|
||||||
// the crypto store
|
// the crypto store
|
||||||
private val mCryptoStore: IMXCryptoStore,
|
private val cryptoStore: IMXCryptoStore,
|
||||||
// Olm device
|
// Olm device
|
||||||
private val mOlmDevice: MXOlmDevice,
|
private val olmDevice: MXOlmDevice,
|
||||||
// Set of parameters used to configure/customize the end-to-end crypto.
|
// Set of parameters used to configure/customize the end-to-end crypto.
|
||||||
private val mCryptoConfig: MXCryptoConfig = MXCryptoConfig(),
|
private val cryptoConfig: MXCryptoConfig = MXCryptoConfig(),
|
||||||
// Device list manager
|
// Device list manager
|
||||||
private val deviceListManager: DeviceListManager,
|
private val deviceListManager: DeviceListManager,
|
||||||
// The key backup service.
|
// The key backup service.
|
||||||
private val mKeysBackup: KeysBackup,
|
private val keysBackup: KeysBackup,
|
||||||
//
|
//
|
||||||
private val mObjectSigner: ObjectSigner,
|
private val objectSigner: ObjectSigner,
|
||||||
//
|
//
|
||||||
private val mOneTimeKeysUploader: OneTimeKeysUploader,
|
private val oneTimeKeysUploader: OneTimeKeysUploader,
|
||||||
//
|
//
|
||||||
private val roomDecryptorProvider: RoomDecryptorProvider,
|
private val roomDecryptorProvider: RoomDecryptorProvider,
|
||||||
// The SAS verification service.
|
// The SAS verification service.
|
||||||
private val mSasVerificationService: DefaultSasVerificationService,
|
private val sasVerificationService: DefaultSasVerificationService,
|
||||||
//
|
//
|
||||||
private val mIncomingRoomKeyRequestManager: IncomingRoomKeyRequestManager,
|
private val incomingRoomKeyRequestManager: IncomingRoomKeyRequestManager,
|
||||||
//
|
//
|
||||||
private val mOutgoingRoomKeyRequestManager: OutgoingRoomKeyRequestManager,
|
private val outgoingRoomKeyRequestManager: OutgoingRoomKeyRequestManager,
|
||||||
// Olm Manager
|
// Olm Manager
|
||||||
private val mOlmManager: OlmManager,
|
private val olmManager: OlmManager,
|
||||||
// Actions
|
// Actions
|
||||||
private val mSetDeviceVerificationAction: SetDeviceVerificationAction,
|
private val setDeviceVerificationAction: SetDeviceVerificationAction,
|
||||||
private val mMegolmSessionDataImporter: MegolmSessionDataImporter,
|
private val megolmSessionDataImporter: MegolmSessionDataImporter,
|
||||||
private val mEnsureOlmSessionsForDevicesAction: EnsureOlmSessionsForDevicesAction,
|
private val ensureOlmSessionsForDevicesAction: EnsureOlmSessionsForDevicesAction,
|
||||||
// Repository
|
// Repository
|
||||||
private val mWarnOnUnknownDevicesRepository: WarnOnUnknownDeviceRepository,
|
private val warnOnUnknownDevicesRepository: WarnOnUnknownDeviceRepository,
|
||||||
private val mMXMegolmEncryptionFactory: MXMegolmEncryptionFactory,
|
private val megolmEncryptionFactory: MXMegolmEncryptionFactory,
|
||||||
private val mMXOlmEncryptionFactory: MXOlmEncryptionFactory,
|
private val olmEncryptionFactory: MXOlmEncryptionFactory,
|
||||||
// Tasks
|
// Tasks
|
||||||
private val mClaimOneTimeKeysForUsersDeviceTask: ClaimOneTimeKeysForUsersDeviceTask,
|
private val deleteDeviceTask: DeleteDeviceTask,
|
||||||
private val mDeleteDeviceTask: DeleteDeviceTask,
|
private val getDevicesTask: GetDevicesTask,
|
||||||
private val mGetDevicesTask: GetDevicesTask,
|
private val setDeviceNameTask: SetDeviceNameTask,
|
||||||
private val mGetKeyChangesTask: GetKeyChangesTask,
|
private val uploadKeysTask: UploadKeysTask,
|
||||||
private val mSendToDeviceTask: SendToDeviceTask,
|
|
||||||
private val mSetDeviceNameTask: SetDeviceNameTask,
|
|
||||||
private val mUploadKeysTask: UploadKeysTask,
|
|
||||||
private val loadRoomMembersTask: LoadRoomMembersTask,
|
private val loadRoomMembersTask: LoadRoomMembersTask,
|
||||||
private val monarchy: Monarchy,
|
private val monarchy: Monarchy,
|
||||||
private val coroutineDispatchers: MatrixCoroutineDispatchers,
|
private val coroutineDispatchers: MatrixCoroutineDispatchers,
|
||||||
// TaskExecutor
|
// TaskExecutor
|
||||||
private val mTaskExecutor: TaskExecutor
|
private val taskExecutor: TaskExecutor
|
||||||
) : CryptoService {
|
) : CryptoService {
|
||||||
|
|
||||||
// MXEncrypting instance for each room.
|
// MXEncrypting instance for each room.
|
||||||
private val mRoomEncryptors: MutableMap<String, IMXEncrypting> = HashMap()
|
private val roomEncryptors: MutableMap<String, IMXEncrypting> = HashMap()
|
||||||
|
|
||||||
// the encryption is starting
|
// the encryption is starting
|
||||||
private var mIsStarting: Boolean = false
|
private var isStarting: Boolean = false
|
||||||
|
|
||||||
// tell if the crypto is started
|
// tell if the crypto is started
|
||||||
private var mIsStarted: Boolean = false
|
private var isStarted: Boolean = false
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
//private val mNetworkListener = object : IMXNetworkEventListener {
|
//private val mNetworkListener = object : IMXNetworkEventListener {
|
||||||
@ -179,36 +173,36 @@ internal class CryptoManager(
|
|||||||
private val mInitializationCallbacks = ArrayList<MatrixCallback<Unit>>()
|
private val mInitializationCallbacks = ArrayList<MatrixCallback<Unit>>()
|
||||||
|
|
||||||
override fun setDeviceName(deviceId: String, deviceName: String, callback: MatrixCallback<Unit>) {
|
override fun setDeviceName(deviceId: String, deviceName: String, callback: MatrixCallback<Unit>) {
|
||||||
mSetDeviceNameTask
|
setDeviceNameTask
|
||||||
.configureWith(SetDeviceNameTask.Params(deviceId, deviceName))
|
.configureWith(SetDeviceNameTask.Params(deviceId, deviceName))
|
||||||
.dispatchTo(callback)
|
.dispatchTo(callback)
|
||||||
.executeBy(mTaskExecutor)
|
.executeBy(taskExecutor)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun deleteDevice(deviceId: String, accountPassword: String, callback: MatrixCallback<Unit>) {
|
override fun deleteDevice(deviceId: String, accountPassword: String, callback: MatrixCallback<Unit>) {
|
||||||
mDeleteDeviceTask
|
deleteDeviceTask
|
||||||
.configureWith(DeleteDeviceTask.Params(deviceId, accountPassword))
|
.configureWith(DeleteDeviceTask.Params(deviceId, accountPassword))
|
||||||
.dispatchTo(callback)
|
.dispatchTo(callback)
|
||||||
.executeBy(mTaskExecutor)
|
.executeBy(taskExecutor)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getCryptoVersion(context: Context, longFormat: Boolean): String {
|
override fun getCryptoVersion(context: Context, longFormat: Boolean): String {
|
||||||
return if (longFormat) mOlmManager.getDetailedVersion(context) else mOlmManager.version
|
return if (longFormat) olmManager.getDetailedVersion(context) else olmManager.version
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getMyDevice(): MXDeviceInfo {
|
override fun getMyDevice(): MXDeviceInfo {
|
||||||
return mMyDeviceInfoHolder.myDevice
|
return myDeviceInfoHolder.myDevice
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getDevicesList(callback: MatrixCallback<DevicesListResponse>) {
|
override fun getDevicesList(callback: MatrixCallback<DevicesListResponse>) {
|
||||||
mGetDevicesTask
|
getDevicesTask
|
||||||
.configureWith(Unit)
|
.configureWith(Unit)
|
||||||
.dispatchTo(callback)
|
.dispatchTo(callback)
|
||||||
.executeBy(mTaskExecutor)
|
.executeBy(taskExecutor)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun inboundGroupSessionsCount(onlyBackedUp: Boolean): Int {
|
override fun inboundGroupSessionsCount(onlyBackedUp: Boolean): Int {
|
||||||
return mCryptoStore.inboundGroupSessionsCount(onlyBackedUp)
|
return cryptoStore.inboundGroupSessionsCount(onlyBackedUp)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -218,7 +212,7 @@ internal class CryptoManager(
|
|||||||
* @return the tracking status
|
* @return the tracking status
|
||||||
*/
|
*/
|
||||||
override fun getDeviceTrackingStatus(userId: String): Int {
|
override fun getDeviceTrackingStatus(userId: String): Int {
|
||||||
return mCryptoStore.getDeviceTrackingStatus(userId, DeviceListManager.TRACKING_STATUS_NOT_TRACKED)
|
return cryptoStore.getDeviceTrackingStatus(userId, DeviceListManager.TRACKING_STATUS_NOT_TRACKED)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -227,7 +221,7 @@ internal class CryptoManager(
|
|||||||
* @return true if the crypto is started
|
* @return true if the crypto is started
|
||||||
*/
|
*/
|
||||||
fun isStarted(): Boolean {
|
fun isStarted(): Boolean {
|
||||||
return mIsStarted
|
return isStarted
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -236,7 +230,7 @@ internal class CryptoManager(
|
|||||||
* @return true if the crypto is starting
|
* @return true if the crypto is starting
|
||||||
*/
|
*/
|
||||||
fun isStarting(): Boolean {
|
fun isStarting(): Boolean {
|
||||||
return mIsStarting
|
return isStarting
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -248,7 +242,7 @@ internal class CryptoManager(
|
|||||||
* @param isInitialSync true if it starts from an initial sync
|
* @param isInitialSync true if it starts from an initial sync
|
||||||
*/
|
*/
|
||||||
fun start(isInitialSync: Boolean) {
|
fun start(isInitialSync: Boolean) {
|
||||||
if (mIsStarting) {
|
if (isStarting) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -261,16 +255,16 @@ internal class CryptoManager(
|
|||||||
// return
|
// return
|
||||||
//}
|
//}
|
||||||
|
|
||||||
mIsStarting = true
|
isStarting = true
|
||||||
|
|
||||||
// Open the store
|
// Open the store
|
||||||
mCryptoStore.open()
|
cryptoStore.open()
|
||||||
|
|
||||||
uploadDeviceKeys(object : MatrixCallback<KeysUploadResponse> {
|
uploadDeviceKeys(object : MatrixCallback<KeysUploadResponse> {
|
||||||
private fun onError() {
|
private fun onError() {
|
||||||
Handler().postDelayed({
|
Handler().postDelayed({
|
||||||
if (!isStarted()) {
|
if (!isStarted()) {
|
||||||
mIsStarting = false
|
isStarting = false
|
||||||
start(isInitialSync)
|
start(isInitialSync)
|
||||||
}
|
}
|
||||||
}, 1000)
|
}, 1000)
|
||||||
@ -278,33 +272,33 @@ internal class CryptoManager(
|
|||||||
|
|
||||||
override fun onSuccess(data: KeysUploadResponse) {
|
override fun onSuccess(data: KeysUploadResponse) {
|
||||||
Timber.v("###########################################################")
|
Timber.v("###########################################################")
|
||||||
Timber.v("uploadDeviceKeys done for " + mCredentials.userId)
|
Timber.v("uploadDeviceKeys done for " + credentials.userId)
|
||||||
Timber.v(" - device id : " + mCredentials.deviceId)
|
Timber.v(" - device id : " + credentials.deviceId)
|
||||||
Timber.v(" - ed25519 : " + mOlmDevice.deviceEd25519Key)
|
Timber.v(" - ed25519 : " + olmDevice.deviceEd25519Key)
|
||||||
Timber.v(" - curve25519 : " + mOlmDevice.deviceCurve25519Key)
|
Timber.v(" - curve25519 : " + olmDevice.deviceCurve25519Key)
|
||||||
Timber.v(" - oneTimeKeys: " + mOneTimeKeysUploader.mLastPublishedOneTimeKeys)
|
Timber.v(" - oneTimeKeys: " + oneTimeKeysUploader.mLastPublishedOneTimeKeys)
|
||||||
Timber.v("")
|
Timber.v("")
|
||||||
|
|
||||||
mOneTimeKeysUploader.maybeUploadOneTimeKeys(object : MatrixCallback<Unit> {
|
oneTimeKeysUploader.maybeUploadOneTimeKeys(object : MatrixCallback<Unit> {
|
||||||
override fun onSuccess(data: Unit) {
|
override fun onSuccess(data: Unit) {
|
||||||
// TODO
|
// TODO
|
||||||
//if (null != mNetworkConnectivityReceiver) {
|
//if (null != mNetworkConnectivityReceiver) {
|
||||||
// mNetworkConnectivityReceiver!!.removeEventListener(mNetworkListener)
|
// mNetworkConnectivityReceiver!!.removeEventListener(mNetworkListener)
|
||||||
//}
|
//}
|
||||||
|
|
||||||
mIsStarting = false
|
isStarting = false
|
||||||
mIsStarted = true
|
isStarted = true
|
||||||
|
|
||||||
mOutgoingRoomKeyRequestManager.start()
|
outgoingRoomKeyRequestManager.start()
|
||||||
|
|
||||||
mKeysBackup.checkAndStartKeysBackup()
|
keysBackup.checkAndStartKeysBackup()
|
||||||
|
|
||||||
if (isInitialSync) {
|
if (isInitialSync) {
|
||||||
// refresh the devices list for each known room members
|
// refresh the devices list for each known room members
|
||||||
deviceListManager.invalidateAllDeviceLists()
|
deviceListManager.invalidateAllDeviceLists()
|
||||||
deviceListManager.refreshOutdatedDeviceLists()
|
deviceListManager.refreshOutdatedDeviceLists()
|
||||||
} else {
|
} else {
|
||||||
mIncomingRoomKeyRequestManager.processReceivedRoomKeyRequests()
|
incomingRoomKeyRequestManager.processReceivedRoomKeyRequests()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -326,58 +320,51 @@ internal class CryptoManager(
|
|||||||
* Close the crypto
|
* Close the crypto
|
||||||
*/
|
*/
|
||||||
fun close() {
|
fun close() {
|
||||||
mOlmDevice.release()
|
olmDevice.release()
|
||||||
|
|
||||||
mCryptoStore.close()
|
cryptoStore.close()
|
||||||
|
|
||||||
mOutgoingRoomKeyRequestManager.stop()
|
outgoingRoomKeyRequestManager.stop()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun isCryptoEnabled(): Boolean {
|
override fun isCryptoEnabled(): Boolean {
|
||||||
// TODO Check that this test is correct
|
// TODO Check that this test is correct
|
||||||
return mOlmDevice != null
|
return olmDevice != null
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the Keys backup Service
|
* @return the Keys backup Service
|
||||||
*/
|
*/
|
||||||
override fun getKeysBackupService(): KeysBackupService {
|
override fun getKeysBackupService(): KeysBackupService {
|
||||||
return mKeysBackup
|
return keysBackup
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the SasVerificationService
|
* @return the SasVerificationService
|
||||||
*/
|
*/
|
||||||
override fun getSasVerificationService(): SasVerificationService {
|
override fun getSasVerificationService(): SasVerificationService {
|
||||||
return mSasVerificationService
|
return sasVerificationService
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A sync response has been received
|
* A sync response has been received
|
||||||
*
|
*
|
||||||
* @param syncResponse the syncResponse
|
* @param syncResponse the syncResponse
|
||||||
* @param fromToken the start sync token
|
|
||||||
* @param isCatchingUp true if there is a catch-up in progress.
|
|
||||||
*/
|
*/
|
||||||
fun onSyncCompleted(syncResponse: SyncResponse, fromToken: String?, isCatchingUp: Boolean) {
|
fun onSyncCompleted(syncResponse: SyncResponse) {
|
||||||
if (null != syncResponse.deviceLists) {
|
if (syncResponse.deviceLists != null) {
|
||||||
deviceListManager.handleDeviceListsChanges(syncResponse.deviceLists.changed, syncResponse.deviceLists.left)
|
deviceListManager.handleDeviceListsChanges(syncResponse.deviceLists.changed, syncResponse.deviceLists.left)
|
||||||
}
|
}
|
||||||
|
if (syncResponse.deviceOneTimeKeysCount != null) {
|
||||||
if (null != syncResponse.deviceOneTimeKeysCount) {
|
|
||||||
val currentCount = syncResponse.deviceOneTimeKeysCount.signedCurve25519 ?: 0
|
val currentCount = syncResponse.deviceOneTimeKeysCount.signedCurve25519 ?: 0
|
||||||
mOneTimeKeysUploader.updateOneTimeKeyCount(currentCount)
|
oneTimeKeysUploader.updateOneTimeKeyCount(currentCount)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isStarted()) {
|
if (isStarted()) {
|
||||||
// Make sure we process to-device messages before generating new one-time-keys #2782
|
// Make sure we process to-device messages before generating new one-time-keys #2782
|
||||||
deviceListManager.refreshOutdatedDeviceLists()
|
deviceListManager.refreshOutdatedDeviceLists()
|
||||||
}
|
oneTimeKeysUploader.maybeUploadOneTimeKeys()
|
||||||
|
incomingRoomKeyRequestManager.processReceivedRoomKeyRequests()
|
||||||
if (!isCatchingUp && isStarted()) {
|
|
||||||
mOneTimeKeysUploader.maybeUploadOneTimeKeys()
|
|
||||||
|
|
||||||
mIncomingRoomKeyRequestManager.processReceivedRoomKeyRequests()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -392,7 +379,7 @@ internal class CryptoManager(
|
|||||||
return if (!TextUtils.equals(algorithm, MXCRYPTO_ALGORITHM_MEGOLM) && !TextUtils.equals(algorithm, MXCRYPTO_ALGORITHM_OLM)) {
|
return if (!TextUtils.equals(algorithm, MXCRYPTO_ALGORITHM_MEGOLM) && !TextUtils.equals(algorithm, MXCRYPTO_ALGORITHM_OLM)) {
|
||||||
// We only deal in olm keys
|
// We only deal in olm keys
|
||||||
null
|
null
|
||||||
} else mCryptoStore.deviceWithIdentityKey(senderKey)
|
} else cryptoStore.deviceWithIdentityKey(senderKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -403,7 +390,7 @@ internal class CryptoManager(
|
|||||||
*/
|
*/
|
||||||
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 (!TextUtils.isEmpty(userId) && !TextUtils.isEmpty(deviceId)) {
|
||||||
mCryptoStore.getUserDevice(deviceId!!, userId)
|
cryptoStore.getUserDevice(deviceId!!, userId)
|
||||||
} else {
|
} else {
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
@ -432,7 +419,7 @@ internal class CryptoManager(
|
|||||||
val userIds = devicesIdListByUserId.keys
|
val userIds = devicesIdListByUserId.keys
|
||||||
|
|
||||||
for (userId in userIds) {
|
for (userId in userIds) {
|
||||||
val storedDeviceIDs = mCryptoStore.getUserDevices(userId)
|
val storedDeviceIDs = cryptoStore.getUserDevices(userId)
|
||||||
|
|
||||||
// sanity checks
|
// sanity checks
|
||||||
if (null != storedDeviceIDs) {
|
if (null != storedDeviceIDs) {
|
||||||
@ -451,7 +438,7 @@ internal class CryptoManager(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (isUpdated) {
|
if (isUpdated) {
|
||||||
mCryptoStore.storeUserDevices(userId, storedDeviceIDs)
|
cryptoStore.storeUserDevices(userId, storedDeviceIDs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -468,7 +455,7 @@ internal class CryptoManager(
|
|||||||
* @param userId the owner of the device
|
* @param userId the owner of the device
|
||||||
*/
|
*/
|
||||||
override fun setDeviceVerification(verificationStatus: Int, deviceId: String, userId: String) {
|
override fun setDeviceVerification(verificationStatus: Int, deviceId: String, userId: String) {
|
||||||
mSetDeviceVerificationAction.handle(verificationStatus, deviceId, userId)
|
setDeviceVerificationAction.handle(verificationStatus, deviceId, userId)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -484,7 +471,7 @@ internal class CryptoManager(
|
|||||||
private fun setEncryptionInRoom(roomId: String, algorithm: String?, inhibitDeviceQuery: Boolean, membersId: List<String>): Boolean {
|
private fun setEncryptionInRoom(roomId: String, algorithm: String?, inhibitDeviceQuery: Boolean, membersId: List<String>): Boolean {
|
||||||
// If we already have encryption in this room, we should ignore this event
|
// If we already have encryption in this room, we should ignore this event
|
||||||
// (for now at least. Maybe we should alert the user somehow?)
|
// (for now at least. Maybe we should alert the user somehow?)
|
||||||
val existingAlgorithm = mCryptoStore.getRoomAlgorithm(roomId)
|
val existingAlgorithm = cryptoStore.getRoomAlgorithm(roomId)
|
||||||
|
|
||||||
if (!TextUtils.isEmpty(existingAlgorithm) && !TextUtils.equals(existingAlgorithm, algorithm)) {
|
if (!TextUtils.isEmpty(existingAlgorithm) && !TextUtils.equals(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")
|
||||||
@ -498,15 +485,15 @@ internal class CryptoManager(
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
mCryptoStore.storeRoomAlgorithm(roomId, algorithm!!)
|
cryptoStore.storeRoomAlgorithm(roomId, algorithm!!)
|
||||||
|
|
||||||
val alg: IMXEncrypting = when (algorithm) {
|
val alg: IMXEncrypting = when (algorithm) {
|
||||||
MXCRYPTO_ALGORITHM_MEGOLM -> mMXMegolmEncryptionFactory.instantiate(roomId)
|
MXCRYPTO_ALGORITHM_MEGOLM -> megolmEncryptionFactory.instantiate(roomId)
|
||||||
else -> mMXOlmEncryptionFactory.instantiate(roomId)
|
else -> olmEncryptionFactory.instantiate(roomId)
|
||||||
}
|
}
|
||||||
|
|
||||||
synchronized(mRoomEncryptors) {
|
synchronized(roomEncryptors) {
|
||||||
mRoomEncryptors.put(roomId, alg)
|
roomEncryptors.put(roomId, alg)
|
||||||
}
|
}
|
||||||
|
|
||||||
// if encryption was not previously enabled in this room, we will have been
|
// if encryption was not previously enabled in this room, we will have been
|
||||||
@ -538,12 +525,12 @@ internal class CryptoManager(
|
|||||||
override fun isRoomEncrypted(roomId: String): Boolean {
|
override fun isRoomEncrypted(roomId: String): Boolean {
|
||||||
var res: Boolean
|
var res: Boolean
|
||||||
|
|
||||||
synchronized(mRoomEncryptors) {
|
synchronized(roomEncryptors) {
|
||||||
res = mRoomEncryptors.containsKey(roomId)
|
res = roomEncryptors.containsKey(roomId)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!res) {
|
if (!res) {
|
||||||
res = !mCryptoStore.getRoomAlgorithm(roomId).isNullOrBlank()
|
res = !cryptoStore.getRoomAlgorithm(roomId).isNullOrBlank()
|
||||||
}
|
}
|
||||||
|
|
||||||
return res
|
return res
|
||||||
@ -553,7 +540,7 @@ internal class CryptoManager(
|
|||||||
* @return the stored device keys for a user.
|
* @return the stored device keys for a user.
|
||||||
*/
|
*/
|
||||||
override fun getUserDevices(userId: String): MutableList<MXDeviceInfo> {
|
override fun getUserDevices(userId: String): MutableList<MXDeviceInfo> {
|
||||||
val map = mCryptoStore.getUserDevices(userId)
|
val map = cryptoStore.getUserDevices(userId)
|
||||||
return if (null != map) ArrayList(map.values) else ArrayList()
|
return if (null != map) ArrayList(map.values) else ArrayList()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -568,15 +555,15 @@ internal class CryptoManager(
|
|||||||
*/
|
*/
|
||||||
fun ensureOlmSessionsForDevices(devicesByUser: Map<String, List<MXDeviceInfo>>,
|
fun ensureOlmSessionsForDevices(devicesByUser: Map<String, List<MXDeviceInfo>>,
|
||||||
callback: MatrixCallback<MXUsersDevicesMap<MXOlmSessionResult>>?) {
|
callback: MatrixCallback<MXUsersDevicesMap<MXOlmSessionResult>>?) {
|
||||||
mEnsureOlmSessionsForDevicesAction.handle(devicesByUser, callback)
|
ensureOlmSessionsForDevicesAction.handle(devicesByUser, callback)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isEncryptionEnabledForInvitedUser(): Boolean {
|
fun isEncryptionEnabledForInvitedUser(): Boolean {
|
||||||
return mCryptoConfig.mEnableEncryptionForInvitedMembers
|
return cryptoConfig.mEnableEncryptionForInvitedMembers
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getEncryptionAlgorithm(roomId: String): String? {
|
override fun getEncryptionAlgorithm(roomId: String): String? {
|
||||||
return mCryptoStore.getRoomAlgorithm(roomId)
|
return cryptoStore.getRoomAlgorithm(roomId)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -588,7 +575,7 @@ internal class CryptoManager(
|
|||||||
* @return true if we should encrypt messages for invited users.
|
* @return true if we should encrypt messages for invited users.
|
||||||
*/
|
*/
|
||||||
override fun shouldEncryptForInvitedMembers(roomId: String): Boolean {
|
override fun shouldEncryptForInvitedMembers(roomId: String): Boolean {
|
||||||
return mCryptoStore.shouldEncryptForInvitedMembers(roomId)
|
return cryptoStore.shouldEncryptForInvitedMembers(roomId)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -612,15 +599,15 @@ internal class CryptoManager(
|
|||||||
}
|
}
|
||||||
|
|
||||||
val userIds = getRoomUserIds(roomId)
|
val userIds = getRoomUserIds(roomId)
|
||||||
var alg = synchronized(mRoomEncryptors) {
|
var alg = synchronized(roomEncryptors) {
|
||||||
mRoomEncryptors[roomId]
|
roomEncryptors[roomId]
|
||||||
}
|
}
|
||||||
if (null == alg) {
|
if (null == alg) {
|
||||||
val algorithm = getEncryptionAlgorithm(roomId)
|
val algorithm = getEncryptionAlgorithm(roomId)
|
||||||
if (null != algorithm) {
|
if (null != algorithm) {
|
||||||
if (setEncryptionInRoom(roomId, algorithm, false, userIds)) {
|
if (setEncryptionInRoom(roomId, algorithm, false, userIds)) {
|
||||||
synchronized(mRoomEncryptors) {
|
synchronized(roomEncryptors) {
|
||||||
alg = mRoomEncryptors[roomId]
|
alg = roomEncryptors[roomId]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -706,7 +693,7 @@ internal class CryptoManager(
|
|||||||
* @param timelineId the timeline id
|
* @param timelineId the timeline id
|
||||||
*/
|
*/
|
||||||
fun resetReplayAttackCheckInTimeline(timelineId: String) {
|
fun resetReplayAttackCheckInTimeline(timelineId: String) {
|
||||||
mOlmDevice.resetReplayAttackCheckInTimeline(timelineId)
|
olmDevice.resetReplayAttackCheckInTimeline(timelineId)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -718,7 +705,7 @@ internal class CryptoManager(
|
|||||||
if (event.getClearType() == EventType.ROOM_KEY || event.getClearType() == EventType.FORWARDED_ROOM_KEY) {
|
if (event.getClearType() == EventType.ROOM_KEY || event.getClearType() == EventType.FORWARDED_ROOM_KEY) {
|
||||||
onRoomKeyEvent(event)
|
onRoomKeyEvent(event)
|
||||||
} else if (event.getClearType() == EventType.ROOM_KEY_REQUEST) {
|
} else if (event.getClearType() == EventType.ROOM_KEY_REQUEST) {
|
||||||
mIncomingRoomKeyRequestManager.onRoomKeyRequestEvent(event)
|
incomingRoomKeyRequestManager.onRoomKeyRequestEvent(event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -743,7 +730,7 @@ internal class CryptoManager(
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
alg.onRoomKeyEvent(event, mKeysBackup)
|
alg.onRoomKeyEvent(event, keysBackup)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -759,7 +746,6 @@ internal class CryptoManager(
|
|||||||
.map { allLoaded ->
|
.map { allLoaded ->
|
||||||
val userIds = getRoomUserIds(roomId)
|
val userIds = getRoomUserIds(roomId)
|
||||||
setEncryptionInRoom(roomId, event.content!!["algorithm"] as String, true, userIds)
|
setEncryptionInRoom(roomId, event.content!!["algorithm"] as String, true, userIds)
|
||||||
allLoaded
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -789,8 +775,8 @@ internal class CryptoManager(
|
|||||||
private fun onRoomMembershipEvent(roomId: String, event: Event) {
|
private fun onRoomMembershipEvent(roomId: String, event: Event) {
|
||||||
val alg: IMXEncrypting?
|
val alg: IMXEncrypting?
|
||||||
|
|
||||||
synchronized(mRoomEncryptors) {
|
synchronized(roomEncryptors) {
|
||||||
alg = mRoomEncryptors[roomId]
|
alg = roomEncryptors[roomId]
|
||||||
}
|
}
|
||||||
|
|
||||||
if (null == alg) {
|
if (null == alg) {
|
||||||
@ -805,7 +791,7 @@ internal class CryptoManager(
|
|||||||
deviceListManager.startTrackingDeviceList(Arrays.asList(userId))
|
deviceListManager.startTrackingDeviceList(Arrays.asList(userId))
|
||||||
} else if (membership == Membership.INVITE
|
} else if (membership == Membership.INVITE
|
||||||
&& shouldEncryptForInvitedMembers(roomId)
|
&& shouldEncryptForInvitedMembers(roomId)
|
||||||
&& mCryptoConfig.mEnableEncryptionForInvitedMembers) {
|
&& cryptoConfig.mEnableEncryptionForInvitedMembers) {
|
||||||
// track the deviceList for this invited user.
|
// track the deviceList for this invited user.
|
||||||
// Caution: there's a big edge case here in that federated servers do not
|
// Caution: there's a big edge case here in that federated servers do not
|
||||||
// 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.
|
||||||
@ -820,7 +806,7 @@ internal class CryptoManager(
|
|||||||
val eventContent = event.content.toModel<RoomHistoryVisibilityContent>()
|
val eventContent = event.content.toModel<RoomHistoryVisibilityContent>()
|
||||||
|
|
||||||
eventContent?.historyVisibility?.let {
|
eventContent?.historyVisibility?.let {
|
||||||
mCryptoStore.setShouldEncryptForInvitedMembers(roomId, it != RoomHistoryVisibility.JOINED)
|
cryptoStore.setShouldEncryptForInvitedMembers(roomId, it != RoomHistoryVisibility.JOINED)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -837,15 +823,15 @@ internal class CryptoManager(
|
|||||||
// Sign it
|
// Sign it
|
||||||
val canonicalJson = MoshiProvider.getCanonicalJson(Map::class.java, getMyDevice().signalableJSONDictionary())
|
val canonicalJson = MoshiProvider.getCanonicalJson(Map::class.java, getMyDevice().signalableJSONDictionary())
|
||||||
|
|
||||||
getMyDevice().signatures = mObjectSigner.signObject(canonicalJson)
|
getMyDevice().signatures = objectSigner.signObject(canonicalJson)
|
||||||
|
|
||||||
// For now, we set the device id explicitly, as we may not be using the
|
// For now, we set the device id explicitly, as we may not be using the
|
||||||
// same one as used in login.
|
// same one as used in login.
|
||||||
mUploadKeysTask
|
uploadKeysTask
|
||||||
.configureWith(UploadKeysTask.Params(getMyDevice().toDeviceKeys(), null, getMyDevice().deviceId))
|
.configureWith(UploadKeysTask.Params(getMyDevice().toDeviceKeys(), null, getMyDevice().deviceId))
|
||||||
.executeOn(TaskThread.ENCRYPTION)
|
.executeOn(TaskThread.ENCRYPTION)
|
||||||
.dispatchTo(callback)
|
.dispatchTo(callback)
|
||||||
.executeBy(mTaskExecutor)
|
.executeBy(taskExecutor)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -870,7 +856,7 @@ internal class CryptoManager(
|
|||||||
|
|
||||||
val exportedSessions = ArrayList<MegolmSessionData>()
|
val exportedSessions = ArrayList<MegolmSessionData>()
|
||||||
|
|
||||||
val inboundGroupSessions = mCryptoStore.getInboundGroupSessions()
|
val inboundGroupSessions = cryptoStore.getInboundGroupSessions()
|
||||||
|
|
||||||
for (session in inboundGroupSessions) {
|
for (session in inboundGroupSessions) {
|
||||||
val megolmSessionData = session.exportKeys()
|
val megolmSessionData = session.exportKeys()
|
||||||
@ -941,7 +927,7 @@ internal class CryptoManager(
|
|||||||
|
|
||||||
Timber.v("## importRoomKeys : JSON parsing " + (t2 - t1) + " ms")
|
Timber.v("## importRoomKeys : JSON parsing " + (t2 - t1) + " ms")
|
||||||
|
|
||||||
mMegolmSessionDataImporter.handle(importedSessions, true, progressListener, callback)
|
megolmSessionDataImporter.handle(importedSessions, true, progressListener, callback)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -950,7 +936,7 @@ internal class CryptoManager(
|
|||||||
* @param warn true to warn when some unknown devices are detected.
|
* @param warn true to warn when some unknown devices are detected.
|
||||||
*/
|
*/
|
||||||
override fun setWarnOnUnknownDevices(warn: Boolean) {
|
override fun setWarnOnUnknownDevices(warn: Boolean) {
|
||||||
mWarnOnUnknownDevicesRepository.setWarnOnUnknownDevices(warn)
|
warnOnUnknownDevicesRepository.setWarnOnUnknownDevices(warn)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -992,7 +978,7 @@ internal class CryptoManager(
|
|||||||
* @param block true to unilaterally blacklist all
|
* @param block true to unilaterally blacklist all
|
||||||
*/
|
*/
|
||||||
override fun setGlobalBlacklistUnverifiedDevices(block: Boolean) {
|
override fun setGlobalBlacklistUnverifiedDevices(block: Boolean) {
|
||||||
mCryptoStore.setGlobalBlacklistUnverifiedDevices(block)
|
cryptoStore.setGlobalBlacklistUnverifiedDevices(block)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1003,7 +989,7 @@ internal class CryptoManager(
|
|||||||
* @return true to unilaterally blacklist all unverified devices.
|
* @return true to unilaterally blacklist all unverified devices.
|
||||||
*/
|
*/
|
||||||
override fun getGlobalBlacklistUnverifiedDevices(): Boolean {
|
override fun getGlobalBlacklistUnverifiedDevices(): Boolean {
|
||||||
return mCryptoStore.getGlobalBlacklistUnverifiedDevices()
|
return cryptoStore.getGlobalBlacklistUnverifiedDevices()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1017,7 +1003,7 @@ internal class CryptoManager(
|
|||||||
// TODO add this info in CryptoRoomEntity?
|
// TODO add this info in CryptoRoomEntity?
|
||||||
override fun isRoomBlacklistUnverifiedDevices(roomId: String?): Boolean {
|
override fun isRoomBlacklistUnverifiedDevices(roomId: String?): Boolean {
|
||||||
return if (null != roomId) {
|
return if (null != roomId) {
|
||||||
mCryptoStore.getRoomsListBlacklistUnverifiedDevices().contains(roomId)
|
cryptoStore.getRoomsListBlacklistUnverifiedDevices().contains(roomId)
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
@ -1030,7 +1016,7 @@ internal class CryptoManager(
|
|||||||
* @param add true to add the room id to the list, false to remove it.
|
* @param add true to add the room id to the list, false to remove it.
|
||||||
*/
|
*/
|
||||||
private fun setRoomBlacklistUnverifiedDevices(roomId: String, add: Boolean) {
|
private fun setRoomBlacklistUnverifiedDevices(roomId: String, add: Boolean) {
|
||||||
val roomIds = mCryptoStore.getRoomsListBlacklistUnverifiedDevices().toMutableList()
|
val roomIds = cryptoStore.getRoomsListBlacklistUnverifiedDevices().toMutableList()
|
||||||
|
|
||||||
if (add) {
|
if (add) {
|
||||||
if (!roomIds.contains(roomId)) {
|
if (!roomIds.contains(roomId)) {
|
||||||
@ -1040,7 +1026,7 @@ internal class CryptoManager(
|
|||||||
roomIds.remove(roomId)
|
roomIds.remove(roomId)
|
||||||
}
|
}
|
||||||
|
|
||||||
mCryptoStore.setRoomsListBlacklistUnverifiedDevices(roomIds)
|
cryptoStore.setRoomsListBlacklistUnverifiedDevices(roomIds)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1069,7 +1055,7 @@ internal class CryptoManager(
|
|||||||
* @param requestBody requestBody
|
* @param requestBody requestBody
|
||||||
*/
|
*/
|
||||||
override fun cancelRoomKeyRequest(requestBody: RoomKeyRequestBody) {
|
override fun cancelRoomKeyRequest(requestBody: RoomKeyRequestBody) {
|
||||||
mOutgoingRoomKeyRequestManager.cancelRoomKeyRequest(requestBody)
|
outgoingRoomKeyRequestManager.cancelRoomKeyRequest(requestBody)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1091,7 +1077,7 @@ internal class CryptoManager(
|
|||||||
requestBody.senderKey = senderKey
|
requestBody.senderKey = senderKey
|
||||||
requestBody.sessionId = sessionId
|
requestBody.sessionId = sessionId
|
||||||
|
|
||||||
mOutgoingRoomKeyRequestManager.resendRoomKeyRequest(requestBody)
|
outgoingRoomKeyRequestManager.resendRoomKeyRequest(requestBody)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1100,7 +1086,7 @@ internal class CryptoManager(
|
|||||||
* @param listener listener
|
* @param listener listener
|
||||||
*/
|
*/
|
||||||
override fun addRoomKeysRequestListener(listener: RoomKeysRequestListener) {
|
override fun addRoomKeysRequestListener(listener: RoomKeysRequestListener) {
|
||||||
mIncomingRoomKeyRequestManager.addRoomKeysRequestListener(listener)
|
incomingRoomKeyRequestManager.addRoomKeysRequestListener(listener)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1109,7 +1095,7 @@ internal class CryptoManager(
|
|||||||
* @param listener listener
|
* @param listener listener
|
||||||
*/
|
*/
|
||||||
fun removeRoomKeysRequestListener(listener: RoomKeysRequestListener) {
|
fun removeRoomKeysRequestListener(listener: RoomKeysRequestListener) {
|
||||||
mIncomingRoomKeyRequestManager.removeRoomKeysRequestListener(listener)
|
incomingRoomKeyRequestManager.removeRoomKeysRequestListener(listener)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1141,7 +1127,7 @@ internal class CryptoManager(
|
|||||||
* ========================================================================================== */
|
* ========================================================================================== */
|
||||||
|
|
||||||
override fun toString(): String {
|
override fun toString(): String {
|
||||||
return "CryptoManager of " + mCredentials.userId + " (" + mCredentials.deviceId + ")"
|
return "CryptoManager of " + credentials.userId + " (" + credentials.deviceId + ")"
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -171,38 +171,35 @@ internal class CryptoModule {
|
|||||||
// CryptoManager
|
// CryptoManager
|
||||||
scope(DefaultSession.SCOPE) {
|
scope(DefaultSession.SCOPE) {
|
||||||
CryptoManager(
|
CryptoManager(
|
||||||
mCredentials = get(),
|
credentials = get(),
|
||||||
mMyDeviceInfoHolder = get(),
|
myDeviceInfoHolder = get(),
|
||||||
mCryptoStore = get(),
|
cryptoStore = get(),
|
||||||
mOlmDevice = get(),
|
olmDevice = get(),
|
||||||
mCryptoConfig = get(),
|
cryptoConfig = get(),
|
||||||
deviceListManager = get(),
|
deviceListManager = get(),
|
||||||
mKeysBackup = get(),
|
keysBackup = get(),
|
||||||
mObjectSigner = get(),
|
objectSigner = get(),
|
||||||
mOneTimeKeysUploader = get(),
|
oneTimeKeysUploader = get(),
|
||||||
roomDecryptorProvider = get(),
|
roomDecryptorProvider = get(),
|
||||||
mSasVerificationService = get(),
|
sasVerificationService = get(),
|
||||||
mIncomingRoomKeyRequestManager = get(),
|
incomingRoomKeyRequestManager = get(),
|
||||||
mOutgoingRoomKeyRequestManager = get(),
|
outgoingRoomKeyRequestManager = get(),
|
||||||
mOlmManager = get(),
|
olmManager = get(),
|
||||||
mSetDeviceVerificationAction = get(),
|
setDeviceVerificationAction = get(),
|
||||||
mMegolmSessionDataImporter = get(),
|
megolmSessionDataImporter = get(),
|
||||||
mEnsureOlmSessionsForDevicesAction = get(),
|
ensureOlmSessionsForDevicesAction = get(),
|
||||||
mWarnOnUnknownDevicesRepository = get(),
|
warnOnUnknownDevicesRepository = get(),
|
||||||
mMXMegolmEncryptionFactory = get(),
|
megolmEncryptionFactory = get(),
|
||||||
mMXOlmEncryptionFactory = get(),
|
olmEncryptionFactory = get(),
|
||||||
mClaimOneTimeKeysForUsersDeviceTask = get(),
|
|
||||||
// Tasks
|
// Tasks
|
||||||
mDeleteDeviceTask = get(),
|
deleteDeviceTask = get(),
|
||||||
mGetDevicesTask = get(),
|
getDevicesTask = get(),
|
||||||
mGetKeyChangesTask = get(),
|
setDeviceNameTask = get(),
|
||||||
mSendToDeviceTask = get(),
|
uploadKeysTask = get(),
|
||||||
mSetDeviceNameTask = get(),
|
|
||||||
mUploadKeysTask = get(),
|
|
||||||
loadRoomMembersTask = get(),
|
loadRoomMembersTask = get(),
|
||||||
monarchy = get(),
|
monarchy = get(),
|
||||||
coroutineDispatchers = get(),
|
coroutineDispatchers = get(),
|
||||||
mTaskExecutor = get()
|
taskExecutor = get()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,27 +33,27 @@ import timber.log.Timber
|
|||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
// Legacy name: MXDeviceList
|
// Legacy name: MXDeviceList
|
||||||
internal class DeviceListManager(private val mCryptoStore: IMXCryptoStore,
|
internal class DeviceListManager(private val cryptoStore: IMXCryptoStore,
|
||||||
private val mOlmDevice: MXOlmDevice,
|
private val olmDevice: MXOlmDevice,
|
||||||
private val mSyncTokenStore: SyncTokenStore,
|
private val syncTokenStore: SyncTokenStore,
|
||||||
private val mCredentials: Credentials,
|
private val credentials: Credentials,
|
||||||
private val mDownloadKeysForUsersTask: DownloadKeysForUsersTask,
|
private val downloadKeysForUsersTask: DownloadKeysForUsersTask,
|
||||||
private val mTaskExecutor: TaskExecutor) {
|
private val taskExecutor: TaskExecutor) {
|
||||||
|
|
||||||
// keys in progress
|
// keys in progress
|
||||||
private val mUserKeyDownloadsInProgress = HashSet<String>()
|
private val userKeyDownloadsInProgress = HashSet<String>()
|
||||||
|
|
||||||
// HS not ready for retry
|
// HS not ready for retry
|
||||||
private val mNotReadyToRetryHS = HashSet<String>()
|
private val notReadyToRetryHS = HashSet<String>()
|
||||||
|
|
||||||
// indexed by UserId
|
// indexed by UserId
|
||||||
private val mPendingDownloadKeysRequestToken = HashMap<String, String>()
|
private val pendingDownloadKeysRequestToken = HashMap<String, String>()
|
||||||
|
|
||||||
// pending queues list
|
// pending queues list
|
||||||
private val mDownloadKeysQueues = ArrayList<DownloadKeysPromise>()
|
private val downloadKeysQueues = ArrayList<DownloadKeysPromise>()
|
||||||
|
|
||||||
// tells if there is a download keys request in progress
|
// tells if there is a download keys request in progress
|
||||||
private var mIsDownloadingKeys = false
|
private var isDownloadingKeys = false
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creator
|
* Creator
|
||||||
@ -78,7 +78,7 @@ internal class DeviceListManager(private val mCryptoStore: IMXCryptoStore,
|
|||||||
init {
|
init {
|
||||||
var isUpdated = false
|
var isUpdated = false
|
||||||
|
|
||||||
val deviceTrackingStatuses = mCryptoStore.getDeviceTrackingStatuses().toMutableMap()
|
val deviceTrackingStatuses = cryptoStore.getDeviceTrackingStatuses().toMutableMap()
|
||||||
for (userId in deviceTrackingStatuses.keys) {
|
for (userId in deviceTrackingStatuses.keys) {
|
||||||
val status = deviceTrackingStatuses[userId]!!
|
val status = deviceTrackingStatuses[userId]!!
|
||||||
|
|
||||||
@ -90,7 +90,7 @@ internal class DeviceListManager(private val mCryptoStore: IMXCryptoStore,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (isUpdated) {
|
if (isUpdated) {
|
||||||
mCryptoStore.saveDeviceTrackingStatuses(deviceTrackingStatuses)
|
cryptoStore.saveDeviceTrackingStatuses(deviceTrackingStatuses)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,8 +105,8 @@ internal class DeviceListManager(private val mCryptoStore: IMXCryptoStore,
|
|||||||
|
|
||||||
if (!TextUtils.isEmpty(userId) && userId.contains(":")) {
|
if (!TextUtils.isEmpty(userId) && userId.contains(":")) {
|
||||||
try {
|
try {
|
||||||
synchronized(mNotReadyToRetryHS) {
|
synchronized(notReadyToRetryHS) {
|
||||||
res = !mNotReadyToRetryHS.contains(userId.substring(userId.lastIndexOf(":") + 1))
|
res = !notReadyToRetryHS.contains(userId.substring(userId.lastIndexOf(":") + 1))
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Timber.e(e, "## canRetryKeysDownload() failed")
|
Timber.e(e, "## canRetryKeysDownload() failed")
|
||||||
@ -138,15 +138,15 @@ internal class DeviceListManager(private val mCryptoStore: IMXCryptoStore,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
synchronized(mUserKeyDownloadsInProgress) {
|
synchronized(userKeyDownloadsInProgress) {
|
||||||
filteredUserIds.removeAll(mUserKeyDownloadsInProgress)
|
filteredUserIds.removeAll(userKeyDownloadsInProgress)
|
||||||
mUserKeyDownloadsInProgress.addAll(userIds)
|
userKeyDownloadsInProgress.addAll(userIds)
|
||||||
// got some email addresses instead of matrix ids
|
// got some email addresses instead of matrix ids
|
||||||
mUserKeyDownloadsInProgress.removeAll(invalidUserIds)
|
userKeyDownloadsInProgress.removeAll(invalidUserIds)
|
||||||
userIds.removeAll(invalidUserIds)
|
userIds.removeAll(invalidUserIds)
|
||||||
}
|
}
|
||||||
|
|
||||||
mDownloadKeysQueues.add(DownloadKeysPromise(userIds, callback))
|
downloadKeysQueues.add(DownloadKeysPromise(userIds, callback))
|
||||||
|
|
||||||
return filteredUserIds
|
return filteredUserIds
|
||||||
} else {
|
} else {
|
||||||
@ -158,8 +158,8 @@ internal class DeviceListManager(private val mCryptoStore: IMXCryptoStore,
|
|||||||
* Clear the unavailable server lists
|
* Clear the unavailable server lists
|
||||||
*/
|
*/
|
||||||
private fun clearUnavailableServersList() {
|
private fun clearUnavailableServersList() {
|
||||||
synchronized(mNotReadyToRetryHS) {
|
synchronized(notReadyToRetryHS) {
|
||||||
mNotReadyToRetryHS.clear()
|
notReadyToRetryHS.clear()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -172,7 +172,7 @@ internal class DeviceListManager(private val mCryptoStore: IMXCryptoStore,
|
|||||||
fun startTrackingDeviceList(userIds: List<String>?) {
|
fun startTrackingDeviceList(userIds: List<String>?) {
|
||||||
if (null != userIds) {
|
if (null != userIds) {
|
||||||
var isUpdated = false
|
var isUpdated = false
|
||||||
val deviceTrackingStatuses = mCryptoStore.getDeviceTrackingStatuses().toMutableMap()
|
val deviceTrackingStatuses = cryptoStore.getDeviceTrackingStatuses().toMutableMap()
|
||||||
|
|
||||||
for (userId in userIds) {
|
for (userId in userIds) {
|
||||||
if (!deviceTrackingStatuses.containsKey(userId) || TRACKING_STATUS_NOT_TRACKED == deviceTrackingStatuses[userId]) {
|
if (!deviceTrackingStatuses.containsKey(userId) || TRACKING_STATUS_NOT_TRACKED == deviceTrackingStatuses[userId]) {
|
||||||
@ -183,7 +183,7 @@ internal class DeviceListManager(private val mCryptoStore: IMXCryptoStore,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (isUpdated) {
|
if (isUpdated) {
|
||||||
mCryptoStore.saveDeviceTrackingStatuses(deviceTrackingStatuses)
|
cryptoStore.saveDeviceTrackingStatuses(deviceTrackingStatuses)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -196,7 +196,7 @@ internal class DeviceListManager(private val mCryptoStore: IMXCryptoStore,
|
|||||||
*/
|
*/
|
||||||
fun handleDeviceListsChanges(changed: List<String>?, left: List<String>?) {
|
fun handleDeviceListsChanges(changed: List<String>?, left: List<String>?) {
|
||||||
var isUpdated = false
|
var isUpdated = false
|
||||||
val deviceTrackingStatuses = mCryptoStore.getDeviceTrackingStatuses().toMutableMap()
|
val deviceTrackingStatuses = cryptoStore.getDeviceTrackingStatuses().toMutableMap()
|
||||||
|
|
||||||
if (changed?.isNotEmpty() == true) {
|
if (changed?.isNotEmpty() == true) {
|
||||||
clearUnavailableServersList()
|
clearUnavailableServersList()
|
||||||
@ -223,7 +223,7 @@ internal class DeviceListManager(private val mCryptoStore: IMXCryptoStore,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (isUpdated) {
|
if (isUpdated) {
|
||||||
mCryptoStore.saveDeviceTrackingStatuses(deviceTrackingStatuses)
|
cryptoStore.saveDeviceTrackingStatuses(deviceTrackingStatuses)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -232,7 +232,7 @@ internal class DeviceListManager(private val mCryptoStore: IMXCryptoStore,
|
|||||||
* + update
|
* + update
|
||||||
*/
|
*/
|
||||||
fun invalidateAllDeviceLists() {
|
fun invalidateAllDeviceLists() {
|
||||||
handleDeviceListsChanges(ArrayList(mCryptoStore.getDeviceTrackingStatuses().keys), null)
|
handleDeviceListsChanges(ArrayList(cryptoStore.getDeviceTrackingStatuses().keys), null)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -242,19 +242,19 @@ internal class DeviceListManager(private val mCryptoStore: IMXCryptoStore,
|
|||||||
*/
|
*/
|
||||||
private fun onKeysDownloadFailed(userIds: List<String>?) {
|
private fun onKeysDownloadFailed(userIds: List<String>?) {
|
||||||
if (null != userIds) {
|
if (null != userIds) {
|
||||||
synchronized(mUserKeyDownloadsInProgress) {
|
synchronized(userKeyDownloadsInProgress) {
|
||||||
val deviceTrackingStatuses = mCryptoStore.getDeviceTrackingStatuses().toMutableMap()
|
val deviceTrackingStatuses = cryptoStore.getDeviceTrackingStatuses().toMutableMap()
|
||||||
|
|
||||||
for (userId in userIds) {
|
for (userId in userIds) {
|
||||||
mUserKeyDownloadsInProgress.remove(userId)
|
userKeyDownloadsInProgress.remove(userId)
|
||||||
deviceTrackingStatuses.put(userId, TRACKING_STATUS_PENDING_DOWNLOAD)
|
deviceTrackingStatuses.put(userId, TRACKING_STATUS_PENDING_DOWNLOAD)
|
||||||
}
|
}
|
||||||
|
|
||||||
mCryptoStore.saveDeviceTrackingStatuses(deviceTrackingStatuses)
|
cryptoStore.saveDeviceTrackingStatuses(deviceTrackingStatuses)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mIsDownloadingKeys = false
|
isDownloadingKeys = false
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -281,21 +281,21 @@ internal class DeviceListManager(private val mCryptoStore: IMXCryptoStore,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (statusCode == 503) {
|
if (statusCode == 503) {
|
||||||
synchronized(mNotReadyToRetryHS) {
|
synchronized(notReadyToRetryHS) {
|
||||||
mNotReadyToRetryHS.add(k)
|
notReadyToRetryHS.add(k)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val deviceTrackingStatuses = mCryptoStore.getDeviceTrackingStatuses().toMutableMap()
|
val deviceTrackingStatuses = cryptoStore.getDeviceTrackingStatuses().toMutableMap()
|
||||||
|
|
||||||
if (null != userIds) {
|
if (null != userIds) {
|
||||||
if (mDownloadKeysQueues.size > 0) {
|
if (downloadKeysQueues.size > 0) {
|
||||||
val promisesToRemove = ArrayList<DownloadKeysPromise>()
|
val promisesToRemove = ArrayList<DownloadKeysPromise>()
|
||||||
|
|
||||||
for (promise in mDownloadKeysQueues) {
|
for (promise in downloadKeysQueues) {
|
||||||
promise.mPendingUserIdsList.removeAll(userIds)
|
promise.mPendingUserIdsList.removeAll(userIds)
|
||||||
|
|
||||||
if (promise.mPendingUserIdsList.size == 0) {
|
if (promise.mPendingUserIdsList.size == 0) {
|
||||||
@ -303,7 +303,7 @@ internal class DeviceListManager(private val mCryptoStore: IMXCryptoStore,
|
|||||||
val usersDevicesInfoMap = MXUsersDevicesMap<MXDeviceInfo>()
|
val usersDevicesInfoMap = MXUsersDevicesMap<MXDeviceInfo>()
|
||||||
|
|
||||||
for (userId in promise.mUserIdsList) {
|
for (userId in promise.mUserIdsList) {
|
||||||
val devices = mCryptoStore.getUserDevices(userId)
|
val devices = cryptoStore.getUserDevices(userId)
|
||||||
if (null == devices) {
|
if (null == devices) {
|
||||||
if (canRetryKeysDownload(userId)) {
|
if (canRetryKeysDownload(userId)) {
|
||||||
deviceTrackingStatuses.put(userId, TRACKING_STATUS_PENDING_DOWNLOAD)
|
deviceTrackingStatuses.put(userId, TRACKING_STATUS_PENDING_DOWNLOAD)
|
||||||
@ -336,17 +336,17 @@ internal class DeviceListManager(private val mCryptoStore: IMXCryptoStore,
|
|||||||
promisesToRemove.add(promise)
|
promisesToRemove.add(promise)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mDownloadKeysQueues.removeAll(promisesToRemove)
|
downloadKeysQueues.removeAll(promisesToRemove)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (userId in userIds) {
|
for (userId in userIds) {
|
||||||
mUserKeyDownloadsInProgress.remove(userId)
|
userKeyDownloadsInProgress.remove(userId)
|
||||||
}
|
}
|
||||||
|
|
||||||
mCryptoStore.saveDeviceTrackingStatuses(deviceTrackingStatuses)
|
cryptoStore.saveDeviceTrackingStatuses(deviceTrackingStatuses)
|
||||||
}
|
}
|
||||||
|
|
||||||
mIsDownloadingKeys = false
|
isDownloadingKeys = false
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -372,14 +372,14 @@ internal class DeviceListManager(private val mCryptoStore: IMXCryptoStore,
|
|||||||
downloadUsers.addAll(userIds)
|
downloadUsers.addAll(userIds)
|
||||||
} else {
|
} else {
|
||||||
for (userId in userIds) {
|
for (userId in userIds) {
|
||||||
val status = mCryptoStore.getDeviceTrackingStatus(userId, TRACKING_STATUS_NOT_TRACKED)
|
val status = cryptoStore.getDeviceTrackingStatus(userId, TRACKING_STATUS_NOT_TRACKED)
|
||||||
|
|
||||||
// downloading keys ->the keys download won't be triggered twice but the callback requires the dedicated keys
|
// downloading keys ->the keys download won't be triggered twice but the callback requires the dedicated keys
|
||||||
// not yet retrieved
|
// not yet retrieved
|
||||||
if (mUserKeyDownloadsInProgress.contains(userId) || TRACKING_STATUS_UP_TO_DATE != status && TRACKING_STATUS_UNREACHABLE_SERVER != status) {
|
if (userKeyDownloadsInProgress.contains(userId) || TRACKING_STATUS_UP_TO_DATE != status && TRACKING_STATUS_UNREACHABLE_SERVER != status) {
|
||||||
downloadUsers.add(userId)
|
downloadUsers.add(userId)
|
||||||
} else {
|
} else {
|
||||||
val devices = mCryptoStore.getUserDevices(userId)
|
val devices = cryptoStore.getUserDevices(userId)
|
||||||
|
|
||||||
// should always be true
|
// should always be true
|
||||||
if (null != devices) {
|
if (null != devices) {
|
||||||
@ -444,7 +444,7 @@ internal class DeviceListManager(private val mCryptoStore: IMXCryptoStore,
|
|||||||
// return
|
// return
|
||||||
//}
|
//}
|
||||||
|
|
||||||
mIsDownloadingKeys = true
|
isDownloadingKeys = true
|
||||||
|
|
||||||
// track the race condition while sending requests
|
// track the race condition while sending requests
|
||||||
// we defines a tag for each request
|
// we defines a tag for each request
|
||||||
@ -452,11 +452,11 @@ internal class DeviceListManager(private val mCryptoStore: IMXCryptoStore,
|
|||||||
val downloadToken = filteredUsers.hashCode().toString() + " " + System.currentTimeMillis()
|
val downloadToken = filteredUsers.hashCode().toString() + " " + System.currentTimeMillis()
|
||||||
|
|
||||||
for (userId in filteredUsers) {
|
for (userId in filteredUsers) {
|
||||||
mPendingDownloadKeysRequestToken[userId] = downloadToken
|
pendingDownloadKeysRequestToken[userId] = downloadToken
|
||||||
}
|
}
|
||||||
|
|
||||||
mDownloadKeysForUsersTask
|
downloadKeysForUsersTask
|
||||||
.configureWith(DownloadKeysForUsersTask.Params(filteredUsers, mSyncTokenStore.getLastToken()))
|
.configureWith(DownloadKeysForUsersTask.Params(filteredUsers, syncTokenStore.getLastToken()))
|
||||||
.dispatchTo(object : MatrixCallback<KeysQueryResponse> {
|
.dispatchTo(object : MatrixCallback<KeysQueryResponse> {
|
||||||
override fun onSuccess(data: KeysQueryResponse) {
|
override fun onSuccess(data: KeysQueryResponse) {
|
||||||
CryptoAsyncHelper.getEncryptBackgroundHandler().post {
|
CryptoAsyncHelper.getEncryptBackgroundHandler().post {
|
||||||
@ -465,7 +465,7 @@ internal class DeviceListManager(private val mCryptoStore: IMXCryptoStore,
|
|||||||
|
|
||||||
for (userId in userIdsList) {
|
for (userId in userIdsList) {
|
||||||
// test if the response is the latest request one
|
// test if the response is the latest request one
|
||||||
if (!TextUtils.equals(mPendingDownloadKeysRequestToken[userId], downloadToken)) {
|
if (!TextUtils.equals(pendingDownloadKeysRequestToken[userId], downloadToken)) {
|
||||||
Timber.e("## doKeyDownloadForUsers() : Another update in the queue for "
|
Timber.e("## doKeyDownloadForUsers() : Another update in the queue for "
|
||||||
+ userId + " not marking up-to-date")
|
+ userId + " not marking up-to-date")
|
||||||
filteredUsers.remove(userId)
|
filteredUsers.remove(userId)
|
||||||
@ -486,12 +486,12 @@ internal class DeviceListManager(private val mCryptoStore: IMXCryptoStore,
|
|||||||
//}
|
//}
|
||||||
|
|
||||||
// Get the potential previously store device keys for this device
|
// Get the potential previously store device keys for this device
|
||||||
val previouslyStoredDeviceKeys = mCryptoStore.getUserDevice(deviceId, userId)
|
val previouslyStoredDeviceKeys = cryptoStore.getUserDevice(deviceId, userId)
|
||||||
val deviceInfo = mutableDevices[deviceId]
|
val deviceInfo = mutableDevices[deviceId]
|
||||||
|
|
||||||
// in some race conditions (like unit tests)
|
// in some race conditions (like unit tests)
|
||||||
// the self device must be seen as verified
|
// the self device must be seen as verified
|
||||||
if (TextUtils.equals(deviceInfo!!.deviceId, mCredentials.deviceId) && TextUtils.equals(userId, mCredentials.userId)) {
|
if (TextUtils.equals(deviceInfo!!.deviceId, credentials.deviceId) && TextUtils.equals(userId, credentials.userId)) {
|
||||||
deviceInfo.mVerified = MXDeviceInfo.DEVICE_VERIFICATION_VERIFIED
|
deviceInfo.mVerified = MXDeviceInfo.DEVICE_VERIFICATION_VERIFIED
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -514,11 +514,11 @@ internal class DeviceListManager(private val mCryptoStore: IMXCryptoStore,
|
|||||||
|
|
||||||
// Update the store
|
// Update the store
|
||||||
// Note that devices which aren't in the response will be removed from the stores
|
// Note that devices which aren't in the response will be removed from the stores
|
||||||
mCryptoStore.storeUserDevices(userId, mutableDevices)
|
cryptoStore.storeUserDevices(userId, mutableDevices)
|
||||||
}
|
}
|
||||||
|
|
||||||
// the response is the latest request one
|
// the response is the latest request one
|
||||||
mPendingDownloadKeysRequestToken.remove(userId)
|
pendingDownloadKeysRequestToken.remove(userId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -532,12 +532,12 @@ internal class DeviceListManager(private val mCryptoStore: IMXCryptoStore,
|
|||||||
|
|
||||||
// test if the response is the latest request one
|
// test if the response is the latest request one
|
||||||
for (userId in userIdsList) {
|
for (userId in userIdsList) {
|
||||||
if (!TextUtils.equals(mPendingDownloadKeysRequestToken[userId], downloadToken)) {
|
if (!TextUtils.equals(pendingDownloadKeysRequestToken[userId], downloadToken)) {
|
||||||
Timber.e("## doKeyDownloadForUsers() : Another update in the queue for $userId not marking up-to-date")
|
Timber.e("## doKeyDownloadForUsers() : Another update in the queue for $userId not marking up-to-date")
|
||||||
filteredUsers.remove(userId)
|
filteredUsers.remove(userId)
|
||||||
} else {
|
} else {
|
||||||
// the response is the latest request one
|
// the response is the latest request one
|
||||||
mPendingDownloadKeysRequestToken.remove(userId)
|
pendingDownloadKeysRequestToken.remove(userId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -553,7 +553,7 @@ internal class DeviceListManager(private val mCryptoStore: IMXCryptoStore,
|
|||||||
callback?.onFailure(failure)
|
callback?.onFailure(failure)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.executeBy(mTaskExecutor)
|
.executeBy(taskExecutor)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -619,7 +619,7 @@ internal class DeviceListManager(private val mCryptoStore: IMXCryptoStore,
|
|||||||
var errorMessage: String? = null
|
var errorMessage: String? = null
|
||||||
|
|
||||||
try {
|
try {
|
||||||
mOlmDevice.verifySignature(signKey, deviceKeys.signalableJSONDictionary(), signature)
|
olmDevice.verifySignature(signKey, deviceKeys.signalableJSONDictionary(), signature)
|
||||||
isVerified = true
|
isVerified = true
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
errorMessage = e.message
|
errorMessage = e.message
|
||||||
@ -658,7 +658,7 @@ internal class DeviceListManager(private val mCryptoStore: IMXCryptoStore,
|
|||||||
fun refreshOutdatedDeviceLists() {
|
fun refreshOutdatedDeviceLists() {
|
||||||
val users = ArrayList<String>()
|
val users = ArrayList<String>()
|
||||||
|
|
||||||
val deviceTrackingStatuses = mCryptoStore.getDeviceTrackingStatuses().toMutableMap()
|
val deviceTrackingStatuses = cryptoStore.getDeviceTrackingStatuses().toMutableMap()
|
||||||
|
|
||||||
for (userId in deviceTrackingStatuses.keys) {
|
for (userId in deviceTrackingStatuses.keys) {
|
||||||
if (TRACKING_STATUS_PENDING_DOWNLOAD == deviceTrackingStatuses[userId]) {
|
if (TRACKING_STATUS_PENDING_DOWNLOAD == deviceTrackingStatuses[userId]) {
|
||||||
@ -670,7 +670,7 @@ internal class DeviceListManager(private val mCryptoStore: IMXCryptoStore,
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mIsDownloadingKeys) {
|
if (isDownloadingKeys) {
|
||||||
// request already in progress - do nothing. (We will automatically
|
// request already in progress - do nothing. (We will automatically
|
||||||
// make another request if there are more users with outdated
|
// make another request if there are more users with outdated
|
||||||
// device lists when the current request completes).
|
// device lists when the current request completes).
|
||||||
@ -686,7 +686,7 @@ internal class DeviceListManager(private val mCryptoStore: IMXCryptoStore,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mCryptoStore.saveDeviceTrackingStatuses(deviceTrackingStatuses)
|
cryptoStore.saveDeviceTrackingStatuses(deviceTrackingStatuses)
|
||||||
|
|
||||||
doKeyDownloadForUsers(users, object : MatrixCallback<MXUsersDevicesMap<MXDeviceInfo>> {
|
doKeyDownloadForUsers(users, object : MatrixCallback<MXUsersDevicesMap<MXDeviceInfo>> {
|
||||||
override fun onSuccess(data: MXUsersDevicesMap<MXDeviceInfo>) {
|
override fun onSuccess(data: MXUsersDevicesMap<MXDeviceInfo>) {
|
||||||
|
@ -67,9 +67,9 @@ internal class MXMegolmDecryption(private val mCredentials: Credentials,
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Throws(MXDecryptionException::class)
|
@Throws(MXDecryptionException::class)
|
||||||
|
|
||||||
private fun decryptEvent(event: Event, timeline: String, requestKeysOnFail: Boolean): MXEventDecryptionResult? {
|
private fun decryptEvent(event: Event, timeline: String, requestKeysOnFail: Boolean): MXEventDecryptionResult? {
|
||||||
val encryptedEventContent = event.content.toModel<EncryptedEventContent>()!!
|
val encryptedEventContent = event.content.toModel<EncryptedEventContent>()!!
|
||||||
|
|
||||||
if (TextUtils.isEmpty(encryptedEventContent.senderKey) || TextUtils.isEmpty(encryptedEventContent.sessionId) || TextUtils.isEmpty(encryptedEventContent.ciphertext)) {
|
if (TextUtils.isEmpty(encryptedEventContent.senderKey) || TextUtils.isEmpty(encryptedEventContent.sessionId) || TextUtils.isEmpty(encryptedEventContent.ciphertext)) {
|
||||||
throw MXDecryptionException(MXCryptoError(MXCryptoError.MISSING_FIELDS_ERROR_CODE,
|
throw MXDecryptionException(MXCryptoError(MXCryptoError.MISSING_FIELDS_ERROR_CODE,
|
||||||
MXCryptoError.UNABLE_TO_DECRYPT, MXCryptoError.MISSING_FIELDS_REASON))
|
MXCryptoError.UNABLE_TO_DECRYPT, MXCryptoError.MISSING_FIELDS_REASON))
|
||||||
|
@ -499,7 +499,7 @@ internal class MXMegolmEncryption(
|
|||||||
CryptoAsyncHelper.getUiHandler().post {
|
CryptoAsyncHelper.getUiHandler().post {
|
||||||
// Check if any of these devices are not yet known to the user.
|
// 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 so, warn the user so they can verify or ignore.
|
||||||
if (0 != unknownDevices.map.size) {
|
if (unknownDevices.map.isNotEmpty()) {
|
||||||
callback.onFailure(Failure.CryptoError(MXCryptoError(MXCryptoError.UNKNOWN_DEVICES_CODE,
|
callback.onFailure(Failure.CryptoError(MXCryptoError(MXCryptoError.UNKNOWN_DEVICES_CODE,
|
||||||
MXCryptoError.UNABLE_TO_ENCRYPT, MXCryptoError.UNKNOWN_DEVICES_REASON, unknownDevices)))
|
MXCryptoError.UNABLE_TO_ENCRYPT, MXCryptoError.UNKNOWN_DEVICES_REASON, unknownDevices)))
|
||||||
} else {
|
} else {
|
||||||
|
@ -54,9 +54,9 @@ internal class UploadContentWorker(context: Context, params: WorkerParameters)
|
|||||||
|
|
||||||
override suspend fun doWork(): Result {
|
override suspend fun doWork(): Result {
|
||||||
val params = WorkerParamsFactory.fromData<Params>(inputData)
|
val params = WorkerParamsFactory.fromData<Params>(inputData)
|
||||||
?: return Result.failure()
|
?: return Result.success()
|
||||||
|
|
||||||
val eventId = params.event.eventId ?: return Result.failure()
|
val eventId = params.event.eventId ?: return Result.success()
|
||||||
val attachment = params.attachment
|
val attachment = params.attachment
|
||||||
|
|
||||||
val thumbnailData = ThumbnailExtractor.extractThumbnail(params.attachment)
|
val thumbnailData = ThumbnailExtractor.extractThumbnail(params.attachment)
|
||||||
@ -96,7 +96,7 @@ internal class UploadContentWorker(context: Context, params: WorkerParameters)
|
|||||||
|
|
||||||
private fun handleFailure(params: Params): Result {
|
private fun handleFailure(params: Params): Result {
|
||||||
contentUploadProgressTracker.setFailure(params.event.eventId!!)
|
contentUploadProgressTracker.setFailure(params.event.eventId!!)
|
||||||
return Result.failure()
|
return Result.success()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleSuccess(params: Params,
|
private fun handleSuccess(params: Params,
|
||||||
|
@ -44,11 +44,11 @@ internal class EncryptEventWorker(context: Context, params: WorkerParameters)
|
|||||||
override fun doWork(): Result {
|
override fun doWork(): Result {
|
||||||
|
|
||||||
val params = WorkerParamsFactory.fromData<Params>(inputData)
|
val params = WorkerParamsFactory.fromData<Params>(inputData)
|
||||||
?: return Result.failure()
|
?: return Result.success()
|
||||||
|
|
||||||
val localEvent = params.event
|
val localEvent = params.event
|
||||||
if (localEvent.eventId == null) {
|
if (localEvent.eventId == null) {
|
||||||
return Result.failure()
|
return Result.success()
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO Better async handling
|
// TODO Better async handling
|
||||||
@ -78,7 +78,7 @@ internal class EncryptEventWorker(context: Context, params: WorkerParameters)
|
|||||||
val safeResult = result
|
val safeResult = result
|
||||||
// TODO Update local echo
|
// TODO Update local echo
|
||||||
return if (error != null) {
|
return if (error != null) {
|
||||||
Result.failure() // TODO Pass error!!)
|
Result.success() // TODO Pass error!!)
|
||||||
} else if (safeResult != null) {
|
} else if (safeResult != null) {
|
||||||
val encryptedEvent = localEvent.copy(
|
val encryptedEvent = localEvent.copy(
|
||||||
type = safeResult.mEventType,
|
type = safeResult.mEventType,
|
||||||
@ -88,7 +88,7 @@ internal class EncryptEventWorker(context: Context, params: WorkerParameters)
|
|||||||
Result.success(WorkerParamsFactory.toData(nextWorkerParams))
|
Result.success(WorkerParamsFactory.toData(nextWorkerParams))
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
Result.failure()
|
Result.success()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,11 +20,20 @@ import android.content.Context
|
|||||||
import androidx.work.Worker
|
import androidx.work.Worker
|
||||||
import androidx.work.WorkerParameters
|
import androidx.work.WorkerParameters
|
||||||
import com.squareup.moshi.JsonClass
|
import com.squareup.moshi.JsonClass
|
||||||
|
import com.zhuinden.monarchy.Monarchy
|
||||||
import im.vector.matrix.android.api.session.events.model.Event
|
import im.vector.matrix.android.api.session.events.model.Event
|
||||||
|
import im.vector.matrix.android.api.session.room.send.SendState
|
||||||
|
import im.vector.matrix.android.internal.database.helper.addSendingEvent
|
||||||
|
import im.vector.matrix.android.internal.database.model.ChunkEntity
|
||||||
|
import im.vector.matrix.android.internal.database.model.RoomEntity
|
||||||
|
import im.vector.matrix.android.internal.database.query.find
|
||||||
|
import im.vector.matrix.android.internal.database.query.findLastLiveChunkFromRoom
|
||||||
|
import im.vector.matrix.android.internal.database.query.where
|
||||||
import im.vector.matrix.android.internal.di.MatrixKoinComponent
|
import im.vector.matrix.android.internal.di.MatrixKoinComponent
|
||||||
import im.vector.matrix.android.internal.network.executeRequest
|
import im.vector.matrix.android.internal.network.executeRequest
|
||||||
import im.vector.matrix.android.internal.session.room.RoomAPI
|
import im.vector.matrix.android.internal.session.room.RoomAPI
|
||||||
import im.vector.matrix.android.internal.util.WorkerParamsFactory
|
import im.vector.matrix.android.internal.util.WorkerParamsFactory
|
||||||
|
import im.vector.matrix.android.internal.util.tryTransactionAsync
|
||||||
import org.koin.standalone.inject
|
import org.koin.standalone.inject
|
||||||
|
|
||||||
internal class SendEventWorker(context: Context, params: WorkerParameters)
|
internal class SendEventWorker(context: Context, params: WorkerParameters)
|
||||||
@ -38,25 +47,35 @@ internal class SendEventWorker(context: Context, params: WorkerParameters)
|
|||||||
)
|
)
|
||||||
|
|
||||||
private val roomAPI by inject<RoomAPI>()
|
private val roomAPI by inject<RoomAPI>()
|
||||||
|
private val monarchy by inject<Monarchy>()
|
||||||
|
|
||||||
override fun doWork(): Result {
|
override fun doWork(): Result {
|
||||||
|
|
||||||
val params = WorkerParamsFactory.fromData<Params>(inputData)
|
val params = WorkerParamsFactory.fromData<Params>(inputData)
|
||||||
?: return Result.failure()
|
?: return Result.success()
|
||||||
|
|
||||||
val localEvent = params.event
|
val event = params.event
|
||||||
if (localEvent.eventId == null) {
|
if (event.eventId == null) {
|
||||||
return Result.failure()
|
return Result.success()
|
||||||
}
|
}
|
||||||
|
|
||||||
val result = executeRequest<SendResponse> {
|
val result = executeRequest<SendResponse> {
|
||||||
apiCall = roomAPI.send(
|
apiCall = roomAPI.send(
|
||||||
localEvent.eventId,
|
event.eventId,
|
||||||
params.roomId,
|
params.roomId,
|
||||||
localEvent.type,
|
event.type,
|
||||||
localEvent.content
|
event.content
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
return result.fold({ Result.failure() }, { Result.success() })
|
return result.fold(
|
||||||
|
{
|
||||||
|
//TODO export that in a localEchoRepository
|
||||||
|
monarchy.tryTransactionAsync { realm ->
|
||||||
|
val roomEntity = RoomEntity.where(realm, roomId = params.roomId).findFirst()
|
||||||
|
val eventEntity = roomEntity?.sendingTimelineEvents?.find(event.eventId)
|
||||||
|
eventEntity?.sendState = SendState.UNSENT
|
||||||
|
}
|
||||||
|
Result.success() }
|
||||||
|
, { Result.success() })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -49,7 +49,7 @@ internal class CryptoSyncHandler(private val cryptoManager: CryptoManager,
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun onSyncCompleted(syncResponse: SyncResponse, fromToken: String?, catchingUp: Boolean) {
|
fun onSyncCompleted(syncResponse: SyncResponse, fromToken: String?, catchingUp: Boolean) {
|
||||||
cryptoManager.onSyncCompleted(syncResponse, fromToken, catchingUp)
|
cryptoManager.onSyncCompleted(syncResponse)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user