Merge branch 'develop'

This commit is contained in:
Benoit Marty 2021-03-18 10:36:22 +01:00
commit a6c43f4638
22 changed files with 85 additions and 75 deletions

View file

@ -1,4 +1,11 @@
Changes in Element 1.1.2 (2021-03-16)
Changes in Element 1.1.3 (2021-03-18)
===================================================
Bugfix 🐛:
- Fix regression in UpdateTrustWorker (introduced in 1.1.2)
- Timeline : Fix ripple effect on text item and fix background color of separators.
Changes in Element 1.1.2 (2021-03-16) (was not published tp GPlay prod)
===================================================
Improvements 🙌:
@ -14,7 +21,7 @@ Bugfix 🐛:
Other changes:
- Change formatting on issue templates to proper headings.
Changes in Element 1.1.1 (2021-03-10)
Changes in Element 1.1.1 (2021-03-10) (was not published tp GPlay prod)
===================================================
Improvements 🙌:

View file

@ -0,0 +1,2 @@
Main changes in this version: performance improvement and bug fixes!
Full changelog: https://github.com/vector-im/element-android/releases/tag/v1.1.3

View file

@ -39,7 +39,7 @@ internal class GossipingWorkManager @Inject constructor(
.setConstraints(WorkManagerProvider.workConstraints)
.startChain(startChain)
.setInputData(data)
.setBackoffCriteria(BackoffPolicy.LINEAR, 10_000L, TimeUnit.MILLISECONDS)
.setBackoffCriteria(BackoffPolicy.LINEAR, WorkManagerProvider.BACKOFF_DELAY_MILLIS, TimeUnit.MILLISECONDS)
.build()
}

View file

