mirror of
https://github.com/SchildiChat/SchildiChat-android.git
synced 2025-02-05 13:37:36 +01:00
Merge pull request #726 from vector-im/feature/sign_x_stabilization
Registration stabilization
This commit is contained in:
commit
9fb50dde32
@ -16,6 +16,8 @@ Other changes:
|
||||
Bugfix 🐛:
|
||||
- Do not show long click help if only invitation are displayed
|
||||
- Fix emoji filtering not working
|
||||
- Fix issue of closing Realm in another thread (#725)
|
||||
- Attempt to properly cancel the crypto module when user signs out (#724)
|
||||
|
||||
Translations 🗣:
|
||||
-
|
||||
|
@ -17,6 +17,7 @@
|
||||
package im.vector.matrix.android.api.session.file
|
||||
|
||||
import im.vector.matrix.android.api.MatrixCallback
|
||||
import im.vector.matrix.android.api.util.Cancelable
|
||||
import im.vector.matrix.android.internal.crypto.attachments.ElementToDecrypt
|
||||
import java.io.File
|
||||
|
||||
@ -47,5 +48,5 @@ interface FileService {
|
||||
fileName: String,
|
||||
url: String?,
|
||||
elementToDecrypt: ElementToDecrypt?,
|
||||
callback: MatrixCallback<File>)
|
||||
callback: MatrixCallback<File>): Cancelable
|
||||
}
|
||||
|
@ -22,6 +22,8 @@ import im.vector.matrix.android.internal.database.awaitTransaction
|
||||
import im.vector.matrix.android.internal.di.AuthDatabase
|
||||
import io.realm.Realm
|
||||
import io.realm.RealmConfiguration
|
||||
import io.realm.exceptions.RealmPrimaryKeyConstraintException
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
internal class RealmSessionParamsStore @Inject constructor(private val mapper: SessionParamsMapper,
|
||||
@ -63,7 +65,12 @@ internal class RealmSessionParamsStore @Inject constructor(private val mapper: S
|
||||
awaitTransaction(realmConfiguration) {
|
||||
val entity = mapper.map(sessionParams)
|
||||
if (entity != null) {
|
||||
it.insert(entity)
|
||||
try {
|
||||
it.insert(entity)
|
||||
} catch (e: RealmPrimaryKeyConstraintException) {
|
||||
Timber.e(e, "Something wrong happened during previous session creation. Override with new credentials")
|
||||
it.insertOrUpdate(entity)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -37,6 +37,8 @@ import im.vector.matrix.android.internal.session.SessionScope
|
||||
import im.vector.matrix.android.internal.session.cache.ClearCacheTask
|
||||
import im.vector.matrix.android.internal.session.cache.RealmClearCacheTask
|
||||
import io.realm.RealmConfiguration
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
import retrofit2.Retrofit
|
||||
import java.io.File
|
||||
|
||||
@ -66,6 +68,13 @@ internal abstract class CryptoModule {
|
||||
.build()
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
@Provides
|
||||
@SessionScope
|
||||
fun providesCryptoCoroutineScope(): CoroutineScope {
|
||||
return CoroutineScope(SupervisorJob())
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
@Provides
|
||||
@CryptoDatabase
|
||||
|
@ -132,7 +132,8 @@ internal class DefaultCryptoService @Inject constructor(
|
||||
private val loadRoomMembersTask: LoadRoomMembersTask,
|
||||
private val monarchy: Monarchy,
|
||||
private val coroutineDispatchers: MatrixCoroutineDispatchers,
|
||||
private val taskExecutor: TaskExecutor
|
||||
private val taskExecutor: TaskExecutor,
|
||||
private val cryptoCoroutineScope: CoroutineScope
|
||||
) : CryptoService {
|
||||
|
||||
private val uiHandler = Handler(Looper.getMainLooper())
|
||||
@ -243,7 +244,8 @@ internal class DefaultCryptoService @Inject constructor(
|
||||
return
|
||||
}
|
||||
isStarting.set(true)
|
||||
GlobalScope.launch(coroutineDispatchers.crypto) {
|
||||
|
||||
cryptoCoroutineScope.launch(coroutineDispatchers.crypto) {
|
||||
internalStart(isInitialSync)
|
||||
}
|
||||
}
|
||||
@ -269,10 +271,9 @@ internal class DefaultCryptoService @Inject constructor(
|
||||
isStarted.set(true)
|
||||
},
|
||||
{
|
||||
Timber.e("Start failed: $it")
|
||||
delay(1000)
|
||||
isStarting.set(false)
|
||||
internalStart(isInitialSync)
|
||||
isStarted.set(false)
|
||||
Timber.e(it, "Start failed")
|
||||
}
|
||||
)
|
||||
}
|
||||
@ -281,9 +282,12 @@ internal class DefaultCryptoService @Inject constructor(
|
||||
* Close the crypto
|
||||
*/
|
||||
fun close() = runBlocking(coroutineDispatchers.crypto) {
|
||||
cryptoCoroutineScope.coroutineContext.cancelChildren(CancellationException("Closing crypto module"))
|
||||
|
||||
outgoingRoomKeyRequestManager.stop()
|
||||
|
||||
olmDevice.release()
|
||||
cryptoStore.close()
|
||||
outgoingRoomKeyRequestManager.stop()
|
||||
}
|
||||
|
||||
// Aways enabled on RiotX
|
||||
@ -305,19 +309,21 @@ internal class DefaultCryptoService @Inject constructor(
|
||||
* @param syncResponse the syncResponse
|
||||
*/
|
||||
fun onSyncCompleted(syncResponse: SyncResponse) {
|
||||
GlobalScope.launch(coroutineDispatchers.crypto) {
|
||||
if (syncResponse.deviceLists != null) {
|
||||
deviceListManager.handleDeviceListsChanges(syncResponse.deviceLists.changed, syncResponse.deviceLists.left)
|
||||
}
|
||||
if (syncResponse.deviceOneTimeKeysCount != null) {
|
||||
val currentCount = syncResponse.deviceOneTimeKeysCount.signedCurve25519 ?: 0
|
||||
oneTimeKeysUploader.updateOneTimeKeyCount(currentCount)
|
||||
}
|
||||
if (isStarted()) {
|
||||
// Make sure we process to-device messages before generating new one-time-keys #2782
|
||||
deviceListManager.refreshOutdatedDeviceLists()
|
||||
oneTimeKeysUploader.maybeUploadOneTimeKeys()
|
||||
incomingRoomKeyRequestManager.processReceivedRoomKeyRequests()
|
||||
cryptoCoroutineScope.launch(coroutineDispatchers.crypto) {
|
||||
runCatching {
|
||||
if (syncResponse.deviceLists != null) {
|
||||
deviceListManager.handleDeviceListsChanges(syncResponse.deviceLists.changed, syncResponse.deviceLists.left)
|
||||
}
|
||||
if (syncResponse.deviceOneTimeKeysCount != null) {
|
||||
val currentCount = syncResponse.deviceOneTimeKeysCount.signedCurve25519 ?: 0
|
||||
oneTimeKeysUploader.updateOneTimeKeyCount(currentCount)
|
||||
}
|
||||
if (isStarted()) {
|
||||
// Make sure we process to-device messages before generating new one-time-keys #2782
|
||||
deviceListManager.refreshOutdatedDeviceLists()
|
||||
oneTimeKeysUploader.maybeUploadOneTimeKeys()
|
||||
incomingRoomKeyRequestManager.processReceivedRoomKeyRequests()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -511,7 +517,7 @@ internal class DefaultCryptoService @Inject constructor(
|
||||
eventType: String,
|
||||
roomId: String,
|
||||
callback: MatrixCallback<MXEncryptEventContentResult>) {
|
||||
GlobalScope.launch(coroutineDispatchers.crypto) {
|
||||
cryptoCoroutineScope.launch(coroutineDispatchers.crypto) {
|
||||
if (!isStarted()) {
|
||||
Timber.v("## encryptEventContent() : wait after e2e init")
|
||||
internalStart(false)
|
||||
@ -571,7 +577,7 @@ internal class DefaultCryptoService @Inject constructor(
|
||||
* @param callback the callback to return data or null
|
||||
*/
|
||||
override fun decryptEventAsync(event: Event, timeline: String, callback: MatrixCallback<MXEventDecryptionResult>) {
|
||||
GlobalScope.launch {
|
||||
cryptoCoroutineScope.launch {
|
||||
val result = runCatching {
|
||||
withContext(coroutineDispatchers.crypto) {
|
||||
internalDecryptEvent(event, timeline)
|
||||
@ -621,7 +627,7 @@ internal class DefaultCryptoService @Inject constructor(
|
||||
* @param event the event
|
||||
*/
|
||||
fun onToDeviceEvent(event: Event) {
|
||||
GlobalScope.launch(coroutineDispatchers.crypto) {
|
||||
cryptoCoroutineScope.launch(coroutineDispatchers.crypto) {
|
||||
when (event.getClearType()) {
|
||||
EventType.ROOM_KEY, EventType.FORWARDED_ROOM_KEY -> {
|
||||
onRoomKeyEvent(event)
|
||||
@ -661,7 +667,7 @@ internal class DefaultCryptoService @Inject constructor(
|
||||
* @param event the encryption event.
|
||||
*/
|
||||
private fun onRoomEncryptionEvent(roomId: String, event: Event) {
|
||||
GlobalScope.launch(coroutineDispatchers.crypto) {
|
||||
cryptoCoroutineScope.launch(coroutineDispatchers.crypto) {
|
||||
val params = LoadRoomMembersTask.Params(roomId)
|
||||
try {
|
||||
loadRoomMembersTask.execute(params)
|
||||
@ -753,7 +759,7 @@ internal class DefaultCryptoService @Inject constructor(
|
||||
* @param callback the exported keys
|
||||
*/
|
||||
override fun exportRoomKeys(password: String, callback: MatrixCallback<ByteArray>) {
|
||||
GlobalScope.launch(coroutineDispatchers.main) {
|
||||
cryptoCoroutineScope.launch(coroutineDispatchers.main) {
|
||||
runCatching {
|
||||
exportRoomKeys(password, MXMegolmExportEncryption.DEFAULT_ITERATION_COUNT)
|
||||
}.foldToCallback(callback)
|
||||
@ -791,7 +797,7 @@ internal class DefaultCryptoService @Inject constructor(
|
||||
password: String,
|
||||
progressListener: ProgressListener?,
|
||||
callback: MatrixCallback<ImportRoomKeysResult>) {
|
||||
GlobalScope.launch(coroutineDispatchers.main) {
|
||||
cryptoCoroutineScope.launch(coroutineDispatchers.main) {
|
||||
runCatching {
|
||||
withContext(coroutineDispatchers.crypto) {
|
||||
Timber.v("## importRoomKeys starts")
|
||||
@ -839,7 +845,7 @@ internal class DefaultCryptoService @Inject constructor(
|
||||
*/
|
||||
fun checkUnknownDevices(userIds: List<String>, callback: MatrixCallback<Unit>) {
|
||||
// force the refresh to ensure that the devices list is up-to-date
|
||||
GlobalScope.launch(coroutineDispatchers.crypto) {
|
||||
cryptoCoroutineScope.launch(coroutineDispatchers.crypto) {
|
||||
runCatching {
|
||||
val keys = deviceListManager.downloadKeys(userIds, true)
|
||||
val unknownDevices = getUnknownDevices(keys)
|
||||
@ -999,7 +1005,7 @@ internal class DefaultCryptoService @Inject constructor(
|
||||
}
|
||||
|
||||
override fun downloadKeys(userIds: List<String>, forceDownload: Boolean, callback: MatrixCallback<MXUsersDevicesMap<MXDeviceInfo>>) {
|
||||
GlobalScope.launch(coroutineDispatchers.crypto) {
|
||||
cryptoCoroutineScope.launch(coroutineDispatchers.crypto) {
|
||||
runCatching {
|
||||
deviceListManager.downloadKeys(userIds, forceDownload)
|
||||
}.foldToCallback(callback)
|
||||
|
@ -25,7 +25,6 @@ import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore
|
||||
import im.vector.matrix.android.internal.session.SessionScope
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
import kotlin.collections.ArrayList
|
||||
|
||||
@SessionScope
|
||||
internal class IncomingRoomKeyRequestManager @Inject constructor(
|
||||
@ -51,7 +50,7 @@ internal class IncomingRoomKeyRequestManager @Inject constructor(
|
||||
*
|
||||
* @param event the announcement event.
|
||||
*/
|
||||
suspend fun onRoomKeyRequestEvent(event: Event) {
|
||||
fun onRoomKeyRequestEvent(event: Event) {
|
||||
val roomKeyShare = event.getClearContent().toModel<RoomKeyShare>()
|
||||
when (roomKeyShare?.action) {
|
||||
RoomKeyShare.ACTION_SHARE_REQUEST -> receivedRoomKeyRequests.add(IncomingRoomKeyRequest(event))
|
||||
@ -78,7 +77,7 @@ internal class IncomingRoomKeyRequestManager @Inject constructor(
|
||||
Timber.v("m.room_key_request from $userId:$deviceId for $roomId / ${body.sessionId} id ${request.requestId}")
|
||||
if (userId == null || credentials.userId != userId) {
|
||||
// TODO: determine if we sent this device the keys already: in
|
||||
Timber.e("## processReceivedRoomKeyRequests() : Ignoring room key request from other user for now")
|
||||
Timber.w("## processReceivedRoomKeyRequests() : Ignoring room key request from other user for now")
|
||||
return
|
||||
}
|
||||
// TODO: should we queue up requests we don't yet have keys for, in case they turn up later?
|
||||
@ -86,11 +85,11 @@ internal class IncomingRoomKeyRequestManager @Inject constructor(
|
||||
// the keys for the requested events, and can drop the requests.
|
||||
val decryptor = roomDecryptorProvider.getRoomDecryptor(roomId, alg)
|
||||
if (null == decryptor) {
|
||||
Timber.e("## processReceivedRoomKeyRequests() : room key request for unknown $alg in room $roomId")
|
||||
Timber.w("## processReceivedRoomKeyRequests() : room key request for unknown $alg in room $roomId")
|
||||
continue
|
||||
}
|
||||
if (!decryptor.hasKeysForKeyRequest(request)) {
|
||||
Timber.e("## processReceivedRoomKeyRequests() : room key request for unknown session ${body.sessionId!!}")
|
||||
Timber.w("## processReceivedRoomKeyRequests() : room key request for unknown session ${body.sessionId!!}")
|
||||
cryptoStore.deleteIncomingRoomKeyRequest(request)
|
||||
continue
|
||||
}
|
||||
@ -139,7 +138,7 @@ internal class IncomingRoomKeyRequestManager @Inject constructor(
|
||||
if (null != receivedRoomKeyRequestCancellations) {
|
||||
for (request in receivedRoomKeyRequestCancellations!!) {
|
||||
Timber.v("## ## processReceivedRoomKeyRequests() : m.room_key_request cancellation for " + request.userId
|
||||
+ ":" + request.deviceId + " id " + request.requestId)
|
||||
+ ":" + request.deviceId + " id " + request.requestId)
|
||||
|
||||
// we should probably only notify the app of cancellations we told it
|
||||
// about, but we don't currently have a record of that, so we just pass
|
||||
|
@ -764,7 +764,7 @@ internal class MXOlmDevice @Inject constructor(
|
||||
return session
|
||||
}
|
||||
} else {
|
||||
Timber.e("## getInboundGroupSession() : Cannot retrieve inbound group session $sessionId")
|
||||
Timber.w("## getInboundGroupSession() : Cannot retrieve inbound group session $sessionId")
|
||||
throw MXCryptoError.Base(MXCryptoError.ErrorType.UNKNOWN_INBOUND_SESSION_ID, MXCryptoError.UNKNOWN_INBOUND_SESSION_ID_REASON)
|
||||
}
|
||||
}
|
||||
|
@ -63,6 +63,7 @@ internal class OutgoingRoomKeyRequestManager @Inject constructor(
|
||||
*/
|
||||
fun stop() {
|
||||
isClientRunning = false
|
||||
stopTimer()
|
||||
}
|
||||
|
||||
/**
|
||||
@ -171,6 +172,10 @@ internal class OutgoingRoomKeyRequestManager @Inject constructor(
|
||||
}, SEND_KEY_REQUESTS_DELAY_MS.toLong())
|
||||
}
|
||||
|
||||
private fun stopTimer() {
|
||||
BACKGROUND_HANDLER.removeCallbacksAndMessages(null)
|
||||
}
|
||||
|
||||
// look for and send any queued requests. Runs itself recursively until
|
||||
// there are no more requests, or there is an error (in which case, the
|
||||
// timer will be restarted before the promise resolves).
|
||||
@ -187,7 +192,7 @@ internal class OutgoingRoomKeyRequestManager @Inject constructor(
|
||||
OutgoingRoomKeyRequest.RequestState.CANCELLATION_PENDING_AND_WILL_RESEND))
|
||||
|
||||
if (null == outgoingRoomKeyRequest) {
|
||||
Timber.e("## sendOutgoingRoomKeyRequests() : No more outgoing room key requests")
|
||||
Timber.v("## sendOutgoingRoomKeyRequests() : No more outgoing room key requests")
|
||||
sendOutgoingRoomKeyRequestsRunning.set(false)
|
||||
return
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ import im.vector.matrix.android.internal.crypto.model.rest.RoomKeyRequestBody
|
||||
import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore
|
||||
import im.vector.matrix.android.internal.crypto.tasks.SendToDeviceTask
|
||||
import im.vector.matrix.android.internal.util.MatrixCoroutineDispatchers
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
|
||||
@ -46,8 +46,9 @@ internal class MXMegolmDecryption(private val userId: String,
|
||||
private val ensureOlmSessionsForDevicesAction: EnsureOlmSessionsForDevicesAction,
|
||||
private val cryptoStore: IMXCryptoStore,
|
||||
private val sendToDeviceTask: SendToDeviceTask,
|
||||
private val coroutineDispatchers: MatrixCoroutineDispatchers)
|
||||
: IMXDecrypting {
|
||||
private val coroutineDispatchers: MatrixCoroutineDispatchers,
|
||||
private val cryptoCoroutineScope: CoroutineScope
|
||||
) : IMXDecrypting {
|
||||
|
||||
var newSessionListener: NewSessionListener? = null
|
||||
|
||||
@ -61,7 +62,7 @@ internal class MXMegolmDecryption(private val userId: String,
|
||||
return decryptEvent(event, timeline, true)
|
||||
}
|
||||
|
||||
private suspend fun decryptEvent(event: Event, timeline: String, requestKeysOnFail: Boolean): MXEventDecryptionResult {
|
||||
private fun decryptEvent(event: Event, timeline: String, requestKeysOnFail: Boolean): MXEventDecryptionResult {
|
||||
if (event.roomId.isNullOrBlank()) {
|
||||
throw MXCryptoError.Base(MXCryptoError.ErrorType.MISSING_FIELDS, MXCryptoError.MISSING_FIELDS_REASON)
|
||||
}
|
||||
@ -292,7 +293,7 @@ internal class MXMegolmDecryption(private val userId: String,
|
||||
return
|
||||
}
|
||||
val userId = request.userId ?: return
|
||||
GlobalScope.launch(coroutineDispatchers.crypto) {
|
||||
cryptoCoroutineScope.launch(coroutineDispatchers.crypto) {
|
||||
runCatching { deviceListManager.downloadKeys(listOf(userId), false) }
|
||||
.mapCatching {
|
||||
val deviceId = request.deviceId
|
||||
|
@ -25,17 +25,21 @@ import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore
|
||||
import im.vector.matrix.android.internal.crypto.tasks.SendToDeviceTask
|
||||
import im.vector.matrix.android.internal.di.UserId
|
||||
import im.vector.matrix.android.internal.util.MatrixCoroutineDispatchers
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import javax.inject.Inject
|
||||
|
||||
internal class MXMegolmDecryptionFactory @Inject constructor(@UserId private val userId: String,
|
||||
private val olmDevice: MXOlmDevice,
|
||||
private val deviceListManager: DeviceListManager,
|
||||
private val outgoingRoomKeyRequestManager: OutgoingRoomKeyRequestManager,
|
||||
private val messageEncrypter: MessageEncrypter,
|
||||
private val ensureOlmSessionsForDevicesAction: EnsureOlmSessionsForDevicesAction,
|
||||
private val cryptoStore: IMXCryptoStore,
|
||||
private val sendToDeviceTask: SendToDeviceTask,
|
||||
private val coroutineDispatchers: MatrixCoroutineDispatchers) {
|
||||
internal class MXMegolmDecryptionFactory @Inject constructor(
|
||||
@UserId private val userId: String,
|
||||
private val olmDevice: MXOlmDevice,
|
||||
private val deviceListManager: DeviceListManager,
|
||||
private val outgoingRoomKeyRequestManager: OutgoingRoomKeyRequestManager,
|
||||
private val messageEncrypter: MessageEncrypter,
|
||||
private val ensureOlmSessionsForDevicesAction: EnsureOlmSessionsForDevicesAction,
|
||||
private val cryptoStore: IMXCryptoStore,
|
||||
private val sendToDeviceTask: SendToDeviceTask,
|
||||
private val coroutineDispatchers: MatrixCoroutineDispatchers,
|
||||
private val cryptoCoroutineScope: CoroutineScope
|
||||
) {
|
||||
|
||||
fun create(): MXMegolmDecryption {
|
||||
return MXMegolmDecryption(
|
||||
@ -47,6 +51,7 @@ internal class MXMegolmDecryptionFactory @Inject constructor(@UserId private val
|
||||
ensureOlmSessionsForDevicesAction,
|
||||
cryptoStore,
|
||||
sendToDeviceTask,
|
||||
coroutineDispatchers)
|
||||
coroutineDispatchers,
|
||||
cryptoCoroutineScope)
|
||||
}
|
||||
}
|
||||
|
@ -59,7 +59,7 @@ import im.vector.matrix.android.internal.task.configureWith
|
||||
import im.vector.matrix.android.internal.util.JsonCanonicalizer
|
||||
import im.vector.matrix.android.internal.util.MatrixCoroutineDispatchers
|
||||
import im.vector.matrix.android.internal.util.awaitCallback
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.matrix.olm.OlmException
|
||||
@ -102,7 +102,8 @@ internal class KeysBackup @Inject constructor(
|
||||
private val updateKeysBackupVersionTask: UpdateKeysBackupVersionTask,
|
||||
// Task executor
|
||||
private val taskExecutor: TaskExecutor,
|
||||
private val coroutineDispatchers: MatrixCoroutineDispatchers
|
||||
private val coroutineDispatchers: MatrixCoroutineDispatchers,
|
||||
private val cryptoCoroutineScope: CoroutineScope
|
||||
) : KeysBackupService {
|
||||
|
||||
private val uiHandler = Handler(Looper.getMainLooper())
|
||||
@ -143,7 +144,7 @@ internal class KeysBackup @Inject constructor(
|
||||
override fun prepareKeysBackupVersion(password: String?,
|
||||
progressListener: ProgressListener?,
|
||||
callback: MatrixCallback<MegolmBackupCreationInfo>) {
|
||||
GlobalScope.launch(coroutineDispatchers.main) {
|
||||
cryptoCoroutineScope.launch(coroutineDispatchers.main) {
|
||||
runCatching {
|
||||
withContext(coroutineDispatchers.crypto) {
|
||||
val olmPkDecryption = OlmPkDecryption()
|
||||
@ -233,7 +234,7 @@ internal class KeysBackup @Inject constructor(
|
||||
}
|
||||
|
||||
override fun deleteBackup(version: String, callback: MatrixCallback<Unit>?) {
|
||||
GlobalScope.launch(coroutineDispatchers.main) {
|
||||
cryptoCoroutineScope.launch(coroutineDispatchers.main) {
|
||||
withContext(coroutineDispatchers.crypto) {
|
||||
// If we're currently backing up to this backup... stop.
|
||||
// (We start using it automatically in createKeysBackupVersion so this is symmetrical).
|
||||
@ -344,9 +345,7 @@ internal class KeysBackup @Inject constructor(
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
keysBackupStateManager.addListener(keysBackupStateListener!!)
|
||||
}.also { keysBackupStateManager.addListener(it) }
|
||||
|
||||
backupKeys()
|
||||
}
|
||||
@ -448,7 +447,7 @@ internal class KeysBackup @Inject constructor(
|
||||
|
||||
callback.onFailure(IllegalArgumentException("Missing element"))
|
||||
} else {
|
||||
GlobalScope.launch(coroutineDispatchers.main) {
|
||||
cryptoCoroutineScope.launch(coroutineDispatchers.main) {
|
||||
val updateKeysBackupVersionBody = withContext(coroutineDispatchers.crypto) {
|
||||
// Get current signatures, or create an empty set
|
||||
val myUserSignatures = authData.signatures?.get(userId)?.toMutableMap()
|
||||
@ -523,7 +522,7 @@ internal class KeysBackup @Inject constructor(
|
||||
callback: MatrixCallback<Unit>) {
|
||||
Timber.v("trustKeysBackupVersionWithRecoveryKey: version ${keysBackupVersion.version}")
|
||||
|
||||
GlobalScope.launch(coroutineDispatchers.main) {
|
||||
cryptoCoroutineScope.launch(coroutineDispatchers.main) {
|
||||
val isValid = withContext(coroutineDispatchers.crypto) {
|
||||
isValidRecoveryKeyForKeysBackupVersion(recoveryKey, keysBackupVersion)
|
||||
}
|
||||
@ -543,7 +542,7 @@ internal class KeysBackup @Inject constructor(
|
||||
callback: MatrixCallback<Unit>) {
|
||||
Timber.v("trustKeysBackupVersionWithPassphrase: version ${keysBackupVersion.version}")
|
||||
|
||||
GlobalScope.launch(coroutineDispatchers.main) {
|
||||
cryptoCoroutineScope.launch(coroutineDispatchers.main) {
|
||||
val recoveryKey = withContext(coroutineDispatchers.crypto) {
|
||||
recoveryKeyFromPassword(password, keysBackupVersion, null)
|
||||
}
|
||||
@ -614,7 +613,7 @@ internal class KeysBackup @Inject constructor(
|
||||
callback: MatrixCallback<ImportRoomKeysResult>) {
|
||||
Timber.v("restoreKeysWithRecoveryKey: From backup version: ${keysVersionResult.version}")
|
||||
|
||||
GlobalScope.launch(coroutineDispatchers.main) {
|
||||
cryptoCoroutineScope.launch(coroutineDispatchers.main) {
|
||||
runCatching {
|
||||
val decryption = withContext(coroutineDispatchers.crypto) {
|
||||
// Check if the recovery is valid before going any further
|
||||
@ -695,7 +694,7 @@ internal class KeysBackup @Inject constructor(
|
||||
callback: MatrixCallback<ImportRoomKeysResult>) {
|
||||
Timber.v("[MXKeyBackup] restoreKeyBackup with password: From backup version: ${keysBackupVersion.version}")
|
||||
|
||||
GlobalScope.launch(coroutineDispatchers.main) {
|
||||
cryptoCoroutineScope.launch(coroutineDispatchers.main) {
|
||||
runCatching {
|
||||
val progressListener = if (stepProgressListener != null) {
|
||||
object : ProgressListener {
|
||||
@ -729,8 +728,8 @@ internal class KeysBackup @Inject constructor(
|
||||
* parameters and always returns a KeysBackupData object through the Callback
|
||||
*/
|
||||
private suspend fun getKeys(sessionId: String?,
|
||||
roomId: String?,
|
||||
version: String): KeysBackupData {
|
||||
roomId: String?,
|
||||
version: String): KeysBackupData {
|
||||
return if (roomId != null && sessionId != null) {
|
||||
// Get key for the room and for the session
|
||||
val data = getRoomSessionDataTask.execute(GetRoomSessionDataTask.Params(roomId, sessionId, version))
|
||||
@ -1154,7 +1153,7 @@ internal class KeysBackup @Inject constructor(
|
||||
|
||||
keysBackupStateManager.state = KeysBackupState.BackingUp
|
||||
|
||||
GlobalScope.launch(coroutineDispatchers.main) {
|
||||
cryptoCoroutineScope.launch(coroutineDispatchers.main) {
|
||||
withContext(coroutineDispatchers.crypto) {
|
||||
Timber.v("backupKeys: 2 - Encrypting keys")
|
||||
|
||||
|
@ -53,10 +53,10 @@ internal class DefaultUploadKeysTask @Inject constructor(private val cryptoApi:
|
||||
}
|
||||
|
||||
return executeRequest {
|
||||
if (encodedDeviceId.isNullOrBlank()) {
|
||||
apiCall = cryptoApi.uploadKeys(body)
|
||||
apiCall = if (encodedDeviceId.isBlank()) {
|
||||
cryptoApi.uploadKeys(body)
|
||||
} else {
|
||||
apiCall = cryptoApi.uploadKeys(encodedDeviceId, body)
|
||||
cryptoApi.uploadKeys(encodedDeviceId, body)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -83,7 +83,7 @@ internal class SessionRealmConfigurationFactory @Inject constructor(private val
|
||||
try {
|
||||
File(directory, file).deleteRecursively()
|
||||
} catch (e: Exception) {
|
||||
Timber.e(e, "Unable to move files")
|
||||
Timber.e(e, "Unable to delete files")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -16,26 +16,27 @@
|
||||
|
||||
package im.vector.matrix.android.internal.database.query
|
||||
|
||||
import im.vector.matrix.android.internal.database.awaitTransaction
|
||||
import im.vector.matrix.android.internal.database.model.FilterEntity
|
||||
import im.vector.matrix.android.internal.session.filter.FilterFactory
|
||||
import io.realm.Realm
|
||||
import io.realm.kotlin.createObject
|
||||
import io.realm.kotlin.where
|
||||
|
||||
/**
|
||||
* Get the current filter
|
||||
*/
|
||||
internal fun FilterEntity.Companion.get(realm: Realm): FilterEntity? {
|
||||
return realm.where<FilterEntity>().findFirst()
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current filter, create one if it does not exist
|
||||
*/
|
||||
internal suspend fun FilterEntity.Companion.getFilter(realm: Realm): FilterEntity {
|
||||
var filter = realm.where<FilterEntity>().findFirst()
|
||||
if (filter == null) {
|
||||
filter = FilterEntity().apply {
|
||||
filterBodyJson = FilterFactory.createDefaultFilterBody().toJSONString()
|
||||
roomEventFilterJson = FilterFactory.createDefaultRoomFilter().toJSONString()
|
||||
filterId = ""
|
||||
}
|
||||
awaitTransaction(realm.configuration) {
|
||||
it.insert(filter)
|
||||
}
|
||||
}
|
||||
return filter
|
||||
internal fun FilterEntity.Companion.getOrCreate(realm: Realm): FilterEntity {
|
||||
return get(realm) ?: realm.createObject<FilterEntity>()
|
||||
.apply {
|
||||
filterBodyJson = FilterFactory.createDefaultFilterBody().toJSONString()
|
||||
roomEventFilterJson = FilterFactory.createDefaultRoomFilter().toJSONString()
|
||||
filterId = ""
|
||||
}
|
||||
}
|
||||
|
@ -22,12 +22,14 @@ import arrow.core.Try
|
||||
import im.vector.matrix.android.api.MatrixCallback
|
||||
import im.vector.matrix.android.api.session.content.ContentUrlResolver
|
||||
import im.vector.matrix.android.api.session.file.FileService
|
||||
import im.vector.matrix.android.api.util.Cancelable
|
||||
import im.vector.matrix.android.internal.crypto.attachments.ElementToDecrypt
|
||||
import im.vector.matrix.android.internal.crypto.attachments.MXEncryptedAttachments
|
||||
import im.vector.matrix.android.internal.di.UserMd5
|
||||
import im.vector.matrix.android.internal.extensions.foldToCallback
|
||||
import im.vector.matrix.android.internal.util.MatrixCoroutineDispatchers
|
||||
import im.vector.matrix.android.internal.util.md5
|
||||
import im.vector.matrix.android.internal.util.toCancelable
|
||||
import im.vector.matrix.android.internal.util.writeToFile
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.launch
|
||||
@ -55,8 +57,8 @@ internal class DefaultFileService @Inject constructor(private val context: Conte
|
||||
fileName: String,
|
||||
url: String?,
|
||||
elementToDecrypt: ElementToDecrypt?,
|
||||
callback: MatrixCallback<File>) {
|
||||
GlobalScope.launch(coroutineDispatchers.main) {
|
||||
callback: MatrixCallback<File>): Cancelable {
|
||||
return GlobalScope.launch(coroutineDispatchers.main) {
|
||||
withContext(coroutineDispatchers.io) {
|
||||
Try {
|
||||
val folder = getFolder(downloadMode, id)
|
||||
@ -96,7 +98,7 @@ internal class DefaultFileService @Inject constructor(private val context: Conte
|
||||
}
|
||||
}
|
||||
.foldToCallback(callback)
|
||||
}
|
||||
}.toCancelable()
|
||||
}
|
||||
|
||||
private fun getFolder(downloadMode: FileService.DownloadMode, id: String): File {
|
||||
|
@ -101,7 +101,7 @@ class DefaultInitialSyncProgressService @Inject constructor() : InitialSyncProgr
|
||||
val parentProgress = (currentProgress * parentWeight).toInt()
|
||||
it.setProgress(offset + parentProgress)
|
||||
} ?: run {
|
||||
Timber.e("--- ${leaf().nameRes}: $currentProgress")
|
||||
Timber.v("--- ${leaf().nameRes}: $currentProgress")
|
||||
status.postValue(
|
||||
InitialSyncProgressService.Status(leaf().nameRes, currentProgress)
|
||||
)
|
||||
|
@ -19,7 +19,8 @@ package im.vector.matrix.android.internal.session.filter
|
||||
import com.zhuinden.monarchy.Monarchy
|
||||
import im.vector.matrix.android.internal.database.model.FilterEntity
|
||||
import im.vector.matrix.android.internal.database.model.FilterEntityFields
|
||||
import im.vector.matrix.android.internal.database.query.getFilter
|
||||
import im.vector.matrix.android.internal.database.query.get
|
||||
import im.vector.matrix.android.internal.database.query.getOrCreate
|
||||
import im.vector.matrix.android.internal.util.awaitTransaction
|
||||
import io.realm.Realm
|
||||
import io.realm.kotlin.where
|
||||
@ -29,26 +30,28 @@ internal class DefaultFilterRepository @Inject constructor(private val monarchy:
|
||||
|
||||
override suspend fun storeFilter(filterBody: FilterBody, roomEventFilter: RoomEventFilter): Boolean {
|
||||
return Realm.getInstance(monarchy.realmConfiguration).use { realm ->
|
||||
val filter = FilterEntity.getFilter(realm)
|
||||
val result = if (filter.filterBodyJson != filterBody.toJSONString()) {
|
||||
// Filter has changed, store it and reset the filter Id
|
||||
monarchy.awaitTransaction {
|
||||
val filter = FilterEntity.get(realm)
|
||||
// Filter has changed, or no filter Id yet
|
||||
filter == null
|
||||
|| filter.filterBodyJson != filterBody.toJSONString()
|
||||
|| filter.filterId.isBlank()
|
||||
}.also { hasChanged ->
|
||||
if (hasChanged) {
|
||||
// Filter is new or has changed, store it and reset the filter Id.
|
||||
// This has to be done outside of the Realm.use(), because awaitTransaction change the current thread
|
||||
monarchy.awaitTransaction { realm ->
|
||||
// We manage only one filter for now
|
||||
val filterBodyJson = filterBody.toJSONString()
|
||||
val roomEventFilterJson = roomEventFilter.toJSONString()
|
||||
|
||||
val filterEntity = FilterEntity.getFilter(it)
|
||||
val filterEntity = FilterEntity.getOrCreate(realm)
|
||||
|
||||
filterEntity.filterBodyJson = filterBodyJson
|
||||
filterEntity.roomEventFilterJson = roomEventFilterJson
|
||||
// Reset filterId
|
||||
filterEntity.filterId = ""
|
||||
}
|
||||
true
|
||||
} else {
|
||||
filter.filterId.isBlank()
|
||||
}
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
@ -67,7 +70,7 @@ internal class DefaultFilterRepository @Inject constructor(private val monarchy:
|
||||
|
||||
override suspend fun getFilter(): String {
|
||||
return Realm.getInstance(monarchy.realmConfiguration).use {
|
||||
val filter = FilterEntity.getFilter(it)
|
||||
val filter = FilterEntity.getOrCreate(it)
|
||||
if (filter.filterId.isBlank()) {
|
||||
// Use the Json format
|
||||
filter.filterBodyJson
|
||||
@ -80,7 +83,7 @@ internal class DefaultFilterRepository @Inject constructor(private val monarchy:
|
||||
|
||||
override suspend fun getRoomFilter(): String {
|
||||
return Realm.getInstance(monarchy.realmConfiguration).use {
|
||||
FilterEntity.getFilter(it).roomEventFilterJson
|
||||
FilterEntity.getOrCreate(it).roomEventFilterJson
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,7 @@
|
||||
package im.vector.matrix.android.internal.session.signout
|
||||
|
||||
import android.content.Context
|
||||
import im.vector.matrix.android.BuildConfig
|
||||
import im.vector.matrix.android.internal.SessionManager
|
||||
import im.vector.matrix.android.internal.auth.SessionParamsStore
|
||||
import im.vector.matrix.android.internal.crypto.CryptoModule
|
||||
@ -27,6 +28,8 @@ import im.vector.matrix.android.internal.session.SessionModule
|
||||
import im.vector.matrix.android.internal.session.cache.ClearCacheTask
|
||||
import im.vector.matrix.android.internal.task.Task
|
||||
import im.vector.matrix.android.internal.worker.WorkManagerUtil
|
||||
import io.realm.Realm
|
||||
import io.realm.RealmConfiguration
|
||||
import timber.log.Timber
|
||||
import java.io.File
|
||||
import javax.inject.Inject
|
||||
@ -42,6 +45,8 @@ internal class DefaultSignOutTask @Inject constructor(private val context: Conte
|
||||
@CryptoDatabase private val clearCryptoDataTask: ClearCacheTask,
|
||||
@UserCacheDirectory private val userFile: File,
|
||||
private val realmKeysUtils: RealmKeysUtils,
|
||||
@SessionDatabase private val realmSessionConfiguration: RealmConfiguration,
|
||||
@CryptoDatabase private val realmCryptoConfiguration: RealmConfiguration,
|
||||
@UserMd5 private val userMd5: String) : SignOutTask {
|
||||
|
||||
override suspend fun execute(params: Unit) {
|
||||
@ -71,5 +76,15 @@ internal class DefaultSignOutTask @Inject constructor(private val context: Conte
|
||||
Timber.d("SignOut: clear the database keys")
|
||||
realmKeysUtils.clear(SessionModule.DB_ALIAS_PREFIX + userMd5)
|
||||
realmKeysUtils.clear(CryptoModule.DB_ALIAS_PREFIX + userMd5)
|
||||
|
||||
// Sanity check
|
||||
if (BuildConfig.DEBUG) {
|
||||
Realm.getGlobalInstanceCount(realmSessionConfiguration)
|
||||
.takeIf { it > 0 }
|
||||
?.let { Timber.e("All realm instance for session has not been closed ($it)") }
|
||||
Realm.getGlobalInstanceCount(realmCryptoConfiguration)
|
||||
.takeIf { it > 0 }
|
||||
?.let { Timber.e("All realm instance for crypto has not been closed ($it)") }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -97,7 +97,7 @@ class HomeActivity : VectorBaseActivity(), ToolbarConfigurable {
|
||||
if (status == null) {
|
||||
waiting_view.isVisible = false
|
||||
} else {
|
||||
Timber.e("${getString(status.statusText)} ${status.percentProgress}")
|
||||
Timber.v("${getString(status.statusText)} ${status.percentProgress}")
|
||||
waiting_view.setOnClickListener {
|
||||
// block interactions
|
||||
}
|
||||
|
@ -16,5 +16,4 @@
|
||||
|
||||
package im.vector.riotx.features.login
|
||||
|
||||
// TODO Check the link with Nad
|
||||
const val MODULAR_LINK = "https://modular.im/?utm_source=riot-web&utm_medium=web&utm_campaign=riot-web-authentication"
|
||||
const val MODULAR_LINK = "https://modular.im/?utm_source=riot-x-android&utm_medium=native&utm_campaign=riot-x-android-authentication"
|
||||
|
@ -109,8 +109,7 @@ class LoginFragment @Inject constructor(
|
||||
ServerType.Modular -> {
|
||||
loginServerIcon.isVisible = true
|
||||
loginServerIcon.setImageResource(R.drawable.ic_logo_modular)
|
||||
// TODO
|
||||
loginTitle.text = getString(resId, "TODO")
|
||||
loginTitle.text = getString(resId, "Modular")
|
||||
loginNotice.text = getString(R.string.login_server_modular_text)
|
||||
}
|
||||
ServerType.Other -> {
|
||||
|
@ -46,8 +46,7 @@ class LoginSignUpSignInSelectionFragment @Inject constructor(
|
||||
ServerType.Modular -> {
|
||||
loginSignupSigninServerIcon.setImageResource(R.drawable.ic_logo_modular)
|
||||
loginSignupSigninServerIcon.isVisible = true
|
||||
// TODO
|
||||
loginSignupSigninTitle.text = getString(R.string.login_connect_to, "TODO MODULAR NAME")
|
||||
loginSignupSigninTitle.text = getString(R.string.login_connect_to_modular)
|
||||
loginSignupSigninText.text = state.homeServerUrlSimple
|
||||
}
|
||||
ServerType.Other -> {
|
||||
|
Loading…
x
Reference in New Issue
Block a user