From 28c4abb505930d649b76a83930d847ca277ad424 Mon Sep 17 00:00:00 2001 From: Michael Kaye <1917473+michaelkaye@users.noreply.github.com> Date: Thu, 19 May 2022 10:34:38 +0100 Subject: [PATCH 01/14] Track number of retries of tests, and retry KeysBackupTest --- .../java/org/matrix/android/sdk/common/RetryTestRule.kt | 3 +++ .../android/sdk/internal/crypto/keysbackup/KeysBackupTest.kt | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/RetryTestRule.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/RetryTestRule.kt index b16ab98e6c..80ccf578e5 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/RetryTestRule.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/RetryTestRule.kt @@ -40,6 +40,9 @@ class RetryTestRule(val retryCount: Int = 3) : TestRule { for (i in 0 until retryCount) { try { base.evaluate() + if(i > 0) { + println("Retried test $i times") + } return } catch (t: Throwable) { caughtThrowable = t diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupTest.kt index 9136272b1e..d5fd299f1f 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupTest.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupTest.kt @@ -24,6 +24,7 @@ import org.junit.Assert.assertNotNull import org.junit.Assert.assertNull import org.junit.Assert.assertTrue import org.junit.FixMethodOrder +import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith import org.junit.runners.MethodSorters @@ -45,6 +46,7 @@ import org.matrix.android.sdk.api.session.crypto.model.ImportRoomKeysResult import org.matrix.android.sdk.api.session.getRoom import org.matrix.android.sdk.common.CommonTestHelper import org.matrix.android.sdk.common.CryptoTestHelper +import org.matrix.android.sdk.common.RetryTestRule import org.matrix.android.sdk.common.TestConstants import org.matrix.android.sdk.common.TestMatrixCallback import java.util.Collections @@ -55,6 +57,8 @@ import java.util.concurrent.CountDownLatch @LargeTest class KeysBackupTest : InstrumentedTest { + @get:Rule val rule = RetryTestRule(3) + /** * - From doE2ETestWithAliceAndBobInARoomWithEncryptedMessages, we should have no backed up keys * - Check backup keys after having marked one as backed up From fe793798fafa174323c4cd8b8461651abb056e1d Mon Sep 17 00:00:00 2001 From: Michael Kaye <1917473+michaelkaye@users.noreply.github.com> Date: Thu, 19 May 2022 12:06:54 +0100 Subject: [PATCH 02/14] Ignore E2eeSanityTests. They fail infrequently, but in a way that takes the entire test framework down, so ignore them for now and open an issue to fix. --- .../org/matrix/android/sdk/internal/crypto/E2eeSanityTests.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/E2eeSanityTests.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/E2eeSanityTests.kt index 38597269cb..5e740a79ee 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/E2eeSanityTests.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/E2eeSanityTests.kt @@ -23,6 +23,7 @@ import org.amshove.kluent.fail import org.amshove.kluent.internal.assertEquals import org.junit.Assert import org.junit.FixMethodOrder +import org.junit.Ignore import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith @@ -67,6 +68,7 @@ import java.util.concurrent.CountDownLatch @RunWith(JUnit4::class) @FixMethodOrder(MethodSorters.JVM) @LargeTest +@Ignore("This test fails with an unhandled exception thrown from a coroutine which terminates the entire test run.") class E2eeSanityTests : InstrumentedTest { @get:Rule val rule = RetryTestRule(3) From a4fa65b4fdf79e7baf38ab8f515c7f17f7eeec3c Mon Sep 17 00:00:00 2001 From: Michael Kaye <1917473+michaelkaye@users.noreply.github.com> Date: Thu, 19 May 2022 12:37:41 +0100 Subject: [PATCH 03/14] Fix linting --- .../java/org/matrix/android/sdk/common/RetryTestRule.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/RetryTestRule.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/RetryTestRule.kt index 80ccf578e5..39f49a9ccc 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/RetryTestRule.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/RetryTestRule.kt @@ -40,7 +40,7 @@ class RetryTestRule(val retryCount: Int = 3) : TestRule { for (i in 0 until retryCount) { try { base.evaluate() - if(i > 0) { + if (i > 0) { println("Retried test $i times") } return From 695c234139cd27e22478cf792464b3bb403f59d7 Mon Sep 17 00:00:00 2001 From: Maxime NATUREL Date: Mon, 23 May 2022 12:02:43 +0200 Subject: [PATCH 04/14] Adding changelog entry --- changelog.d/6123.wip | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/6123.wip diff --git a/changelog.d/6123.wip b/changelog.d/6123.wip new file mode 100644 index 0000000000..680498280f --- /dev/null +++ b/changelog.d/6123.wip @@ -0,0 +1 @@ +[Live location sharing] Update entity in DB when a live is timed out From d76b93ced302ac92346bc0c4cafae04bcd55b594 Mon Sep 17 00:00:00 2001 From: Maxime NATUREL Date: Mon, 23 May 2022 14:26:23 +0200 Subject: [PATCH 05/14] Adding comment on isActive field --- .../model/livelocation/LiveLocationShareAggregatedSummary.kt | 3 +++ .../livelocation/LiveLocationShareAggregatedSummaryEntity.kt | 3 +++ 2 files changed, 6 insertions(+) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/livelocation/LiveLocationShareAggregatedSummary.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/livelocation/LiveLocationShareAggregatedSummary.kt index 0b28d62f56..059fe21471 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/livelocation/LiveLocationShareAggregatedSummary.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/livelocation/LiveLocationShareAggregatedSummary.kt @@ -22,6 +22,9 @@ import org.matrix.android.sdk.api.session.room.model.message.MessageBeaconLocati * Aggregation info concerning a live location share. */ data class LiveLocationShareAggregatedSummary( + /** + * Indicate whether the live is currently running. + */ val isActive: Boolean?, val endOfLiveTimestampMillis: Long?, val lastLocationDataContent: MessageBeaconLocationDataContent?, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/livelocation/LiveLocationShareAggregatedSummaryEntity.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/livelocation/LiveLocationShareAggregatedSummaryEntity.kt index 4d0d2c5c64..e84337693f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/livelocation/LiveLocationShareAggregatedSummaryEntity.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/livelocation/LiveLocationShareAggregatedSummaryEntity.kt @@ -31,6 +31,9 @@ internal open class LiveLocationShareAggregatedSummaryEntity( var roomId: String = "", + /** + * Indicate whether the live is currently running. + */ var isActive: Boolean? = null, var endOfLiveTimestampMillis: Long? = null, From 47eb7173f0c773b1c0dd174e1faca83b997e9d31 Mon Sep 17 00:00:00 2001 From: Maxime NATUREL Date: Mon, 23 May 2022 15:15:45 +0200 Subject: [PATCH 06/14] Creation of a worker to deactivate a live after timeout --- .../sdk/internal/session/SessionComponent.kt | 3 + .../DeactivateLiveLocationShareWorker.kt | 89 +++++++++++++++++++ .../internal/worker/MatrixWorkerFactory.kt | 7 +- 3 files changed, 97 insertions(+), 2 deletions(-) create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/livelocation/DeactivateLiveLocationShareWorker.kt diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionComponent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionComponent.kt index 050480e6c9..1e3566f49e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionComponent.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionComponent.kt @@ -46,6 +46,7 @@ import org.matrix.android.sdk.internal.session.profile.ProfileModule import org.matrix.android.sdk.internal.session.pushers.AddPusherWorker import org.matrix.android.sdk.internal.session.pushers.PushersModule import org.matrix.android.sdk.internal.session.room.RoomModule +import org.matrix.android.sdk.internal.session.room.aggregation.livelocation.DeactivateLiveLocationShareWorker import org.matrix.android.sdk.internal.session.room.send.MultipleEventSendingDispatcherWorker import org.matrix.android.sdk.internal.session.room.send.RedactEventWorker import org.matrix.android.sdk.internal.session.room.send.SendEventWorker @@ -131,6 +132,8 @@ internal interface SessionComponent { fun inject(worker: UpdateTrustWorker) + fun inject(worker: DeactivateLiveLocationShareWorker) + @Component.Factory interface Factory { fun create( diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/livelocation/DeactivateLiveLocationShareWorker.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/livelocation/DeactivateLiveLocationShareWorker.kt new file mode 100644 index 0000000000..14fc1566d8 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/livelocation/DeactivateLiveLocationShareWorker.kt @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2022 The Matrix.org Foundation C.I.C. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.matrix.android.sdk.internal.session.room.aggregation.livelocation + +import android.content.Context +import androidx.work.WorkerParameters +import com.squareup.moshi.JsonClass +import io.realm.RealmConfiguration +import org.matrix.android.sdk.internal.SessionManager +import org.matrix.android.sdk.internal.database.awaitTransaction +import org.matrix.android.sdk.internal.database.model.livelocation.LiveLocationShareAggregatedSummaryEntity +import org.matrix.android.sdk.internal.database.query.getOrCreate +import org.matrix.android.sdk.internal.di.SessionDatabase +import org.matrix.android.sdk.internal.session.SessionComponent +import org.matrix.android.sdk.internal.worker.SessionSafeCoroutineWorker +import org.matrix.android.sdk.internal.worker.SessionWorkerParams +import timber.log.Timber +import javax.inject.Inject + +/** + * Worker dedicated to update live location summary data so that it is considered as deactivated. + * For the context: it is needed since a live location share should be deactivated after a certain timeout. + */ +internal class DeactivateLiveLocationShareWorker(context: Context, params: WorkerParameters, sessionManager: SessionManager) : + SessionSafeCoroutineWorker( + context, + params, + sessionManager, + Params::class.java + ) { + + @JsonClass(generateAdapter = true) + internal data class Params( + override val sessionId: String, + override val lastFailureMessage: String? = null, + val eventId: String, + val roomId: String + ) : SessionWorkerParams + + @SessionDatabase + @Inject lateinit var realmConfiguration: RealmConfiguration + + override fun injectWith(injector: SessionComponent) { + injector.inject(this) + } + + override suspend fun doSafeWork(params: Params): Result { + return runCatching { + deactivateLiveLocationShare(params) + }.fold( + onSuccess = { + Result.success() + }, + onFailure = { + Timber.e("failed to deactivate live, eventId: ${params.eventId}, roomId: ${params.roomId}") + Result.failure() + } + ) + } + + private suspend fun deactivateLiveLocationShare(params: Params) { + awaitTransaction(realmConfiguration) { realm -> + val aggregatedSummary = LiveLocationShareAggregatedSummaryEntity.getOrCreate( + realm = realm, + roomId = params.roomId, + eventId = params.eventId + ) + aggregatedSummary.isActive = false + } + } + + override fun buildErrorParams(params: Params, message: String): Params { + return params.copy(lastFailureMessage = params.lastFailureMessage ?: message) + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/worker/MatrixWorkerFactory.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/worker/MatrixWorkerFactory.kt index 95b3662c67..a8ef3e0748 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/worker/MatrixWorkerFactory.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/worker/MatrixWorkerFactory.kt @@ -27,6 +27,7 @@ import org.matrix.android.sdk.internal.di.MatrixScope import org.matrix.android.sdk.internal.session.content.UploadContentWorker import org.matrix.android.sdk.internal.session.group.GetGroupDataWorker import org.matrix.android.sdk.internal.session.pushers.AddPusherWorker +import org.matrix.android.sdk.internal.session.room.aggregation.livelocation.DeactivateLiveLocationShareWorker import org.matrix.android.sdk.internal.session.room.send.MultipleEventSendingDispatcherWorker import org.matrix.android.sdk.internal.session.room.send.RedactEventWorker import org.matrix.android.sdk.internal.session.room.send.SendEventWorker @@ -64,9 +65,11 @@ internal class MatrixWorkerFactory @Inject constructor(private val sessionManage SyncWorker(appContext, workerParameters, sessionManager) UpdateTrustWorker::class.java.name -> UpdateTrustWorker(appContext, workerParameters, sessionManager) - UploadContentWorker::class.java.name -> + UploadContentWorker::class.java.name -> UploadContentWorker(appContext, workerParameters, sessionManager) - else -> { + DeactivateLiveLocationShareWorker::class.java.name -> + DeactivateLiveLocationShareWorker(appContext, workerParameters, sessionManager) + else -> { Timber.w("No worker defined on MatrixWorkerFactory for $workerClassName will delegate to default.") // Return null to delegate to the default WorkerFactory. null From 683a9cdfff319d16cf4d5a347b87a6f847005728 Mon Sep 17 00:00:00 2001 From: Maxime NATUREL Date: Mon, 23 May 2022 15:53:25 +0200 Subject: [PATCH 07/14] Schedule work during aggregation --- .../DeactivateLiveLocationShareWorker.kt | 6 +++ .../LiveLocationAggregationProcessor.kt | 50 +++++++++++++++++-- 2 files changed, 52 insertions(+), 4 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/livelocation/DeactivateLiveLocationShareWorker.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/livelocation/DeactivateLiveLocationShareWorker.kt index 14fc1566d8..6461b90435 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/livelocation/DeactivateLiveLocationShareWorker.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/livelocation/DeactivateLiveLocationShareWorker.kt @@ -86,4 +86,10 @@ internal class DeactivateLiveLocationShareWorker(context: Context, params: Worke override fun buildErrorParams(params: Params, message: String): Params { return params.copy(lastFailureMessage = params.lastFailureMessage ?: message) } + + companion object { + private const val WORK_NAME_PREFIX = "DeactivateLiveLocationWork-" + + fun getWorkName(eventId: String, roomId: String) = "${WORK_NAME_PREFIX}$eventId-$roomId" + } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/livelocation/LiveLocationAggregationProcessor.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/livelocation/LiveLocationAggregationProcessor.kt index 76b7a4ec8e..74e8ce8be2 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/livelocation/LiveLocationAggregationProcessor.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/livelocation/LiveLocationAggregationProcessor.kt @@ -16,6 +16,7 @@ package org.matrix.android.sdk.internal.session.room.aggregation.livelocation +import androidx.work.ExistingWorkPolicy import io.realm.Realm import org.matrix.android.sdk.api.extensions.orTrue import org.matrix.android.sdk.api.session.events.model.Event @@ -26,17 +27,27 @@ import org.matrix.android.sdk.api.session.room.model.message.MessageBeaconLocati import org.matrix.android.sdk.internal.database.mapper.ContentMapper import org.matrix.android.sdk.internal.database.model.livelocation.LiveLocationShareAggregatedSummaryEntity import org.matrix.android.sdk.internal.database.query.getOrCreate +import org.matrix.android.sdk.internal.di.SessionId +import org.matrix.android.sdk.internal.di.WorkManagerProvider +import org.matrix.android.sdk.internal.util.time.Clock +import org.matrix.android.sdk.internal.worker.WorkerParamsFactory import timber.log.Timber +import java.util.concurrent.TimeUnit import javax.inject.Inject -internal class LiveLocationAggregationProcessor @Inject constructor() { +internal class LiveLocationAggregationProcessor @Inject constructor( + @SessionId private val sessionId: String, + private val workManagerProvider: WorkManagerProvider, + private val clock: Clock, +) { fun handleBeaconInfo(realm: Realm, event: Event, content: MessageBeaconInfoContent, roomId: String, isLocalEcho: Boolean) { if (event.senderId.isNullOrEmpty() || isLocalEcho) { return } - val targetEventId = if (content.isLive.orTrue()) { + val isLive = content.isLive.orTrue() + val targetEventId = if (isLive) { event.eventId } else { // when live is set to false, we use the id of the event that should have been replaced @@ -56,8 +67,39 @@ internal class LiveLocationAggregationProcessor @Inject constructor() { Timber.d("updating summary of id=$targetEventId with isLive=${content.isLive}") - aggregatedSummary.endOfLiveTimestampMillis = content.getBestTimestampMillis()?.let { it + (content.timeout ?: 0) } - aggregatedSummary.isActive = content.isLive + val endOfLiveTimestampMillis = content.getBestTimestampMillis()?.let { it + (content.timeout ?: 0) } + aggregatedSummary.endOfLiveTimestampMillis = endOfLiveTimestampMillis + aggregatedSummary.isActive = isLive + + if (isLive) { + scheduleDeactivationAfterTimeout(targetEventId, roomId, endOfLiveTimestampMillis) + } else { + cancelDeactivationAfterTimeout(targetEventId, roomId) + } + } + + private fun scheduleDeactivationAfterTimeout(eventId: String, roomId: String, endOfLiveTimestampMillis: Long?) { + endOfLiveTimestampMillis?.let { endOfLiveMillis -> + val workParams = DeactivateLiveLocationShareWorker.Params(sessionId = sessionId, eventId = eventId, roomId = roomId) + val workData = WorkerParamsFactory.toData(workParams) + val workName = DeactivateLiveLocationShareWorker.getWorkName(eventId = eventId, roomId = roomId) + val workDelayMillis = (endOfLiveMillis - clock.epochMillis()).coerceAtLeast(0) + val workRequest = workManagerProvider.matrixOneTimeWorkRequestBuilder() + .setInitialDelay(workDelayMillis, TimeUnit.MILLISECONDS) + .setInputData(workData) + .build() + + workManagerProvider.workManager.enqueueUniqueWork( + workName, + ExistingWorkPolicy.KEEP, + workRequest + ) + } + } + + private fun cancelDeactivationAfterTimeout(eventId: String, roomId: String) { + val workName = DeactivateLiveLocationShareWorker.getWorkName(eventId = eventId, roomId = roomId) + workManagerProvider.workManager.cancelUniqueWork(workName) } fun handleBeaconLocationData( From b05fc763aec15fc142e6727c01cea09244c96177 Mon Sep 17 00:00:00 2001 From: Maxime NATUREL Date: Mon, 23 May 2022 16:06:48 +0200 Subject: [PATCH 08/14] Rely only on isActive field on UI side --- .../factory/LiveLocationShareMessageItemFactory.kt | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/LiveLocationShareMessageItemFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/LiveLocationShareMessageItemFactory.kt index 912702aaed..3c7b6c32e1 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/LiveLocationShareMessageItemFactory.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/LiveLocationShareMessageItemFactory.kt @@ -33,7 +33,6 @@ import im.vector.app.features.home.room.detail.timeline.item.MessageLiveLocation import im.vector.app.features.location.INITIAL_MAP_ZOOM_IN_TIMELINE import im.vector.app.features.location.UrlMapProvider import im.vector.app.features.location.toLocationData -import org.matrix.android.sdk.api.extensions.orFalse import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent import org.threeten.bp.LocalDateTime @@ -129,7 +128,7 @@ class LiveLocationShareMessageItemFactory @Inject constructor( private fun getViewState(liveLocationShareSummaryData: LiveLocationShareSummaryData?): LiveLocationShareViewState { return when { liveLocationShareSummaryData?.isActive == null -> LiveLocationShareViewState.Unkwown - liveLocationShareSummaryData.isActive.not() || isLiveTimedOut(liveLocationShareSummaryData) -> LiveLocationShareViewState.Inactive + liveLocationShareSummaryData.isActive.not() -> LiveLocationShareViewState.Inactive liveLocationShareSummaryData.isActive && liveLocationShareSummaryData.lastGeoUri.isNullOrEmpty() -> LiveLocationShareViewState.Loading else -> LiveLocationShareViewState.Running( @@ -139,16 +138,6 @@ class LiveLocationShareMessageItemFactory @Inject constructor( }.also { viewState -> Timber.d("computed viewState: $viewState") } } - private fun isLiveTimedOut(liveLocationShareSummaryData: LiveLocationShareSummaryData): Boolean { - return getEndOfLiveDateTime(liveLocationShareSummaryData) - ?.let { endOfLive -> - // this will only cover users with different timezones but not users with manually time set - val now = LocalDateTime.now() - now.isAfter(endOfLive) - } - .orFalse() - } - private fun getEndOfLiveDateTime(liveLocationShareSummaryData: LiveLocationShareSummaryData): LocalDateTime? { return liveLocationShareSummaryData.endOfLiveTimestampMillis?.let { DateProvider.toLocalDateTime(timestamp = it) } } From f95853a7b3c103854f6c29f65218f3ed0ead78df Mon Sep 17 00:00:00 2001 From: Johannes Marbach Date: Tue, 24 May 2022 16:28:56 +0200 Subject: [PATCH 09/14] Prevent widget web view from reloading on screen / orientation change (PSF-1034) Signed-off-by: Johannes Marbach --- vector/src/main/AndroidManifest.xml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/vector/src/main/AndroidManifest.xml b/vector/src/main/AndroidManifest.xml index fc78ce90a3..8c2e25bc7e 100644 --- a/vector/src/main/AndroidManifest.xml +++ b/vector/src/main/AndroidManifest.xml @@ -306,7 +306,9 @@ android:supportsPictureInPicture="true" /> - + + From 7913a42664e1a3c6c658aa74bce1a682530a1b32 Mon Sep 17 00:00:00 2001 From: Johannes Marbach Date: Tue, 24 May 2022 16:36:26 +0200 Subject: [PATCH 10/14] Add changelog file --- changelog.d/6140.bugfix | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/6140.bugfix diff --git a/changelog.d/6140.bugfix b/changelog.d/6140.bugfix new file mode 100644 index 0000000000..247e69f837 --- /dev/null +++ b/changelog.d/6140.bugfix @@ -0,0 +1 @@ +Prevent widget web view from reloading on screen / orientation change From b081429725637a74d0daa6df2f48602b96a33882 Mon Sep 17 00:00:00 2001 From: Maxime NATUREL Date: Wed, 25 May 2022 10:59:08 +0200 Subject: [PATCH 11/14] Replace getOrCreate() by get() in worker --- .../LiveLocationShareAggregatedSummaryEntityQuery.kt | 8 ++++++++ .../livelocation/DeactivateLiveLocationShareWorker.kt | 6 +++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/LiveLocationShareAggregatedSummaryEntityQuery.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/LiveLocationShareAggregatedSummaryEntityQuery.kt index 2e2e939fa2..816b5f4392 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/LiveLocationShareAggregatedSummaryEntityQuery.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/LiveLocationShareAggregatedSummaryEntityQuery.kt @@ -55,3 +55,11 @@ internal fun LiveLocationShareAggregatedSummaryEntity.Companion.getOrCreate( return LiveLocationShareAggregatedSummaryEntity.where(realm, roomId, eventId).findFirst() ?: LiveLocationShareAggregatedSummaryEntity.create(realm, roomId, eventId) } + +internal fun LiveLocationShareAggregatedSummaryEntity.Companion.get( + realm: Realm, + roomId: String, + eventId: String, +): LiveLocationShareAggregatedSummaryEntity? { + return LiveLocationShareAggregatedSummaryEntity.where(realm, roomId, eventId).findFirst() +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/livelocation/DeactivateLiveLocationShareWorker.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/livelocation/DeactivateLiveLocationShareWorker.kt index 6461b90435..a437975668 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/livelocation/DeactivateLiveLocationShareWorker.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/livelocation/DeactivateLiveLocationShareWorker.kt @@ -23,7 +23,7 @@ import io.realm.RealmConfiguration import org.matrix.android.sdk.internal.SessionManager import org.matrix.android.sdk.internal.database.awaitTransaction import org.matrix.android.sdk.internal.database.model.livelocation.LiveLocationShareAggregatedSummaryEntity -import org.matrix.android.sdk.internal.database.query.getOrCreate +import org.matrix.android.sdk.internal.database.query.get import org.matrix.android.sdk.internal.di.SessionDatabase import org.matrix.android.sdk.internal.session.SessionComponent import org.matrix.android.sdk.internal.worker.SessionSafeCoroutineWorker @@ -74,12 +74,12 @@ internal class DeactivateLiveLocationShareWorker(context: Context, params: Worke private suspend fun deactivateLiveLocationShare(params: Params) { awaitTransaction(realmConfiguration) { realm -> - val aggregatedSummary = LiveLocationShareAggregatedSummaryEntity.getOrCreate( + val aggregatedSummary = LiveLocationShareAggregatedSummaryEntity.get( realm = realm, roomId = params.roomId, eventId = params.eventId ) - aggregatedSummary.isActive = false + aggregatedSummary?.isActive = false } } From cfdc18d421df0e311b299cf267d2f040e96561ea Mon Sep 17 00:00:00 2001 From: Maxime NATUREL Date: Wed, 25 May 2022 11:05:28 +0200 Subject: [PATCH 12/14] Improve code readability in aggregation processor --- .../LiveLocationAggregationProcessor.kt | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/livelocation/LiveLocationAggregationProcessor.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/livelocation/LiveLocationAggregationProcessor.kt index 74e8ce8be2..b9529143a6 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/livelocation/LiveLocationAggregationProcessor.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/livelocation/LiveLocationAggregationProcessor.kt @@ -79,22 +79,22 @@ internal class LiveLocationAggregationProcessor @Inject constructor( } private fun scheduleDeactivationAfterTimeout(eventId: String, roomId: String, endOfLiveTimestampMillis: Long?) { - endOfLiveTimestampMillis?.let { endOfLiveMillis -> - val workParams = DeactivateLiveLocationShareWorker.Params(sessionId = sessionId, eventId = eventId, roomId = roomId) - val workData = WorkerParamsFactory.toData(workParams) - val workName = DeactivateLiveLocationShareWorker.getWorkName(eventId = eventId, roomId = roomId) - val workDelayMillis = (endOfLiveMillis - clock.epochMillis()).coerceAtLeast(0) - val workRequest = workManagerProvider.matrixOneTimeWorkRequestBuilder() - .setInitialDelay(workDelayMillis, TimeUnit.MILLISECONDS) - .setInputData(workData) - .build() + endOfLiveTimestampMillis ?: return - workManagerProvider.workManager.enqueueUniqueWork( - workName, - ExistingWorkPolicy.KEEP, - workRequest - ) - } + val workParams = DeactivateLiveLocationShareWorker.Params(sessionId = sessionId, eventId = eventId, roomId = roomId) + val workData = WorkerParamsFactory.toData(workParams) + val workName = DeactivateLiveLocationShareWorker.getWorkName(eventId = eventId, roomId = roomId) + val workDelayMillis = (endOfLiveTimestampMillis - clock.epochMillis()).coerceAtLeast(0) + val workRequest = workManagerProvider.matrixOneTimeWorkRequestBuilder() + .setInitialDelay(workDelayMillis, TimeUnit.MILLISECONDS) + .setInputData(workData) + .build() + + workManagerProvider.workManager.enqueueUniqueWork( + workName, + ExistingWorkPolicy.KEEP, + workRequest + ) } private fun cancelDeactivationAfterTimeout(eventId: String, roomId: String) { From 8864a3cf2c460964f4e63f74c4c6e1a6ea4f1fb2 Mon Sep 17 00:00:00 2001 From: Maxime NATUREL Date: Wed, 25 May 2022 11:06:02 +0200 Subject: [PATCH 13/14] Using replace instead of keep strategy for the worker --- .../livelocation/LiveLocationAggregationProcessor.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/livelocation/LiveLocationAggregationProcessor.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/livelocation/LiveLocationAggregationProcessor.kt index b9529143a6..42dfc7ba9f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/livelocation/LiveLocationAggregationProcessor.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/livelocation/LiveLocationAggregationProcessor.kt @@ -92,7 +92,7 @@ internal class LiveLocationAggregationProcessor @Inject constructor( workManagerProvider.workManager.enqueueUniqueWork( workName, - ExistingWorkPolicy.KEEP, + ExistingWorkPolicy.REPLACE, workRequest ) } From 791d4fb1e87e517d9bbde7eb3bff6877ff72b3e3 Mon Sep 17 00:00:00 2001 From: Maxime NATUREL Date: Wed, 25 May 2022 11:10:54 +0200 Subject: [PATCH 14/14] Improve computation of the work name to limit its length --- .../livelocation/DeactivateLiveLocationShareWorker.kt | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/livelocation/DeactivateLiveLocationShareWorker.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/livelocation/DeactivateLiveLocationShareWorker.kt index a437975668..2b83c8028b 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/livelocation/DeactivateLiveLocationShareWorker.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/livelocation/DeactivateLiveLocationShareWorker.kt @@ -20,6 +20,7 @@ import android.content.Context import androidx.work.WorkerParameters import com.squareup.moshi.JsonClass import io.realm.RealmConfiguration +import org.matrix.android.sdk.api.util.md5 import org.matrix.android.sdk.internal.SessionManager import org.matrix.android.sdk.internal.database.awaitTransaction import org.matrix.android.sdk.internal.database.model.livelocation.LiveLocationShareAggregatedSummaryEntity @@ -88,8 +89,9 @@ internal class DeactivateLiveLocationShareWorker(context: Context, params: Worke } companion object { - private const val WORK_NAME_PREFIX = "DeactivateLiveLocationWork-" - - fun getWorkName(eventId: String, roomId: String) = "${WORK_NAME_PREFIX}$eventId-$roomId" + fun getWorkName(eventId: String, roomId: String): String { + val hash = "$eventId$roomId".md5() + return "DeactivateLiveLocationWork-$hash" + } } }