@ -43,6 +43,7 @@ import org.matrix.android.sdk.internal.task.TaskThread
import org.matrix.android.sdk.internal.task.configureWith
import org.matrix.android.sdk.internal.util.JsonCanonicalizer
import org.matrix.android.sdk.internal.util.MatrixCoroutineDispatchers
import org.matrix.android.sdk.internal.util.logLimit
import org.matrix.android.sdk.internal.worker.WorkerParamsFactory
import org.matrix.olm.OlmPkSigning
import org.matrix.olm.OlmUtility
@ -750,7 +751,7 @@ internal class DefaultCrossSigningService @Inject constructor(
}
override fun onUsersDeviceUpdate(userIds: List<String>) {
Timber.d("## CrossSigning - onUsersDeviceUpdate for ${userIds.size} users: $userIds")
Timber.d("## CrossSigning - onUsersDeviceUpdate for users: ${userIds.logLimit()}")
val workerParams = UpdateTrustWorker.Params(
sessionId = sessionId,
filename = updateTrustWorkerDataRepository.createParam(userIds)
@ -759,7 +760,7 @@ internal class DefaultCrossSigningService @Inject constructor(
val workRequest = workManagerProvider.matrixOneTimeWorkRequestBuilder<UpdateTrustWorker>()
.setInputData(workerData)
.setBackoffCriteria(BackoffPolicy.LINEAR, 2_000L, TimeUnit.MILLISECONDS)
.setBackoffCriteria(BackoffPolicy.LINEAR, WorkManagerProvider.BACKOFF_DELAY_MILLIS, TimeUnit.MILLISECONDS)
.build()
workManagerProvider.workManager

View file

@ -97,22 +97,17 @@ internal class UpdateTrustWorker(context: Context,
// Unfortunately we don't have much info on what did exactly changed (is it the cross signing keys of that user,
// or a new device?) So we check all again :/
Timber.d("## CrossSigning - Updating trust for users: ${userList.logLimit()}")
Realm.getInstance(cryptoRealmConfiguration).use { cryptoRealm ->
Realm.getInstance(sessionRealmConfiguration).use {
updateTrust(userList, cryptoRealm)
}
}
updateTrust(userList)
}
cleanup(params)
return Result.success()
}
private suspend fun updateTrust(userListParam: List<String>,
cRealm: Realm) {
private suspend fun updateTrust(userListParam: List<String>) {
var userList = userListParam
var myCrossSigningInfo: MXCrossSigningInfo? = null
// First we check that the users MSK are trusted by mine
// After that we check the trust chain for each devices of each users
awaitTransaction(cryptoRealmConfiguration) { cryptoRealm ->
@ -203,38 +198,43 @@ internal class UpdateTrustWorker(context: Context,
// So Cross Signing keys trust is updated, device trust is updated
// We can now update room shields? in the session DB?
updateTrustStep2(userList, myCrossSigningInfo)
}
private suspend fun updateTrustStep2(userList: List<String>, myCrossSigningInfo: MXCrossSigningInfo?) {
Timber.d("## CrossSigning - Updating shields for impacted rooms...")
awaitTransaction(sessionRealmConfiguration) { sessionRealm ->
sessionRealm.where(RoomMemberSummaryEntity::class.java)
.`in`(RoomMemberSummaryEntityFields.USER_ID, userList.toTypedArray())
.distinct(RoomMemberSummaryEntityFields.ROOM_ID)
.findAll()
.map { it.roomId }
.also { Timber.d("## CrossSigning - ... impacted rooms ${it.logLimit()}") }
.forEach { roomId ->
RoomSummaryEntity.where(sessionRealm, roomId)
.equalTo(RoomSummaryEntityFields.IS_ENCRYPTED, true)
.findFirst()
?.let { roomSummary ->
Timber.d("## CrossSigning - Check shield state for room $roomId")
val allActiveRoomMembers = RoomMemberHelper(sessionRealm, roomId).getActiveRoomMemberIds()
try {
val updatedTrust = computeRoomShield(
myCrossSigningInfo,
cRealm,
allActiveRoomMembers,
roomSummary
)
if (roomSummary.roomEncryptionTrustLevel != updatedTrust) {
Timber.d("## CrossSigning - Shield change detected for $roomId -> $updatedTrust")
roomSummary.roomEncryptionTrustLevel = updatedTrust
Realm.getInstance(cryptoRealmConfiguration).use { cryptoRealm ->
sessionRealm.where(RoomMemberSummaryEntity::class.java)
.`in`(RoomMemberSummaryEntityFields.USER_ID, userList.toTypedArray())
.distinct(RoomMemberSummaryEntityFields.ROOM_ID)
.findAll()
.map { it.roomId }
.also { Timber.d("## CrossSigning - ... impacted rooms ${it.logLimit()}") }
.forEach { roomId ->
RoomSummaryEntity.where(sessionRealm, roomId)
.equalTo(RoomSummaryEntityFields.IS_ENCRYPTED, true)
.findFirst()
?.let { roomSummary ->
Timber.d("## CrossSigning - Check shield state for room $roomId")
val allActiveRoomMembers = RoomMemberHelper(sessionRealm, roomId).getActiveRoomMemberIds()
try {
val updatedTrust = computeRoomShield(
myCrossSigningInfo,
cryptoRealm,
allActiveRoomMembers,
roomSummary
)
if (roomSummary.roomEncryptionTrustLevel != updatedTrust) {
Timber.d("## CrossSigning - Shield change detected for $roomId -> $updatedTrust")
roomSummary.roomEncryptionTrustLevel = updatedTrust
}
} catch (failure: Throwable) {
Timber.e(failure)
}
} catch (failure: Throwable) {
Timber.e(failure)
}
}
}
}
}
}
}

View file

@ -45,7 +45,7 @@ internal class CrossSigningKeysMapper @Inject constructor(moshi: Moshi) {
return CryptoCrossSigningKey(
userId = userId ?: "",
keys = mapOf("ed25519:$pubKey" to pubKey),
usages = keyInfo.usages.map { it },
usages = keyInfo.usages.toList(),
signatures = deserializeSignatures(keyInfo.signatures),
trustLevel = keyInfo.trustLevelEntity?.let {
DeviceTrustLevel(

View file

@ -183,7 +183,7 @@ internal class VerificationTransportRoomMessage(
val workRequest = workManagerProvider.matrixOneTimeWorkRequestBuilder<SendVerificationMessageWorker>()
.setConstraints(WorkManagerProvider.workConstraints)
.setInputData(workerParams)
.setBackoffCriteria(BackoffPolicy.LINEAR, 2_000L, TimeUnit.MILLISECONDS)
.setBackoffCriteria(BackoffPolicy.LINEAR, WorkManagerProvider.BACKOFF_DELAY_MILLIS, TimeUnit.MILLISECONDS)
.build()
workManagerProvider.workManager
@ -280,7 +280,7 @@ internal class VerificationTransportRoomMessage(
val workRequest = workManagerProvider.matrixOneTimeWorkRequestBuilder<SendVerificationMessageWorker>()
.setConstraints(WorkManagerProvider.workConstraints)
.setInputData(workerParams)
.setBackoffCriteria(BackoffPolicy.LINEAR, 2_000L, TimeUnit.MILLISECONDS)
.setBackoffCriteria(BackoffPolicy.LINEAR, WorkManagerProvider.BACKOFF_DELAY_MILLIS, TimeUnit.MILLISECONDS)
.build()
return workManagerProvider.workManager
.beginUniqueWork(uniqueQueueName(), ExistingWorkPolicy.APPEND_OR_REPLACE, workRequest)

View file

@ -23,6 +23,7 @@ import androidx.work.NetworkType
import androidx.work.OneTimeWorkRequestBuilder
import androidx.work.PeriodicWorkRequestBuilder
import androidx.work.WorkManager
import androidx.work.WorkRequest
import java.util.concurrent.TimeUnit
import javax.inject.Inject
@ -69,6 +70,7 @@ internal class WorkManagerProvider @Inject constructor(
.setRequiredNetworkType(NetworkType.CONNECTED)
.build()
const val BACKOFF_DELAY = 10_000L
// Use min value, smaller value will be ignored
const val BACKOFF_DELAY_MILLIS = WorkRequest.MIN_BACKOFF_MILLIS
}
}

View file

@ -96,7 +96,7 @@ internal class DefaultPushersService @Inject constructor(
val request = workManagerProvider.matrixOneTimeWorkRequestBuilder<AddHttpPusherWorker>()
.setConstraints(WorkManagerProvider.workConstraints)
.setInputData(WorkerParamsFactory.toData(params))
.setBackoffCriteria(BackoffPolicy.LINEAR, 10_000L, TimeUnit.MILLISECONDS)
.setBackoffCriteria(BackoffPolicy.LINEAR, WorkManagerProvider.BACKOFF_DELAY_MILLIS, TimeUnit.MILLISECONDS)
.build()
workManagerProvider.workManager.enqueue(request)
return request.id

View file

@ -318,7 +318,7 @@ internal class DefaultSendService @AssistedInject constructor(
.setConstraints(WorkManagerProvider.workConstraints)
.startChain(true)
.setInputData(uploadWorkData)
.setBackoffCriteria(BackoffPolicy.LINEAR, WorkManagerProvider.BACKOFF_DELAY, TimeUnit.MILLISECONDS)
.setBackoffCriteria(BackoffPolicy.LINEAR, WorkManagerProvider.BACKOFF_DELAY_MILLIS, TimeUnit.MILLISECONDS)
.build()
}
@ -332,7 +332,7 @@ internal class DefaultSendService @AssistedInject constructor(
// .setConstraints(WorkManagerProvider.workConstraints)
.startChain(false)
.setInputData(workData)
.setBackoffCriteria(BackoffPolicy.LINEAR, WorkManagerProvider.BACKOFF_DELAY, TimeUnit.MILLISECONDS)
.setBackoffCriteria(BackoffPolicy.LINEAR, WorkManagerProvider.BACKOFF_DELAY_MILLIS, TimeUnit.MILLISECONDS)
.build()
}
}

View file

@ -50,7 +50,7 @@ internal class TimelineSendEventWorkCommon @Inject constructor(
.setConstraints(WorkManagerProvider.workConstraints)
.startChain(startChain)
.setInputData(data)
.setBackoffCriteria(BackoffPolicy.LINEAR, BACKOFF_DELAY, TimeUnit.MILLISECONDS)
.setBackoffCriteria(BackoffPolicy.LINEAR, WorkManagerProvider.BACKOFF_DELAY_MILLIS, TimeUnit.MILLISECONDS)
.build()
}
@ -60,6 +60,5 @@ internal class TimelineSendEventWorkCommon @Inject constructor(
companion object {
private const val SEND_WORK = "SEND_WORK"
private const val BACKOFF_DELAY = 10_000L
}
}

View file

@ -65,7 +65,7 @@ internal class FileInitialSyncStatusRepository(directory: File) : InitialSyncSta
val state = cache?.step ?: InitialSyncStatus.STEP_INIT
return if (state >= InitialSyncStatus.STEP_DOWNLOADED
&& System.currentTimeMillis() > (cache?.downloadedDate ?: 0) + INIT_SYNC_FILE_LIFETIME) {
Timber.v("INIT_SYNC downloaded file is outdated, download it again")
Timber.d("INIT_SYNC downloaded file is outdated, download it again")
// The downloaded file is outdated
setStep(InitialSyncStatus.STEP_INIT)
InitialSyncStatus.STEP_INIT

View file

@ -147,13 +147,13 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle
if (numberOfChunks > 1) {
reportSubtask(reporter, InitSyncStep.ImportingAccountJoinedRooms, numberOfChunks, 0.6f) {
val chunkSize = listSize / numberOfChunks
Timber.v("INIT_SYNC $listSize rooms to insert, split into $numberOfChunks sublists of $chunkSize items")
Timber.d("INIT_SYNC $listSize rooms to insert, split into $numberOfChunks sublists of $chunkSize items")
// I cannot find a better way to chunk a map, so chunk the keys and then create new maps
handlingStrategy.data.keys
.chunked(chunkSize)
.forEachIndexed { index, roomIds ->
val roomEntities = roomIds
.also { Timber.v("INIT_SYNC insert ${roomIds.size} rooms") }
.also { Timber.d("INIT_SYNC insert ${roomIds.size} rooms") }
.map {
handleJoinedRoom(
realm = realm,

View file

@ -101,7 +101,7 @@ internal class DefaultSyncTask @Inject constructor(
val readTimeOut = (params.timeout + TIMEOUT_MARGIN).coerceAtLeast(TimeOutInterceptor.DEFAULT_LONG_TIMEOUT)
if (isInitialSync) {
Timber.v("INIT_SYNC with filter: ${requestParams["filter"]}")
Timber.d("INIT_SYNC with filter: ${requestParams["filter"]}")
val initSyncStrategy = initialSyncStrategy
logDuration("INIT_SYNC strategy: $initSyncStrategy") {
if (initSyncStrategy is InitialSyncStrategy.Optimized) {
@ -145,7 +145,7 @@ internal class DefaultSyncTask @Inject constructor(
val workingFile = File(workingDir, "initSync.json")
val status = initialSyncStatusRepository.getStep()
if (workingFile.exists() && status >= InitialSyncStatus.STEP_DOWNLOADED) {
Timber.v("INIT_SYNC file is already here")
Timber.d("INIT_SYNC file is already here")
reportSubtask(initialSyncProgressService, InitSyncStep.Downloading, 1, 0.3f) {
// Empty task
}
@ -204,7 +204,7 @@ internal class DefaultSyncTask @Inject constructor(
// Log some stats
val nbOfJoinedRooms = syncResponse.rooms?.join?.size ?: 0
val nbOfJoinedRoomsInFile = syncResponse.rooms?.join?.values?.count { it.ephemeral is LazyRoomSyncEphemeral.Stored }
Timber.v("INIT_SYNC $nbOfJoinedRooms rooms, $nbOfJoinedRoomsInFile ephemeral stored into files")
Timber.d("INIT_SYNC $nbOfJoinedRooms rooms, $nbOfJoinedRoomsInFile ephemeral stored into files")
logDuration("INIT_SYNC Database insertion") {
syncResponseHandler.handleResponse(syncResponse, null, initialSyncProgressService)

View file

@ -106,7 +106,7 @@ internal class SyncWorker(context: Context,
val data = WorkerParamsFactory.toData(Params(sessionId, serverTimeout, 0L, false))
val workRequest = workManagerProvider.matrixOneTimeWorkRequestBuilder<SyncWorker>()
.setConstraints(WorkManagerProvider.workConstraints)
.setBackoffCriteria(BackoffPolicy.LINEAR, 1_000, TimeUnit.MILLISECONDS)
.setBackoffCriteria(BackoffPolicy.LINEAR, WorkManagerProvider.BACKOFF_DELAY_MILLIS, TimeUnit.MILLISECONDS)
.setInputData(data)
.build()
workManagerProvider.workManager
@ -118,7 +118,7 @@ internal class SyncWorker(context: Context,
val workRequest = workManagerProvider.matrixOneTimeWorkRequestBuilder<SyncWorker>()
.setConstraints(WorkManagerProvider.workConstraints)
.setInputData(data)
.setBackoffCriteria(BackoffPolicy.LINEAR, 1_000, TimeUnit.MILLISECONDS)
.setBackoffCriteria(BackoffPolicy.LINEAR, WorkManagerProvider.BACKOFF_DELAY_MILLIS, TimeUnit.MILLISECONDS)
.setInitialDelay(delayInSeconds, TimeUnit.SECONDS)
.build()

View file

@ -57,12 +57,12 @@ internal class SplitLazyRoomSyncEphemeralJsonAdapter(
}
val limit = syncStrategy.minSizeToStoreInFile
return if (json.length > limit) {
Timber.v("INIT_SYNC $path content length: ${json.length} copy to a file")
Timber.d("INIT_SYNC $path content length: ${json.length} copy to a file")
// Copy the source to a file
roomSyncEphemeralTemporaryStore.write(roomId, json)
LazyRoomSyncEphemeral.Stored
} else {
Timber.v("INIT_SYNC $path content length: ${json.length} parse it now")
Timber.d("INIT_SYNC $path content length: ${json.length} parse it now")
val roomSync = delegate.fromJson(json) ?: return null
LazyRoomSyncEphemeral.Parsed(roomSync)
}

View file

@ -33,9 +33,9 @@ internal class InitialSyncResponseParser @Inject constructor(
fun parse(syncStrategy: InitialSyncStrategy.Optimized, workingFile: File): SyncResponse {
val syncResponseLength = workingFile.length().toInt()
Timber.v("INIT_SYNC Sync file size is $syncResponseLength bytes")
Timber.d("INIT_SYNC Sync file size is $syncResponseLength bytes")
val shouldSplit = syncResponseLength >= syncStrategy.minSizeToSplit
Timber.v("INIT_SYNC should split in several files: $shouldSplit")
Timber.d("INIT_SYNC should split in several files: $shouldSplit")
return getMoshi(syncStrategy, shouldSplit)
.adapter(SyncResponse::class.java)
.fromJson(workingFile.source().buffer())!!

View file

@ -33,13 +33,13 @@ internal fun <T> Collection<T>.logLimit(maxQuantity: Int = 5): String {
internal suspend fun <T> logDuration(message: String,
block: suspend () -> T): T {
Timber.v("$message -- BEGIN")
Timber.d("$message -- BEGIN")
val start = System.currentTimeMillis()
val result = logRamUsage(message) {
block()
}
val duration = System.currentTimeMillis() - start
Timber.v("$message -- END duration: $duration ms")
Timber.d("$message -- END duration: $duration ms")
return result
}
@ -50,12 +50,12 @@ internal suspend fun <T> logRamUsage(message: String, block: suspend () -> T): T
runtime.gc()
val freeMemoryInMb = runtime.freeMemory() / 1048576L
val usedMemInMBStart = runtime.totalMemory() / 1048576L - freeMemoryInMb
Timber.v("$message -- BEGIN (free memory: $freeMemoryInMb MB)")
Timber.d("$message -- BEGIN (free memory: $freeMemoryInMb MB)")
val result = block()
runtime.gc()
val usedMemInMBEnd = (runtime.totalMemory() - runtime.freeMemory()) / 1048576L
val usedMemInMBDiff = usedMemInMBEnd - usedMemInMBStart
Timber.v("$message -- END RAM usage: $usedMemInMBDiff MB")
Timber.d("$message -- END RAM usage: $usedMemInMBDiff MB")
result
} else {
block()

View file

@ -14,7 +14,7 @@ kapt {
// Note: 2 digits max for each value
ext.versionMajor = 1
ext.versionMinor = 1
ext.versionPatch = 2
ext.versionPatch = 3
static def getGitTimestamp() {
def cmd = 'git show -s --format=%ct'

View file

@ -3,7 +3,6 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?riotx_background"
android:padding="8dp">
<View
@ -12,16 +11,16 @@
android:layout_gravity="center_vertical"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:background="?riotx_header_panel_background" />
android:background="?riotx_list_bottom_sheet_divider_color" />
<TextView
android:id="@+id/itemDayTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:background="?riotx_background"
android:paddingStart="32dp"
android:paddingEnd="32dp"
android:background="?android:attr/windowBackground"
android:paddingStart="24dp"
android:paddingEnd="24dp"
android:textColor="?riotx_header_panel_text_secondary"
android:textSize="15sp"
tools:text="@tools:sample/date/day_of_week" />

View file

@ -3,6 +3,7 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:addStatesFromChildren="true"
android:orientation="vertical">
<TextView

View file

@ -2,7 +2,6 @@
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?riotx_background"
android:padding="8dp">
<View
@ -17,10 +16,10 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:background="?riotx_background"
android:background="?android:attr/windowBackground"
android:fontFamily="sans-serif-medium"
android:paddingStart="8dp"
android:paddingEnd="8dp"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:text="@string/timeline_unread_messages"
android:textColor="@color/notification_accent_color"
android:textSize="15sp" />