diff --git a/.github/ISSUE_TEMPLATE/release.yml b/.github/ISSUE_TEMPLATE/release.yml index 7cb47fa952..f012900752 100644 --- a/.github/ISSUE_TEMPLATE/release.yml +++ b/.github/ISSUE_TEMPLATE/release.yml @@ -49,24 +49,34 @@ body: ### Once tested and validated internally - - [ ] Create a new beta release on the GooglePlay console and upload the 4 signed Apks. + - [ ] Create a new open testing release on the GooglePlay console and upload the 4 signed Apks. - [ ] Check that the version codes are correct - [ ] Copy the fastlane change to the GooglePlay console in the section en-GB. - - [ ] Push to beta release to 100% of the users - - [ ] Notify the F-Droid team so that they can schedule the publication on F-Droid + - [ ] Push the open testing release to 100% of the users + - [ ] Notify the F-Droid team [here](https://matrix.to/#/!LAAuJLQXYHjMNWKrCK:matrix.org?via=matrix.org&via=bubu1.eu&via=lant.uk) so that they can schedule the publication on F-Droid + - [ ] The application is available to the PlayStore testers (live). Google can take between 1 hour and up to 7 days to approve the release. + - [ ] The application is available to the F-Droid users. - ### Once Live on PlayStore + ### Once open testing is live on PlayStore - [ ] Ping the Android public room and update its topic - - [ ] Add an entry in the internal diary - ### After at least 2 days + ### Once Live on F-Droid + + - [ ] Update the Android public room topic + + ### After at least 2 days (generally next Monday) - [ ] Check the [rageshakes](https://github.com/matrix-org/element-android-rageshakes/issues) - [ ] Check the crash reports on the GooglePlay console - [ ] Check the Android Element room for any reported issues on the new version - - [ ] If all is OK, push to production and notify Markus (Bubu) to release the F-Droid version - - [ ] Ping the Android public room and update its topic with the new available version + - [ ] If all is OK, promote the open testing release to production. Generally using a 100% roll out, but can be a smaller value depending on the release content. + - [ ] The application is available to the PlayStore users (live). Google can take (again!) between 1 hour and up to 7 days to approve the release. + + ### Once production is live on PlayStore + + - [ ] Ping the Android public room and update its topic + - [ ] Add an entry in the internal diary ### Android SDK2 diff --git a/build.gradle b/build.gradle index 03e175927c..22d6f5f5ef 100644 --- a/build.gradle +++ b/build.gradle @@ -43,7 +43,7 @@ plugins { id "io.gitlab.arturbosch.detekt" version "1.20.0" // Dependency Analysis - id 'com.autonomousapps.dependency-analysis' version "1.4.0" + id 'com.autonomousapps.dependency-analysis' version "1.5.0" } // https://github.com/jeremylong/DependencyCheck diff --git a/changelog.d/6029.sdk b/changelog.d/6029.sdk new file mode 100644 index 0000000000..b39d1a6359 --- /dev/null +++ b/changelog.d/6029.sdk @@ -0,0 +1,5 @@ +Some methods from `Session` have been moved to a new `SyncService`, that you can retrieve from a `Session`. +- `SyncStatusService` method has been moved to the new `SyncService` +- `InitSyncStep` have been moved and renamed to `InitialSyncStep` +- `SyncStatusService.Status` has been renamed to `SyncRequestState` +- The existing `SyncService` has been renamed to `SyncAndroidService` because of name clash with the new SDK Service diff --git a/changelog.d/6209.bugfix b/changelog.d/6209.bugfix new file mode 100644 index 0000000000..3eac2c9df6 --- /dev/null +++ b/changelog.d/6209.bugfix @@ -0,0 +1 @@ +Fix wrong status of live location sharing in timeline diff --git a/changelog.d/6244.feature b/changelog.d/6244.feature new file mode 100644 index 0000000000..9b02187112 --- /dev/null +++ b/changelog.d/6244.feature @@ -0,0 +1 @@ +Re-organize location settings flags diff --git a/dependencies.gradle b/dependencies.gradle index dcffb06da6..451ad4449b 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -50,7 +50,7 @@ ext.libs = [ androidx : [ 'activity' : "androidx.activity:activity:1.4.0", 'appCompat' : "androidx.appcompat:appcompat:1.4.2", - 'core' : "androidx.core:core-ktx:1.7.0", + 'core' : "androidx.core:core-ktx:1.8.0", 'recyclerview' : "androidx.recyclerview:recyclerview:1.2.1", 'exifinterface' : "androidx.exifinterface:exifinterface:1.3.3", 'fragmentKtx' : "androidx.fragment:fragment-ktx:1.4.1", diff --git a/matrix-sdk-android-flow/src/main/java/org/matrix/android/sdk/flow/FlowSession.kt b/matrix-sdk-android-flow/src/main/java/org/matrix/android/sdk/flow/FlowSession.kt index 2839e6ab61..1086928dc6 100644 --- a/matrix-sdk-android-flow/src/main/java/org/matrix/android/sdk/flow/FlowSession.kt +++ b/matrix-sdk-android-flow/src/main/java/org/matrix/android/sdk/flow/FlowSession.kt @@ -88,7 +88,7 @@ class FlowSession(private val session: Session) { } fun liveSyncState(): Flow { - return session.getSyncStateLive().asFlow() + return session.syncService().getSyncStateLive().asFlow() } fun livePushers(): Flow> { diff --git a/matrix-sdk-android/build.gradle b/matrix-sdk-android/build.gradle index fbed8442a9..ec376effbe 100644 --- a/matrix-sdk-android/build.gradle +++ b/matrix-sdk-android/build.gradle @@ -176,7 +176,7 @@ dependencies { implementation libs.androidx.work // olm lib is now hosted in MavenCentral - implementation 'org.matrix.android:olm-sdk:3.2.11' + implementation 'org.matrix.android:olm-sdk:3.2.12' // DI implementation libs.dagger.dagger diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CommonTestHelper.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CommonTestHelper.kt index 9160130bfa..7dafe33935 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CommonTestHelper.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CommonTestHelper.kt @@ -137,11 +137,11 @@ class CommonTestHelper private constructor(context: Context) { fun syncSession(session: Session, timeout: Long = TestConstants.timeOutMillis * 10) { val lock = CountDownLatch(1) coroutineScope.launch { - session.startSync(true) - val syncLiveData = session.getSyncStateLive() + session.syncService().startSync(true) + val syncLiveData = session.syncService().getSyncStateLive() val syncObserver = object : Observer { override fun onChanged(t: SyncState?) { - if (session.hasAlreadySynced()) { + if (session.syncService().hasAlreadySynced()) { lock.countDown() syncLiveData.removeObserver(this) } @@ -160,10 +160,10 @@ class CommonTestHelper private constructor(context: Context) { fun clearCacheAndSync(session: Session, timeout: Long = TestConstants.timeOutMillis) { waitWithLatch(timeout) { latch -> session.clearCache() - val syncLiveData = session.getSyncStateLive() + val syncLiveData = session.syncService().getSyncStateLive() val syncObserver = object : Observer { override fun onChanged(t: SyncState?) { - if (session.hasAlreadySynced()) { + if (session.syncService().hasAlreadySynced()) { Timber.v("Clear cache and synced") syncLiveData.removeObserver(this) latch.countDown() @@ -171,7 +171,7 @@ class CommonTestHelper private constructor(context: Context) { } } syncLiveData.observeForever(syncObserver) - session.startSync(true) + session.syncService().startSync(true) } } diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/KeyShareTests.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/KeyShareTests.kt index 994a055e5a..7bb53e139c 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/KeyShareTests.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/KeyShareTests.kt @@ -424,7 +424,7 @@ class KeyShareTests : InstrumentedTest { // /!\ Stop initial alice session syncing so that it can't reply aliceSession.cryptoService().enableKeyGossiping(false) - aliceSession.stopSync() + aliceSession.syncService().stopSync() // Let's now try to request aliceNewSession.cryptoService().reRequestRoomKeyForEvent(sentEvents.first().root) @@ -447,7 +447,7 @@ class KeyShareTests : InstrumentedTest { // let's wake up alice aliceSession.cryptoService().enableKeyGossiping(true) - aliceSession.startSync(true) + aliceSession.syncService().startSync(true) // We should now get a reply from first session commonTestHelper.waitWithLatch { latch -> diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/session/room/threads/ThreadMessagingTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/session/room/threads/ThreadMessagingTest.kt index 1ffcc2a3e6..45bd38870d 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/session/room/threads/ThreadMessagingTest.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/session/room/threads/ThreadMessagingTest.kt @@ -83,7 +83,7 @@ class ThreadMessagingTest : InstrumentedTest { val timeline = aliceRoom.timelineService().createTimeline(null, TimelineSettings(30)) timeline.start() - aliceSession.startSync(true) + aliceSession.syncService().startSync(true) run { val lock = CountDownLatch(1) val eventsListener = commonTestHelper.createEventListener(lock) { snapshot -> @@ -97,7 +97,7 @@ class ThreadMessagingTest : InstrumentedTest { timeline.addListener(eventsListener) commonTestHelper.await(lock, 600_000) } - aliceSession.stopSync() + aliceSession.syncService().stopSync() } @Test @@ -144,7 +144,7 @@ class ThreadMessagingTest : InstrumentedTest { val timeline = aliceRoom.timelineService().createTimeline(null, TimelineSettings(30)) timeline.start() - aliceSession.startSync(true) + aliceSession.syncService().startSync(true) run { val lock = CountDownLatch(1) val eventsListener = commonTestHelper.createEventListener(lock) { snapshot -> @@ -156,9 +156,9 @@ class ThreadMessagingTest : InstrumentedTest { timeline.addListener(eventsListener) commonTestHelper.await(lock, 600_000) } - aliceSession.stopSync() + aliceSession.syncService().stopSync() - bobSession.startSync(true) + bobSession.syncService().startSync(true) run { val lock = CountDownLatch(1) val eventsListener = commonTestHelper.createEventListener(lock) { snapshot -> @@ -170,7 +170,7 @@ class ThreadMessagingTest : InstrumentedTest { timeline.addListener(eventsListener) commonTestHelper.await(lock, 600_000) } - bobSession.stopSync() + bobSession.syncService().stopSync() } @Test @@ -217,7 +217,7 @@ class ThreadMessagingTest : InstrumentedTest { val timeline = aliceRoom.timelineService().createTimeline(null, TimelineSettings(30)) timeline.start() - aliceSession.startSync(true) + aliceSession.syncService().startSync(true) run { val lock = CountDownLatch(1) val eventsListener = commonTestHelper.createEventListener(lock) { snapshot -> @@ -233,7 +233,7 @@ class ThreadMessagingTest : InstrumentedTest { timeline.addListener(eventsListener) commonTestHelper.await(lock, 600_000) } - aliceSession.stopSync() + aliceSession.syncService().stopSync() } @Test @@ -314,7 +314,7 @@ class ThreadMessagingTest : InstrumentedTest { val timeline = aliceRoom.timelineService().createTimeline(null, TimelineSettings(30)) timeline.start() - aliceSession.startSync(true) + aliceSession.syncService().startSync(true) run { val lock = CountDownLatch(1) val eventsListener = commonTestHelper.createEventListener(lock) { snapshot -> @@ -338,6 +338,6 @@ class ThreadMessagingTest : InstrumentedTest { timeline.addListener(eventsListener) commonTestHelper.await(lock, 600_000) } - aliceSession.stopSync() + aliceSession.syncService().stopSync() } } diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/session/room/timeline/PollAggregationTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/session/room/timeline/PollAggregationTest.kt index 4b90849a1f..a37d2ce015 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/session/room/timeline/PollAggregationTest.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/session/room/timeline/PollAggregationTest.kt @@ -57,7 +57,7 @@ class PollAggregationTest : InstrumentedTest { // Bob creates a poll roomFromBobPOV.sendService().sendPoll(PollType.DISCLOSED, pollQuestion, pollOptions) - aliceSession.startSync(true) + aliceSession.syncService().startSync(true) val aliceTimeline = roomFromAlicePOV.timelineService().createTimeline(null, TimelineSettings(30)) aliceTimeline.start() @@ -133,7 +133,7 @@ class PollAggregationTest : InstrumentedTest { aliceTimeline.removeAllListeners() - aliceSession.stopSync() + aliceSession.syncService().stopSync() aliceTimeline.dispose() } diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/session/room/timeline/TimelinePreviousLastForwardTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/session/room/timeline/TimelinePreviousLastForwardTest.kt index 3ff4572add..03ab6e6767 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/session/room/timeline/TimelinePreviousLastForwardTest.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/session/room/timeline/TimelinePreviousLastForwardTest.kt @@ -88,7 +88,7 @@ class TimelinePreviousLastForwardTest : InstrumentedTest { } // Bob stop to sync - bobSession.stopSync() + bobSession.syncService().stopSync() val firstMessage = "First messages from Alice" // Alice sends 30 messages @@ -101,7 +101,7 @@ class TimelinePreviousLastForwardTest : InstrumentedTest { .eventId // Bob start to sync - bobSession.startSync(true) + bobSession.syncService().startSync(true) run { val lock = CountDownLatch(1) @@ -125,7 +125,7 @@ class TimelinePreviousLastForwardTest : InstrumentedTest { } // Bob stop to sync - bobSession.stopSync() + bobSession.syncService().stopSync() val secondMessage = "Second messages from Alice" // Alice sends again 30 messages @@ -136,7 +136,7 @@ class TimelinePreviousLastForwardTest : InstrumentedTest { ) // Bob start to sync - bobSession.startSync(true) + bobSession.syncService().startSync(true) run { val lock = CountDownLatch(1) diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/session/room/timeline/TimelineWithManyMembersTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/session/room/timeline/TimelineWithManyMembersTest.kt index 87f404b0f1..27ea0e1c3c 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/session/room/timeline/TimelineWithManyMembersTest.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/session/room/timeline/TimelineWithManyMembersTest.kt @@ -71,7 +71,7 @@ class TimelineWithManyMembersTest : InstrumentedTest { val timelineForCurrentMember = roomForCurrentMember.timelineService().createTimeline(null, TimelineSettings(30)) timelineForCurrentMember.start() - session.startSync(true) + session.syncService().startSync(true) run { val lock = CountDownLatch(1) @@ -92,7 +92,7 @@ class TimelineWithManyMembersTest : InstrumentedTest { timelineForCurrentMember.addListener(eventsListener) commonTestHelper.await(lock, 600_000) } - session.stopSync() + session.syncService().stopSync() } } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/Session.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/Session.kt index 2f1ae8cd87..b3a629094c 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/Session.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/Session.kt @@ -17,8 +17,6 @@ package org.matrix.android.sdk.api.session import androidx.annotation.MainThread -import androidx.lifecycle.LiveData -import kotlinx.coroutines.flow.SharedFlow import okhttp3.OkHttpClient import org.matrix.android.sdk.api.MatrixCoroutineDispatchers import org.matrix.android.sdk.api.auth.data.SessionParams @@ -37,7 +35,6 @@ import org.matrix.android.sdk.api.session.file.FileService import org.matrix.android.sdk.api.session.group.GroupService import org.matrix.android.sdk.api.session.homeserver.HomeServerCapabilitiesService import org.matrix.android.sdk.api.session.identity.IdentityService -import org.matrix.android.sdk.api.session.initsync.SyncStatusService import org.matrix.android.sdk.api.session.integrationmanager.IntegrationManagerService import org.matrix.android.sdk.api.session.media.MediaService import org.matrix.android.sdk.api.session.openid.OpenIdService @@ -55,8 +52,7 @@ import org.matrix.android.sdk.api.session.signout.SignOutService import org.matrix.android.sdk.api.session.space.SpaceService import org.matrix.android.sdk.api.session.statistics.StatisticsListener import org.matrix.android.sdk.api.session.sync.FilterService -import org.matrix.android.sdk.api.session.sync.SyncState -import org.matrix.android.sdk.api.session.sync.model.SyncResponse +import org.matrix.android.sdk.api.session.sync.SyncService import org.matrix.android.sdk.api.session.terms.TermsService import org.matrix.android.sdk.api.session.thirdparty.ThirdPartyService import org.matrix.android.sdk.api.session.typing.TypingUsersTracker @@ -98,59 +94,11 @@ interface Session { @MainThread fun open() - /** - * Requires a one time background sync. - */ - fun requireBackgroundSync() - - /** - * Launches infinite self rescheduling background syncs via the WorkManager. - * - * While dozing, syncs will only occur during maintenance windows. - * For reliability it's recommended to also start a long running foreground service - * along with disabling battery optimizations. - */ - fun startAutomaticBackgroundSync(timeOutInSeconds: Long, repeatDelayInSeconds: Long) - - fun stopAnyBackgroundSync() - - /** - * This method start the sync thread. - */ - fun startSync(fromForeground: Boolean) - - /** - * This method stop the sync thread. - */ - fun stopSync() - /** * Clear cache of the session. */ suspend fun clearCache() - /** - * This method allows to listen the sync state. - * @return a [LiveData] of [SyncState]. - */ - fun getSyncStateLive(): LiveData - - /** - * This method returns the current sync state. - * @return the current [SyncState]. - */ - fun getSyncState(): SyncState - - /** - * This method returns a flow of SyncResponse. New value will be pushed through the sync thread. - */ - fun syncFlow(): SharedFlow - - /** - * This methods return true if an initial sync has been processed. - */ - fun hasAlreadySynced(): Boolean - /** * This method allow to close a session. It does stop some services. */ @@ -247,9 +195,9 @@ interface Session { fun termsService(): TermsService /** - * Returns the SyncStatusService associated with the session. + * Returns the SyncService associated with the session. */ - fun syncStatusService(): SyncStatusService + fun syncService(): SyncService /** * Returns the SecureStorageService associated with the session. diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/initsync/SyncStatusService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/initsync/SyncStatusService.kt deleted file mode 100644 index 7006e11751..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/initsync/SyncStatusService.kt +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2020 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.api.session.initsync - -import androidx.lifecycle.LiveData - -interface SyncStatusService { - - fun getSyncStatusLive(): LiveData - - sealed class Status { - /** - * For initial sync. - */ - abstract class InitialSyncStatus : Status() - - object Idle : InitialSyncStatus() - data class InitialSyncProgressing( - val initSyncStep: InitSyncStep, - val percentProgress: Int = 0 - ) : InitialSyncStatus() - - /** - * For incremental sync. - */ - abstract class IncrementalSyncStatus : Status() - - object IncrementalSyncIdle : IncrementalSyncStatus() - data class IncrementalSyncParsing( - val rooms: Int, - val toDevice: Int - ) : IncrementalSyncStatus() - - object IncrementalSyncError : IncrementalSyncStatus() - object IncrementalSyncDone : IncrementalSyncStatus() - } -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/initsync/InitSyncStep.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/InitialSyncStep.kt similarity index 91% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/initsync/InitSyncStep.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/InitialSyncStep.kt index 901c1b2ffb..407585b003 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/initsync/InitSyncStep.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/InitialSyncStep.kt @@ -14,9 +14,9 @@ * limitations under the License. */ -package org.matrix.android.sdk.api.session.initsync +package org.matrix.android.sdk.api.session.sync -enum class InitSyncStep { +enum class InitialSyncStep { ServerComputing, Downloading, ImportingAccount, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/SyncRequestState.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/SyncRequestState.kt new file mode 100644 index 0000000000..4e932d49de --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/SyncRequestState.kt @@ -0,0 +1,44 @@ +/* + * 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.api.session.sync + +sealed interface SyncRequestState { + /** + * For initial sync. + */ + interface InitialSyncRequestState : SyncRequestState + + object Idle : InitialSyncRequestState + data class InitialSyncProgressing( + val initialSyncStep: InitialSyncStep, + val percentProgress: Int = 0 + ) : InitialSyncRequestState + + /** + * For incremental sync. + */ + interface IncrementalSyncRequestState : SyncRequestState + + object IncrementalSyncIdle : IncrementalSyncRequestState + data class IncrementalSyncParsing( + val rooms: Int, + val toDevice: Int + ) : IncrementalSyncRequestState + + object IncrementalSyncError : IncrementalSyncRequestState + object IncrementalSyncDone : IncrementalSyncRequestState +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/SyncService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/SyncService.kt new file mode 100644 index 0000000000..5b2bf651af --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/SyncService.kt @@ -0,0 +1,76 @@ +/* + * Copyright 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.api.session.sync + +import androidx.lifecycle.LiveData +import kotlinx.coroutines.flow.SharedFlow +import org.matrix.android.sdk.api.session.sync.model.SyncResponse + +interface SyncService { + /** + * This method start the sync thread. + */ + fun startSync(fromForeground: Boolean) + + /** + * This method stop the sync thread. + */ + fun stopSync() + + /** + * Requires a one time background sync. + */ + fun requireBackgroundSync() + + /** + * Launches infinite self rescheduling background syncs via the WorkManager. + * + * While dozing, syncs will only occur during maintenance windows. + * For reliability it's recommended to also start a long running foreground service + * along with disabling battery optimizations. + */ + fun startAutomaticBackgroundSync(timeOutInSeconds: Long, repeatDelayInSeconds: Long) + + fun stopAnyBackgroundSync() + + /** + * This method returns the current sync state. + * @return the current [SyncState]. + */ + fun getSyncState(): SyncState + + /** + * This method allows to listen the sync state. + * @return a [LiveData] of [SyncState]. + */ + fun getSyncStateLive(): LiveData + + /** + * Get the [SyncRequestState] as a LiveData. + */ + fun getSyncRequestStateLive(): LiveData + + /** + * This method returns a flow of SyncResponse. New value will be pushed through the sync thread. + */ + fun syncFlow(): SharedFlow + + /** + * This methods return true if an initial sync has been processed. + */ + fun hasAlreadySynced(): Boolean +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/job/SyncService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/job/SyncAndroidService.kt similarity index 97% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/job/SyncService.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/job/SyncAndroidService.kt index 7d4780585f..8dee633b9c 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/job/SyncService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/job/SyncAndroidService.kt @@ -46,7 +46,7 @@ import java.util.concurrent.atomic.AtomicBoolean * in order to be able to perform a sync even if the app is not running. * The and must be declared in the Manifest or the app using the SDK */ -abstract class SyncService : Service() { +abstract class SyncAndroidService : Service() { private var sessionId: String? = null private var mIsSelfDestroyed: Boolean = false @@ -158,9 +158,9 @@ abstract class SyncService : Service() { // never do that in foreground, let the syncThread work syncTask.execute(params) // Start sync if we were doing an initial sync and the syncThread is not launched yet - if (isInitialSync && session.getSyncState() == SyncState.Idle) { + if (isInitialSync && session.syncService().getSyncState() == SyncState.Idle) { val isForeground = !backgroundDetectionObserver.isInBackground - session.startSync(isForeground) + session.syncService().startSync(isForeground) } stopMe() } catch (throwable: Throwable) { @@ -210,7 +210,7 @@ abstract class SyncService : Service() { session = sessionComponent.session() sessionId = safeSessionId syncTask = sessionComponent.syncTask() - isInitialSync = !session.hasAlreadySynced() + isInitialSync = !session.syncService().hasAlreadySynced() networkConnectivityChecker = sessionComponent.networkConnectivityChecker() taskExecutor = sessionComponent.taskExecutor() coroutineDispatchers = sessionComponent.coroutineDispatchers() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/SessionManager.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/SessionManager.kt index 1950c62995..bd2dac9e3c 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/SessionManager.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/SessionManager.kt @@ -55,7 +55,7 @@ internal class SessionManager @Inject constructor( fun stopSession(sessionId: String) { val sessionComponent = sessionComponents[sessionId] ?: throw RuntimeException("You don't have a session for id $sessionId") - sessionComponent.session().stopSync() + sessionComponent.session().syncService().stopSync() } fun getOrCreateSessionComponent(sessionParams: SessionParams): SessionComponent { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/DefaultSession.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/DefaultSession.kt index 5f77cfb23a..32269c9afd 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/DefaultSession.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/DefaultSession.kt @@ -44,7 +44,6 @@ import org.matrix.android.sdk.api.session.file.FileService import org.matrix.android.sdk.api.session.group.GroupService import org.matrix.android.sdk.api.session.homeserver.HomeServerCapabilitiesService import org.matrix.android.sdk.api.session.identity.IdentityService -import org.matrix.android.sdk.api.session.initsync.SyncStatusService import org.matrix.android.sdk.api.session.integrationmanager.IntegrationManagerService import org.matrix.android.sdk.api.session.media.MediaService import org.matrix.android.sdk.api.session.openid.OpenIdService @@ -61,6 +60,7 @@ import org.matrix.android.sdk.api.session.securestorage.SharedSecretStorageServi import org.matrix.android.sdk.api.session.signout.SignOutService import org.matrix.android.sdk.api.session.space.SpaceService import org.matrix.android.sdk.api.session.sync.FilterService +import org.matrix.android.sdk.api.session.sync.SyncService import org.matrix.android.sdk.api.session.terms.TermsService import org.matrix.android.sdk.api.session.thirdparty.ThirdPartyService import org.matrix.android.sdk.api.session.typing.TypingUsersTracker @@ -76,13 +76,8 @@ import org.matrix.android.sdk.internal.di.SessionId import org.matrix.android.sdk.internal.di.UnauthenticatedWithCertificate import org.matrix.android.sdk.internal.di.WorkManagerProvider import org.matrix.android.sdk.internal.network.GlobalErrorHandler -import org.matrix.android.sdk.internal.session.sync.SyncTokenStore -import org.matrix.android.sdk.internal.session.sync.job.SyncThread -import org.matrix.android.sdk.internal.session.sync.job.SyncWorker import org.matrix.android.sdk.internal.util.createUIHandler -import timber.log.Timber import javax.inject.Inject -import javax.inject.Provider @SessionScope internal class DefaultSession @Inject constructor( @@ -112,16 +107,14 @@ internal class DefaultSession @Inject constructor( private val permalinkService: Lazy, private val secureStorageService: Lazy, private val profileService: Lazy, + private val syncService: Lazy, private val mediaService: Lazy, private val widgetService: Lazy, - private val syncThreadProvider: Provider, private val contentUrlResolver: ContentUrlResolver, - private val syncTokenStore: SyncTokenStore, private val sessionParamsStore: SessionParamsStore, private val contentUploadProgressTracker: ContentUploadStateTracker, private val typingUsersTracker: TypingUsersTracker, private val contentDownloadStateTracker: ContentDownloadStateTracker, - private val syncStatusService: Lazy, private val homeServerCapabilitiesService: Lazy, private val accountDataService: Lazy, private val sharedSecretStorageService: Lazy, @@ -138,14 +131,11 @@ internal class DefaultSession @Inject constructor( private val toDeviceService: Lazy, private val eventStreamService: Lazy, @UnauthenticatedWithCertificate - private val unauthenticatedWithCertificateOkHttpClient: Lazy + private val unauthenticatedWithCertificateOkHttpClient: Lazy, + private val sessionState: SessionState, ) : Session, GlobalErrorHandler.Listener { - private var isOpen = false - - private var syncThread: SyncThread? = null - private val uiHandler = createUIHandler() override val isOpenable: Boolean @@ -153,8 +143,7 @@ internal class DefaultSession @Inject constructor( @MainThread override fun open() { - assert(!isOpen) - isOpen = true + sessionState.setIsOpen(true) globalErrorHandler.listener = this cryptoService.get().ensureDevice() uiHandler.post { @@ -167,40 +156,9 @@ internal class DefaultSession @Inject constructor( } } - override fun requireBackgroundSync() { - SyncWorker.requireBackgroundSync(workManagerProvider, sessionId) - } - - override fun startAutomaticBackgroundSync(timeOutInSeconds: Long, repeatDelayInSeconds: Long) { - SyncWorker.automaticallyBackgroundSync(workManagerProvider, sessionId, timeOutInSeconds, repeatDelayInSeconds) - } - - override fun stopAnyBackgroundSync() { - SyncWorker.stopAnyBackgroundSync(workManagerProvider) - } - - override fun startSync(fromForeground: Boolean) { - Timber.i("Starting sync thread") - assert(isOpen) - val localSyncThread = getSyncThread() - localSyncThread.setInitialForeground(fromForeground) - if (!localSyncThread.isAlive) { - localSyncThread.start() - } else { - localSyncThread.restart() - Timber.w("Attempt to start an already started thread") - } - } - - override fun stopSync() { - assert(isOpen) - syncThread?.kill() - syncThread = null - } - override fun close() { - assert(isOpen) - stopSync() + assert(sessionState.isOpen) + syncService.get().stopSync() // timelineEventDecryptor.destroy() uiHandler.post { lifecycleObservers.forEach { it.onSessionStopped(this) } @@ -210,28 +168,12 @@ internal class DefaultSession @Inject constructor( } cryptoService.get().close() globalErrorHandler.listener = null - isOpen = false - } - - override fun getSyncStateLive() = getSyncThread().liveState() - - override fun syncFlow() = getSyncThread().syncFlow() - - override fun getSyncState() = getSyncThread().currentState() - - override fun hasAlreadySynced(): Boolean { - return syncTokenStore.getLastToken() != null - } - - private fun getSyncThread(): SyncThread { - return syncThread ?: syncThreadProvider.get().also { - syncThread = it - } + sessionState.setIsOpen(false) } override suspend fun clearCache() { - stopSync() - stopAnyBackgroundSync() + syncService.get().stopSync() + syncService.get().stopAnyBackgroundSync() uiHandler.post { lifecycleObservers.forEach { it.onClearCache(this) @@ -271,7 +213,7 @@ internal class DefaultSession @Inject constructor( override fun pushersService(): PushersService = pushersService.get() override fun eventService(): EventService = eventService.get() override fun termsService(): TermsService = termsService.get() - override fun syncStatusService(): SyncStatusService = syncStatusService.get() + override fun syncService(): SyncService = syncService.get() override fun secureStorageService(): SecureStorageService = secureStorageService.get() override fun profileService(): ProfileService = profileService.get() override fun presenceService(): PresenceService = presenceService.get() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionModule.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionModule.kt index b35a95d687..2c2317de0d 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionModule.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionModule.kt @@ -39,7 +39,6 @@ import org.matrix.android.sdk.api.session.ToDeviceService import org.matrix.android.sdk.api.session.accountdata.SessionAccountDataService import org.matrix.android.sdk.api.session.events.EventService import org.matrix.android.sdk.api.session.homeserver.HomeServerCapabilitiesService -import org.matrix.android.sdk.api.session.initsync.SyncStatusService import org.matrix.android.sdk.api.session.openid.OpenIdService import org.matrix.android.sdk.api.session.permalinks.PermalinkService import org.matrix.android.sdk.api.session.securestorage.SecureStorageService @@ -82,7 +81,6 @@ import org.matrix.android.sdk.internal.session.download.DownloadProgressIntercep import org.matrix.android.sdk.internal.session.events.DefaultEventService import org.matrix.android.sdk.internal.session.homeserver.DefaultHomeServerCapabilitiesService import org.matrix.android.sdk.internal.session.identity.DefaultIdentityService -import org.matrix.android.sdk.internal.session.initsync.DefaultSyncStatusService import org.matrix.android.sdk.internal.session.integrationmanager.IntegrationManager import org.matrix.android.sdk.internal.session.openid.DefaultOpenIdService import org.matrix.android.sdk.internal.session.permalinks.DefaultPermalinkService @@ -362,9 +360,6 @@ internal abstract class SessionModule { @IntoSet abstract fun bindEventSenderProcessorAsSessionLifecycleObserver(processor: EventSenderProcessorCoroutine): SessionLifecycleObserver - @Binds - abstract fun bindSyncStatusService(service: DefaultSyncStatusService): SyncStatusService - @Binds abstract fun bindSecureStorageService(service: DefaultSecureStorageService): SecureStorageService diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionState.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionState.kt new file mode 100644 index 0000000000..b109a9aa60 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionState.kt @@ -0,0 +1,33 @@ +/* + * 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 + +import javax.inject.Inject + +@SessionScope +internal class SessionState @Inject constructor() { + var isOpen = false + private set + + /** + * Set the new state. Throw if already in the new state. + */ + fun setIsOpen(newState: Boolean) { + assert(newState != isOpen) + isOpen = newState + } +} 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 2b83c8028b..b17753b25a 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 @@ -75,6 +75,7 @@ internal class DeactivateLiveLocationShareWorker(context: Context, params: Worke private suspend fun deactivateLiveLocationShare(params: Params) { awaitTransaction(realmConfiguration) { realm -> + Timber.d("deactivating live with id=${params.eventId}") val aggregatedSummary = LiveLocationShareAggregatedSummaryEntity.get( realm = realm, roomId = params.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 8f4682a9d5..05bde8f83f 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 @@ -67,16 +67,18 @@ internal class LiveLocationAggregationProcessor @Inject constructor( eventId = targetEventId ) - Timber.d("updating summary of id=$targetEventId with isLive=${content.isLive}") - + // remote event can stay with isLive == true while the local summary is no more active + val isActive = aggregatedSummary.isActive.orTrue() && isLive val endOfLiveTimestampMillis = content.getBestTimestampMillis()?.let { it + (content.timeout ?: 0) } + Timber.d("updating summary of id=$targetEventId with isActive=$isActive and endTimestamp=$endOfLiveTimestampMillis") + aggregatedSummary.endOfLiveTimestampMillis = endOfLiveTimestampMillis - aggregatedSummary.isActive = isLive + aggregatedSummary.isActive = isActive aggregatedSummary.userId = event.senderId deactivateAllPreviousBeacons(realm, roomId, event.senderId, targetEventId) - if (isLive) { + if (isActive) { scheduleDeactivationAfterTimeout(targetEventId, roomId, endOfLiveTimestampMillis) } else { cancelDeactivationAfterTimeout(targetEventId, roomId) @@ -90,6 +92,7 @@ internal class LiveLocationAggregationProcessor @Inject constructor( val workData = WorkerParamsFactory.toData(workParams) val workName = DeactivateLiveLocationShareWorker.getWorkName(eventId = eventId, roomId = roomId) val workDelayMillis = (endOfLiveTimestampMillis - clock.epochMillis()).coerceAtLeast(0) + Timber.d("scheduling deactivation of $eventId after $workDelayMillis millis") val workRequest = workManagerProvider.matrixOneTimeWorkRequestBuilder() .setInitialDelay(workDelayMillis, TimeUnit.MILLISECONDS) .setInputData(workData) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/DefaultSyncService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/DefaultSyncService.kt new file mode 100644 index 0000000000..37869b88f9 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/DefaultSyncService.kt @@ -0,0 +1,91 @@ +/* + * 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.sync + +import androidx.lifecycle.LiveData +import org.matrix.android.sdk.api.session.sync.SyncRequestState +import org.matrix.android.sdk.api.session.sync.SyncService +import org.matrix.android.sdk.internal.di.SessionId +import org.matrix.android.sdk.internal.di.WorkManagerProvider +import org.matrix.android.sdk.internal.session.SessionState +import org.matrix.android.sdk.internal.session.sync.job.SyncThread +import org.matrix.android.sdk.internal.session.sync.job.SyncWorker +import timber.log.Timber +import javax.inject.Inject +import javax.inject.Provider + +internal class DefaultSyncService @Inject constructor( + @SessionId val sessionId: String, + private val workManagerProvider: WorkManagerProvider, + private val syncThreadProvider: Provider, + private val syncTokenStore: SyncTokenStore, + private val syncRequestStateTracker: SyncRequestStateTracker, + private val sessionState: SessionState, +) : SyncService { + private var syncThread: SyncThread? = null + + override fun requireBackgroundSync() { + SyncWorker.requireBackgroundSync(workManagerProvider, sessionId) + } + + override fun startAutomaticBackgroundSync(timeOutInSeconds: Long, repeatDelayInSeconds: Long) { + SyncWorker.automaticallyBackgroundSync(workManagerProvider, sessionId, timeOutInSeconds, repeatDelayInSeconds) + } + + override fun stopAnyBackgroundSync() { + SyncWorker.stopAnyBackgroundSync(workManagerProvider) + } + + override fun startSync(fromForeground: Boolean) { + Timber.i("Starting sync thread") + assert(sessionState.isOpen) + val localSyncThread = getSyncThread() + localSyncThread.setInitialForeground(fromForeground) + if (!localSyncThread.isAlive) { + localSyncThread.start() + } else { + localSyncThread.restart() + Timber.w("Attempt to start an already started thread") + } + } + + override fun stopSync() { + assert(sessionState.isOpen) + syncThread?.kill() + syncThread = null + } + + override fun getSyncStateLive() = getSyncThread().liveState() + + override fun syncFlow() = getSyncThread().syncFlow() + + override fun getSyncState() = getSyncThread().currentState() + + override fun getSyncRequestStateLive(): LiveData { + return syncRequestStateTracker.syncRequestState + } + + override fun hasAlreadySynced(): Boolean { + return syncTokenStore.getLastToken() != null + } + + private fun getSyncThread(): SyncThread { + return syncThread ?: syncThreadProvider.get().also { + syncThread = it + } + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/initsync/Extensions.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/Extensions.kt similarity index 78% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/initsync/Extensions.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/Extensions.kt index d98590f052..ae542103b7 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/initsync/Extensions.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/Extensions.kt @@ -14,18 +14,18 @@ * limitations under the License. */ -package org.matrix.android.sdk.internal.session.initsync +package org.matrix.android.sdk.internal.session.sync -import org.matrix.android.sdk.api.session.initsync.InitSyncStep +import org.matrix.android.sdk.api.session.sync.InitialSyncStep internal inline fun reportSubtask( reporter: ProgressReporter?, - initSyncStep: InitSyncStep, + initialSyncStep: InitialSyncStep, totalProgress: Int, parentWeight: Float, block: () -> T ): T { - reporter?.startTask(initSyncStep, totalProgress, parentWeight) + reporter?.startTask(initialSyncStep, totalProgress, parentWeight) return block().also { reporter?.endTask() } @@ -33,12 +33,12 @@ internal inline fun reportSubtask( internal inline fun Map.mapWithProgress( reporter: ProgressReporter?, - initSyncStep: InitSyncStep, + initialSyncStep: InitialSyncStep, parentWeight: Float, transform: (Map.Entry) -> R ): List { var current = 0F - reporter?.startTask(initSyncStep, count() + 1, parentWeight) + reporter?.startTask(initialSyncStep, count() + 1, parentWeight) return map { reporter?.reportProgress(current) current++ diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/initsync/ProgressReporter.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/ProgressReporter.kt similarity index 83% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/initsync/ProgressReporter.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/ProgressReporter.kt index d608a5aa85..6d77b9be5e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/initsync/ProgressReporter.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/ProgressReporter.kt @@ -14,13 +14,13 @@ * limitations under the License. */ -package org.matrix.android.sdk.internal.session.initsync +package org.matrix.android.sdk.internal.session.sync -import org.matrix.android.sdk.api.session.initsync.InitSyncStep +import org.matrix.android.sdk.api.session.sync.InitialSyncStep internal interface ProgressReporter { fun startTask( - initSyncStep: InitSyncStep, + initialSyncStep: InitialSyncStep, totalProgress: Int, parentWeight: Float ) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncModule.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncModule.kt index 4b31dc4d9b..d78070439c 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncModule.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncModule.kt @@ -19,6 +19,7 @@ package org.matrix.android.sdk.internal.session.sync import dagger.Binds import dagger.Module import dagger.Provides +import org.matrix.android.sdk.api.session.sync.SyncService import org.matrix.android.sdk.internal.session.SessionScope import retrofit2.Retrofit @@ -35,6 +36,9 @@ internal abstract class SyncModule { } } + @Binds + abstract fun bindSyncService(service: DefaultSyncService): SyncService + @Binds abstract fun bindSyncTask(task: DefaultSyncTask): SyncTask diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/initsync/DefaultSyncStatusService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncRequestStateTracker.kt similarity index 68% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/initsync/DefaultSyncStatusService.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncRequestStateTracker.kt index c6e15733d5..bcc5fcf9ab 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/initsync/DefaultSyncStatusService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncRequestStateTracker.kt @@ -13,42 +13,37 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.matrix.android.sdk.internal.session.initsync -import androidx.lifecycle.LiveData +package org.matrix.android.sdk.internal.session.sync + import androidx.lifecycle.MutableLiveData -import org.matrix.android.sdk.api.session.initsync.InitSyncStep -import org.matrix.android.sdk.api.session.initsync.SyncStatusService +import org.matrix.android.sdk.api.session.sync.InitialSyncStep +import org.matrix.android.sdk.api.session.sync.SyncRequestState import org.matrix.android.sdk.internal.session.SessionScope import javax.inject.Inject @SessionScope -internal class DefaultSyncStatusService @Inject constructor() : - SyncStatusService, +internal class SyncRequestStateTracker @Inject constructor() : ProgressReporter { - private val status = MutableLiveData() + val syncRequestState = MutableLiveData() private var rootTask: TaskInfo? = null - override fun getSyncStatusLive(): LiveData { - return status - } - // Only to be used for incremental sync - fun setStatus(newStatus: SyncStatusService.Status.IncrementalSyncStatus) { - status.postValue(newStatus) + fun setSyncRequestState(newSyncRequestState: SyncRequestState.IncrementalSyncRequestState) { + syncRequestState.postValue(newSyncRequestState) } /** * Create a rootTask. */ fun startRoot( - initSyncStep: InitSyncStep, + initialSyncStep: InitialSyncStep, totalProgress: Int ) { endAll() - rootTask = TaskInfo(initSyncStep, totalProgress, null, 1F) + rootTask = TaskInfo(initialSyncStep, totalProgress, null, 1F) reportProgress(0F) } @@ -56,13 +51,13 @@ internal class DefaultSyncStatusService @Inject constructor() : * Add a child to the leaf. */ override fun startTask( - initSyncStep: InitSyncStep, + initialSyncStep: InitialSyncStep, totalProgress: Int, parentWeight: Float ) { val currentLeaf = rootTask?.leaf() ?: return currentLeaf.child = TaskInfo( - initSyncStep = initSyncStep, + initialSyncStep = initialSyncStep, totalProgress = totalProgress, parent = currentLeaf, parentWeight = parentWeight @@ -76,7 +71,7 @@ internal class DefaultSyncStatusService @Inject constructor() : // Update the progress of the leaf and all its parents leaf.setProgress(progress) // Then update the live data using leaf wording and root progress - status.postValue(SyncStatusService.Status.InitialSyncProgressing(leaf.initSyncStep, root.currentProgress.toInt())) + syncRequestState.postValue(SyncRequestState.InitialSyncProgressing(leaf.initialSyncStep, root.currentProgress.toInt())) } } } @@ -91,13 +86,13 @@ internal class DefaultSyncStatusService @Inject constructor() : // And close it endedTask.parent.child = null } else { - status.postValue(SyncStatusService.Status.Idle) + syncRequestState.postValue(SyncRequestState.Idle) } } } fun endAll() { rootTask = null - status.postValue(SyncStatusService.Status.Idle) + syncRequestState.postValue(SyncRequestState.Idle) } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncResponseHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncResponseHandler.kt index 9bdcc4e5d4..9e5302222a 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncResponseHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncResponseHandler.kt @@ -18,9 +18,9 @@ package org.matrix.android.sdk.internal.session.sync import androidx.work.ExistingPeriodicWorkPolicy import com.zhuinden.monarchy.Monarchy -import org.matrix.android.sdk.api.session.initsync.InitSyncStep import org.matrix.android.sdk.api.session.pushrules.PushRuleService import org.matrix.android.sdk.api.session.pushrules.RuleScope +import org.matrix.android.sdk.api.session.sync.InitialSyncStep import org.matrix.android.sdk.api.session.sync.model.GroupsSyncResponse import org.matrix.android.sdk.api.session.sync.model.RoomsSyncResponse import org.matrix.android.sdk.api.session.sync.model.SyncResponse @@ -32,8 +32,6 @@ import org.matrix.android.sdk.internal.di.WorkManagerProvider import org.matrix.android.sdk.internal.session.SessionListeners import org.matrix.android.sdk.internal.session.dispatchTo import org.matrix.android.sdk.internal.session.group.GetGroupDataWorker -import org.matrix.android.sdk.internal.session.initsync.ProgressReporter -import org.matrix.android.sdk.internal.session.initsync.reportSubtask import org.matrix.android.sdk.internal.session.pushrules.ProcessEventForPushTask import org.matrix.android.sdk.internal.session.sync.handler.CryptoSyncHandler import org.matrix.android.sdk.internal.session.sync.handler.GroupSyncHandler @@ -90,7 +88,7 @@ internal class SyncResponseHandler @Inject constructor( // to ensure to decrypt them properly measureTimeMillis { Timber.v("Handle toDevice") - reportSubtask(reporter, InitSyncStep.ImportingAccountCrypto, 100, 0.1f) { + reportSubtask(reporter, InitialSyncStep.ImportingAccountCrypto, 100, 0.1f) { if (syncResponse.toDevice != null) { cryptoSyncHandler.handleToDevice(syncResponse.toDevice, reporter) } @@ -111,7 +109,7 @@ internal class SyncResponseHandler @Inject constructor( // IMPORTANT nothing should be suspend here as we are accessing the realm instance (thread local) measureTimeMillis { Timber.v("Handle rooms") - reportSubtask(reporter, InitSyncStep.ImportingAccountRoom, 1, 0.7f) { + reportSubtask(reporter, InitialSyncStep.ImportingAccountRoom, 1, 0.7f) { if (syncResponse.rooms != null) { roomSyncHandler.handle(realm, syncResponse.rooms, isInitialSync, aggregator, reporter) } @@ -121,7 +119,7 @@ internal class SyncResponseHandler @Inject constructor( } measureTimeMillis { - reportSubtask(reporter, InitSyncStep.ImportingAccountGroups, 1, 0.1f) { + reportSubtask(reporter, InitialSyncStep.ImportingAccountGroups, 1, 0.1f) { Timber.v("Handle groups") if (syncResponse.groups != null) { groupSyncHandler.handle(realm, syncResponse.groups, reporter) @@ -132,7 +130,7 @@ internal class SyncResponseHandler @Inject constructor( } measureTimeMillis { - reportSubtask(reporter, InitSyncStep.ImportingAccountData, 1, 0.1f) { + reportSubtask(reporter, InitialSyncStep.ImportingAccountData, 1, 0.1f) { Timber.v("Handle accountData") userAccountDataSyncHandler.handle(realm, syncResponse.accountData) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncTask.kt index f88d973101..ea296d379d 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncTask.kt @@ -21,10 +21,10 @@ import okhttp3.ResponseBody import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.api.logger.LoggerTag import org.matrix.android.sdk.api.session.Session -import org.matrix.android.sdk.api.session.initsync.InitSyncStep -import org.matrix.android.sdk.api.session.initsync.SyncStatusService import org.matrix.android.sdk.api.session.statistics.StatisticEvent +import org.matrix.android.sdk.api.session.sync.InitialSyncStep import org.matrix.android.sdk.api.session.sync.InitialSyncStrategy +import org.matrix.android.sdk.api.session.sync.SyncRequestState import org.matrix.android.sdk.api.session.sync.initialSyncStrategy import org.matrix.android.sdk.api.session.sync.model.LazyRoomSyncEphemeral import org.matrix.android.sdk.api.session.sync.model.SyncResponse @@ -38,8 +38,6 @@ import org.matrix.android.sdk.internal.session.SessionListeners import org.matrix.android.sdk.internal.session.dispatchTo import org.matrix.android.sdk.internal.session.filter.FilterRepository import org.matrix.android.sdk.internal.session.homeserver.GetHomeServerCapabilitiesTask -import org.matrix.android.sdk.internal.session.initsync.DefaultSyncStatusService -import org.matrix.android.sdk.internal.session.initsync.reportSubtask import org.matrix.android.sdk.internal.session.sync.parsing.InitialSyncResponseParser import org.matrix.android.sdk.internal.session.user.UserStore import org.matrix.android.sdk.internal.task.Task @@ -68,7 +66,7 @@ internal class DefaultSyncTask @Inject constructor( @UserId private val userId: String, private val filterRepository: FilterRepository, private val syncResponseHandler: SyncResponseHandler, - private val defaultSyncStatusService: DefaultSyncStatusService, + private val syncRequestStateTracker: SyncRequestStateTracker, private val syncTokenStore: SyncTokenStore, private val getHomeServerCapabilitiesTask: GetHomeServerCapabilitiesTask, private val userStore: UserStore, @@ -115,7 +113,7 @@ internal class DefaultSyncTask @Inject constructor( displayName = user?.displayName, avatarUrl = user?.avatarUrl ) - defaultSyncStatusService.startRoot(InitSyncStep.ImportingAccount, 100) + syncRequestStateTracker.startRoot(InitialSyncStep.ImportingAccount, 100) } // Maybe refresh the homeserver capabilities data we know getHomeServerCapabilitiesTask.execute(GetHomeServerCapabilitiesTask.Params(forceRefresh = false)) @@ -132,7 +130,7 @@ internal class DefaultSyncTask @Inject constructor( roomSyncEphemeralTemporaryStore.reset() workingDir.mkdirs() val file = downloadInitSyncResponse(requestParams, syncStatisticsData) - syncResponseToReturn = reportSubtask(defaultSyncStatusService, InitSyncStep.ImportingAccount, 1, 0.7F) { + syncResponseToReturn = reportSubtask(syncRequestStateTracker, InitialSyncStep.ImportingAccount, 1, 0.7F) { handleSyncFile(file, initSyncStrategy) } // Delete all files @@ -150,15 +148,15 @@ internal class DefaultSyncTask @Inject constructor( syncStatisticsData.requestInitSyncTime = SystemClock.elapsedRealtime() syncStatisticsData.downloadInitSyncTime = syncStatisticsData.requestInitSyncTime logDuration("INIT_SYNC Database insertion", loggerTag, clock) { - syncResponseHandler.handleResponse(syncResponse, token, defaultSyncStatusService) + syncResponseHandler.handleResponse(syncResponse, token, syncRequestStateTracker) } syncResponseToReturn = syncResponse } } - defaultSyncStatusService.endAll() + syncRequestStateTracker.endAll() } else { Timber.tag(loggerTag.value).d("Start incremental sync request with since token $token") - defaultSyncStatusService.setStatus(SyncStatusService.Status.IncrementalSyncIdle) + syncRequestStateTracker.setSyncRequestState(SyncRequestState.IncrementalSyncIdle) val syncResponse = try { executeRequest(globalErrorReceiver) { syncAPI.sync( @@ -168,7 +166,7 @@ internal class DefaultSyncTask @Inject constructor( } } catch (throwable: Throwable) { Timber.tag(loggerTag.value).e(throwable, "Incremental sync request error") - defaultSyncStatusService.setStatus(SyncStatusService.Status.IncrementalSyncError) + syncRequestStateTracker.setSyncRequestState(SyncRequestState.IncrementalSyncError) throw throwable } val nbRooms = syncResponse.rooms?.invite.orEmpty().size + syncResponse.rooms?.join.orEmpty().size + syncResponse.rooms?.leave.orEmpty().size @@ -177,8 +175,8 @@ internal class DefaultSyncTask @Inject constructor( Timber.tag(loggerTag.value).d( "Incremental sync request parsing, $nbRooms room(s) $nbToDevice toDevice(s). Got nextBatch: $nextBatch" ) - defaultSyncStatusService.setStatus( - SyncStatusService.Status.IncrementalSyncParsing( + syncRequestStateTracker.setSyncRequestState( + SyncRequestState.IncrementalSyncParsing( rooms = nbRooms, toDevice = nbToDevice ) @@ -186,7 +184,7 @@ internal class DefaultSyncTask @Inject constructor( syncResponseHandler.handleResponse(syncResponse, token, null) syncResponseToReturn = syncResponse Timber.tag(loggerTag.value).d("Incremental sync done") - defaultSyncStatusService.setStatus(SyncStatusService.Status.IncrementalSyncDone) + syncRequestStateTracker.setSyncRequestState(SyncRequestState.IncrementalSyncDone) } syncStatisticsData.treatmentSyncTime = SystemClock.elapsedRealtime() syncStatisticsData.nbOfRooms = syncResponseToReturn?.rooms?.join?.size ?: 0 @@ -201,20 +199,20 @@ internal class DefaultSyncTask @Inject constructor( val status = initialSyncStatusRepository.getStep() if (workingFile.exists() && status >= InitialSyncStatus.STEP_DOWNLOADED) { Timber.tag(loggerTag.value).d("INIT_SYNC file is already here") - reportSubtask(defaultSyncStatusService, InitSyncStep.Downloading, 1, 0.3f) { + reportSubtask(syncRequestStateTracker, InitialSyncStep.Downloading, 1, 0.3f) { // Empty task } } else { initialSyncStatusRepository.setStep(InitialSyncStatus.STEP_DOWNLOADING) val syncResponse = logDuration("INIT_SYNC Perform server request", loggerTag, clock) { - reportSubtask(defaultSyncStatusService, InitSyncStep.ServerComputing, 1, 0.2f) { + reportSubtask(syncRequestStateTracker, InitialSyncStep.ServerComputing, 1, 0.2f) { getSyncResponse(requestParams, MAX_NUMBER_OF_RETRY_AFTER_TIMEOUT) } } syncStatisticsData.requestInitSyncTime = SystemClock.elapsedRealtime() if (syncResponse.isSuccessful) { logDuration("INIT_SYNC Download and save to file", loggerTag, clock) { - reportSubtask(defaultSyncStatusService, InitSyncStep.Downloading, 1, 0.1f) { + reportSubtask(syncRequestStateTracker, InitialSyncStep.Downloading, 1, 0.1f) { syncResponse.body()?.byteStream()?.use { inputStream -> workingFile.outputStream().use { outputStream -> inputStream.copyTo(outputStream) @@ -263,7 +261,7 @@ internal class DefaultSyncTask @Inject constructor( Timber.tag(loggerTag.value).d("INIT_SYNC $nbOfJoinedRooms rooms, $nbOfJoinedRoomsInFile ephemeral stored into files") logDuration("INIT_SYNC Database insertion", loggerTag, clock) { - syncResponseHandler.handleResponse(syncResponse, null, defaultSyncStatusService) + syncResponseHandler.handleResponse(syncResponse, null, syncRequestStateTracker) } initialSyncStatusRepository.setStep(InitialSyncStatus.STEP_SUCCESS) syncResponse diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/initsync/TaskInfo.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/TaskInfo.kt similarity index 90% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/initsync/TaskInfo.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/TaskInfo.kt index 5ddbcde1f1..7032aae2b2 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/initsync/TaskInfo.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/TaskInfo.kt @@ -14,13 +14,13 @@ * limitations under the License. */ -package org.matrix.android.sdk.internal.session.initsync +package org.matrix.android.sdk.internal.session.sync -import org.matrix.android.sdk.api.session.initsync.InitSyncStep +import org.matrix.android.sdk.api.session.sync.InitialSyncStep import timber.log.Timber internal class TaskInfo( - val initSyncStep: InitSyncStep, + val initialSyncStep: InitialSyncStep, val totalProgress: Int, val parent: TaskInfo?, val parentWeight: Float diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/CryptoSyncHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/CryptoSyncHandler.kt index 4ae3a10b5c..b6142b3a7a 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/CryptoSyncHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/CryptoSyncHandler.kt @@ -29,7 +29,7 @@ import org.matrix.android.sdk.api.session.sync.model.SyncResponse import org.matrix.android.sdk.api.session.sync.model.ToDeviceSyncResponse import org.matrix.android.sdk.internal.crypto.DefaultCryptoService import org.matrix.android.sdk.internal.crypto.verification.DefaultVerificationService -import org.matrix.android.sdk.internal.session.initsync.ProgressReporter +import org.matrix.android.sdk.internal.session.sync.ProgressReporter import timber.log.Timber import javax.inject.Inject diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/GroupSyncHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/GroupSyncHandler.kt index 76fc077ee7..6e12578ef6 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/GroupSyncHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/GroupSyncHandler.kt @@ -17,16 +17,16 @@ package org.matrix.android.sdk.internal.session.sync.handler import io.realm.Realm -import org.matrix.android.sdk.api.session.initsync.InitSyncStep import org.matrix.android.sdk.api.session.room.model.Membership +import org.matrix.android.sdk.api.session.sync.InitialSyncStep import org.matrix.android.sdk.api.session.sync.model.GroupsSyncResponse import org.matrix.android.sdk.api.session.sync.model.InvitedGroupSync import org.matrix.android.sdk.internal.database.model.GroupEntity import org.matrix.android.sdk.internal.database.model.GroupSummaryEntity import org.matrix.android.sdk.internal.database.query.getOrCreate import org.matrix.android.sdk.internal.database.query.where -import org.matrix.android.sdk.internal.session.initsync.ProgressReporter -import org.matrix.android.sdk.internal.session.initsync.mapWithProgress +import org.matrix.android.sdk.internal.session.sync.ProgressReporter +import org.matrix.android.sdk.internal.session.sync.mapWithProgress import javax.inject.Inject internal class GroupSyncHandler @Inject constructor() { @@ -51,18 +51,18 @@ internal class GroupSyncHandler @Inject constructor() { private fun handleGroupSync(realm: Realm, handlingStrategy: HandlingStrategy, reporter: ProgressReporter?) { val groups = when (handlingStrategy) { - is HandlingStrategy.JOINED -> - handlingStrategy.data.mapWithProgress(reporter, InitSyncStep.ImportingAccountGroups, 0.6f) { + is HandlingStrategy.JOINED -> + handlingStrategy.data.mapWithProgress(reporter, InitialSyncStep.ImportingAccountGroups, 0.6f) { handleJoinedGroup(realm, it.key) } is HandlingStrategy.INVITED -> - handlingStrategy.data.mapWithProgress(reporter, InitSyncStep.ImportingAccountGroups, 0.3f) { + handlingStrategy.data.mapWithProgress(reporter, InitialSyncStep.ImportingAccountGroups, 0.3f) { handleInvitedGroup(realm, it.key) } - is HandlingStrategy.LEFT -> - handlingStrategy.data.mapWithProgress(reporter, InitSyncStep.ImportingAccountGroups, 0.1f) { + is HandlingStrategy.LEFT -> + handlingStrategy.data.mapWithProgress(reporter, InitialSyncStep.ImportingAccountGroups, 0.1f) { handleLeftGroup(realm, it.key) } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt index e2794900f8..88fa52a0bb 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt @@ -27,11 +27,11 @@ import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.EventType import org.matrix.android.sdk.api.session.events.model.toModel import org.matrix.android.sdk.api.session.homeserver.HomeServerCapabilitiesService -import org.matrix.android.sdk.api.session.initsync.InitSyncStep import org.matrix.android.sdk.api.session.room.model.Membership import org.matrix.android.sdk.api.session.room.model.RoomMemberContent import org.matrix.android.sdk.api.session.room.send.SendState import org.matrix.android.sdk.api.session.room.threads.model.ThreadSummaryUpdateType +import org.matrix.android.sdk.api.session.sync.InitialSyncStep import org.matrix.android.sdk.api.session.sync.InitialSyncStrategy import org.matrix.android.sdk.api.session.sync.initialSyncStrategy import org.matrix.android.sdk.api.session.sync.model.InvitedRoomSync @@ -67,17 +67,17 @@ import org.matrix.android.sdk.internal.di.UserId import org.matrix.android.sdk.internal.extensions.clearWith import org.matrix.android.sdk.internal.session.StreamEventsManager import org.matrix.android.sdk.internal.session.events.getFixedRoomMemberContent -import org.matrix.android.sdk.internal.session.initsync.ProgressReporter -import org.matrix.android.sdk.internal.session.initsync.mapWithProgress -import org.matrix.android.sdk.internal.session.initsync.reportSubtask import org.matrix.android.sdk.internal.session.room.membership.RoomChangeMembershipStateDataSource import org.matrix.android.sdk.internal.session.room.membership.RoomMemberEventHandler import org.matrix.android.sdk.internal.session.room.summary.RoomSummaryUpdater import org.matrix.android.sdk.internal.session.room.timeline.PaginationDirection import org.matrix.android.sdk.internal.session.room.timeline.TimelineInput import org.matrix.android.sdk.internal.session.room.typing.TypingEventContent +import org.matrix.android.sdk.internal.session.sync.ProgressReporter import org.matrix.android.sdk.internal.session.sync.SyncResponsePostTreatmentAggregator +import org.matrix.android.sdk.internal.session.sync.mapWithProgress import org.matrix.android.sdk.internal.session.sync.parsing.RoomSyncAccountDataHandler +import org.matrix.android.sdk.internal.session.sync.reportSubtask import org.matrix.android.sdk.internal.util.computeBestChunkSize import org.matrix.android.sdk.internal.util.time.Clock import timber.log.Timber @@ -140,24 +140,24 @@ internal class RoomSyncHandler @Inject constructor( } val syncLocalTimeStampMillis = clock.epochMillis() val rooms = when (handlingStrategy) { - is HandlingStrategy.JOINED -> { + is HandlingStrategy.JOINED -> { if (isInitialSync && initialSyncStrategy is InitialSyncStrategy.Optimized) { insertJoinRoomsFromInitSync(realm, handlingStrategy, syncLocalTimeStampMillis, aggregator, reporter) // Rooms are already inserted, return an empty list emptyList() } else { - handlingStrategy.data.mapWithProgress(reporter, InitSyncStep.ImportingAccountJoinedRooms, 0.6f) { + handlingStrategy.data.mapWithProgress(reporter, InitialSyncStep.ImportingAccountJoinedRooms, 0.6f) { handleJoinedRoom(realm, it.key, it.value, insertType, syncLocalTimeStampMillis, aggregator) } } } is HandlingStrategy.INVITED -> - handlingStrategy.data.mapWithProgress(reporter, InitSyncStep.ImportingAccountInvitedRooms, 0.1f) { + handlingStrategy.data.mapWithProgress(reporter, InitialSyncStep.ImportingAccountInvitedRooms, 0.1f) { handleInvitedRoom(realm, it.key, it.value, insertType, syncLocalTimeStampMillis) } - is HandlingStrategy.LEFT -> { - handlingStrategy.data.mapWithProgress(reporter, InitSyncStep.ImportingAccountLeftRooms, 0.3f) { + is HandlingStrategy.LEFT -> { + handlingStrategy.data.mapWithProgress(reporter, InitialSyncStep.ImportingAccountLeftRooms, 0.3f) { handleLeftRoom(realm, it.key, it.value, insertType, syncLocalTimeStampMillis) } } @@ -178,7 +178,7 @@ internal class RoomSyncHandler @Inject constructor( ) if (bestChunkSize.shouldChunk()) { - reportSubtask(reporter, InitSyncStep.ImportingAccountJoinedRooms, bestChunkSize.numberOfChunks, 0.6f) { + reportSubtask(reporter, InitialSyncStep.ImportingAccountJoinedRooms, bestChunkSize.numberOfChunks, 0.6f) { Timber.d("INIT_SYNC ${handlingStrategy.data.keys.size} rooms to insert, split with $bestChunkSize") // I cannot find a better way to chunk a map, so chunk the keys and then create new maps handlingStrategy.data.keys @@ -202,7 +202,7 @@ internal class RoomSyncHandler @Inject constructor( } } else { // No need to split - val rooms = handlingStrategy.data.mapWithProgress(reporter, InitSyncStep.ImportingAccountJoinedRooms, 0.6f) { + val rooms = handlingStrategy.data.mapWithProgress(reporter, InitialSyncStep.ImportingAccountJoinedRooms, 0.6f) { handleJoinedRoom(realm, it.key, it.value, EventInsertType.INITIAL_SYNC, syncLocalTimeStampMillis, aggregator) } realm.insertOrUpdate(rooms) @@ -578,12 +578,12 @@ internal class RoomSyncHandler @Inject constructor( readReceiptHandler.handle(realm, roomId, readReceiptContent, isInitialSync, aggregator) } } - EventType.TYPING -> { + EventType.TYPING -> { event.content.toModel()?.let { typingEventContent -> result = result.copy(typingUserIds = typingEventContent.typingUserIds) } } - else -> Timber.w("Ephemeral event type '${event.type}' not yet supported") + else -> Timber.w("Ephemeral event type '${event.type}' not yet supported") } } diff --git a/vector/src/androidTest/java/im/vector/app/EspressoExt.kt b/vector/src/androidTest/java/im/vector/app/EspressoExt.kt index 2456d7a3f5..72137ed8e8 100644 --- a/vector/src/androidTest/java/im/vector/app/EspressoExt.kt +++ b/vector/src/androidTest/java/im/vector/app/EspressoExt.kt @@ -142,7 +142,7 @@ fun initialSyncIdlingResource(session: Session): IdlingResource { override fun getName() = "InitialSyncIdlingResource for ${session.myUserId}" override fun isIdleNow(): Boolean { - val isIdle = session.hasAlreadySynced() + val isIdle = session.syncService().hasAlreadySynced() return isIdle } @@ -151,16 +151,16 @@ fun initialSyncIdlingResource(session: Session): IdlingResource { } override fun onChanged(t: SyncState?) { - val isIdle = session.hasAlreadySynced() + val isIdle = session.syncService().hasAlreadySynced() if (isIdle) { callback?.onTransitionToIdle() - session.getSyncStateLive().removeObserver(this) + session.syncService().getSyncStateLive().removeObserver(this) } } } runOnUiThread { - session.getSyncStateLive().observeForever(res) + session.syncService().getSyncStateLive().observeForever(res) } return res diff --git a/vector/src/androidTest/java/im/vector/app/VerificationTestBase.kt b/vector/src/androidTest/java/im/vector/app/VerificationTestBase.kt index 4bb3c377d7..97a2a14da3 100644 --- a/vector/src/androidTest/java/im/vector/app/VerificationTestBase.kt +++ b/vector/src/androidTest/java/im/vector/app/VerificationTestBase.kt @@ -116,14 +116,14 @@ abstract class VerificationTestBase { GlobalScope.launch(Dispatchers.Main) { session.open() } - session.startSync(true) + session.syncService().startSync(true) val syncLiveData = runBlocking(Dispatchers.Main) { - session.getSyncStateLive() + session.syncService().getSyncStateLive() } val syncObserver = object : Observer { override fun onChanged(t: SyncState?) { - if (session.hasAlreadySynced()) { + if (session.syncService().hasAlreadySynced()) { lock.countDown() syncLiveData.removeObserver(this) } diff --git a/vector/src/fdroid/java/im/vector/app/fdroid/BackgroundSyncStarter.kt b/vector/src/fdroid/java/im/vector/app/fdroid/BackgroundSyncStarter.kt index 5bb52be6e6..e2ac4f8822 100644 --- a/vector/src/fdroid/java/im/vector/app/fdroid/BackgroundSyncStarter.kt +++ b/vector/src/fdroid/java/im/vector/app/fdroid/BackgroundSyncStarter.kt @@ -37,7 +37,7 @@ object BackgroundSyncStarter { BackgroundSyncMode.FDROID_BACKGROUND_SYNC_MODE_FOR_BATTERY -> { // we rely on periodic worker Timber.i("## Sync: Work scheduled to periodically sync in ${vectorPreferences.backgroundSyncDelay()}s") - activeSession.startAutomaticBackgroundSync( + activeSession.syncService().startAutomaticBackgroundSync( vectorPreferences.backgroundSyncTimeOut().toLong(), vectorPreferences.backgroundSyncDelay().toLong() ) diff --git a/vector/src/fdroid/java/im/vector/app/fdroid/receiver/AlarmSyncBroadcastReceiver.kt b/vector/src/fdroid/java/im/vector/app/fdroid/receiver/AlarmSyncBroadcastReceiver.kt index 09bd56654d..bd1e0eb0ee 100644 --- a/vector/src/fdroid/java/im/vector/app/fdroid/receiver/AlarmSyncBroadcastReceiver.kt +++ b/vector/src/fdroid/java/im/vector/app/fdroid/receiver/AlarmSyncBroadcastReceiver.kt @@ -26,9 +26,9 @@ import androidx.core.content.ContextCompat import androidx.core.content.getSystemService import im.vector.app.core.extensions.singletonEntryPoint import im.vector.app.core.platform.PendingIntentCompat -import im.vector.app.core.services.VectorSyncService +import im.vector.app.core.services.VectorSyncAndroidService import im.vector.app.core.time.Clock -import org.matrix.android.sdk.api.session.sync.job.SyncService +import org.matrix.android.sdk.api.session.sync.job.SyncAndroidService import timber.log.Timber class AlarmSyncBroadcastReceiver : BroadcastReceiver() { @@ -43,8 +43,8 @@ class AlarmSyncBroadcastReceiver : BroadcastReceiver() { val vectorPreferences = singletonEntryPoint.vectorPreferences() val clock = singletonEntryPoint.clock() - val sessionId = intent.getStringExtra(SyncService.EXTRA_SESSION_ID) ?: return - VectorSyncService.newPeriodicIntent( + val sessionId = intent.getStringExtra(SyncAndroidService.EXTRA_SESSION_ID) ?: return + VectorSyncAndroidService.newPeriodicIntent( context = context, sessionId = sessionId, syncTimeoutSeconds = vectorPreferences.backgroundSyncTimeOut(), @@ -69,8 +69,8 @@ class AlarmSyncBroadcastReceiver : BroadcastReceiver() { // Reschedule Timber.v("## Sync: Scheduling alarm for background sync in $delayInSeconds seconds") val intent = Intent(context, AlarmSyncBroadcastReceiver::class.java).apply { - putExtra(SyncService.EXTRA_SESSION_ID, sessionId) - putExtra(SyncService.EXTRA_PERIODIC, true) + putExtra(SyncAndroidService.EXTRA_SESSION_ID, sessionId) + putExtra(SyncAndroidService.EXTRA_PERIODIC, true) } val pIntent = PendingIntent.getBroadcast( context, @@ -100,7 +100,7 @@ class AlarmSyncBroadcastReceiver : BroadcastReceiver() { alarmMgr.cancel(pIntent) // Stop current service to restart - VectorSyncService.stopIntent(context).let { + VectorSyncAndroidService.stopIntent(context).let { try { ContextCompat.startForegroundService(context, it) } catch (ex: Throwable) { diff --git a/vector/src/fdroid/java/im/vector/app/push/fcm/FcmHelper.kt b/vector/src/fdroid/java/im/vector/app/push/fcm/FcmHelper.kt index a93c4f0e64..7533eae856 100755 --- a/vector/src/fdroid/java/im/vector/app/push/fcm/FcmHelper.kt +++ b/vector/src/fdroid/java/im/vector/app/push/fcm/FcmHelper.kt @@ -63,7 +63,7 @@ object FcmHelper { fun onEnterForeground(context: Context, activeSessionHolder: ActiveSessionHolder) { // try to stop all regardless of background mode - activeSessionHolder.getSafeActiveSession()?.stopAnyBackgroundSync() + activeSessionHolder.getSafeActiveSession()?.syncService()?.stopAnyBackgroundSync() AlarmSyncBroadcastReceiver.cancelAlarm(context) } diff --git a/vector/src/gplay/java/im/vector/app/gplay/push/fcm/VectorFirebaseMessagingService.kt b/vector/src/gplay/java/im/vector/app/gplay/push/fcm/VectorFirebaseMessagingService.kt index a7d814052a..8d0126d6af 100755 --- a/vector/src/gplay/java/im/vector/app/gplay/push/fcm/VectorFirebaseMessagingService.kt +++ b/vector/src/gplay/java/im/vector/app/gplay/push/fcm/VectorFirebaseMessagingService.kt @@ -164,7 +164,7 @@ class VectorFirebaseMessagingService : FirebaseMessagingService() { getEventFastLane(session, roomId, eventId) Timber.tag(loggerTag.value).d("Requesting background sync") - session.requireBackgroundSync() + session.syncService().requireBackgroundSync() } } } catch (e: Exception) { diff --git a/vector/src/main/AndroidManifest.xml b/vector/src/main/AndroidManifest.xml index 2e31439e73..89c600b052 100644 --- a/vector/src/main/AndroidManifest.xml +++ b/vector/src/main/AndroidManifest.xml @@ -358,7 +358,7 @@ diff --git a/vector/src/main/java/im/vector/app/AppStateHandler.kt b/vector/src/main/java/im/vector/app/AppStateHandler.kt index f25bcac92a..d366927d6d 100644 --- a/vector/src/main/java/im/vector/app/AppStateHandler.kt +++ b/vector/src/main/java/im/vector/app/AppStateHandler.kt @@ -41,8 +41,8 @@ import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.getRoom import org.matrix.android.sdk.api.session.getRoomSummary import org.matrix.android.sdk.api.session.group.model.GroupSummary -import org.matrix.android.sdk.api.session.initsync.SyncStatusService import org.matrix.android.sdk.api.session.room.model.RoomSummary +import org.matrix.android.sdk.api.session.sync.SyncRequestState import javax.inject.Inject import javax.inject.Singleton @@ -147,9 +147,9 @@ class AppStateHandler @Inject constructor( } private fun observeSyncStatus(session: Session) { - session.syncStatusService().getSyncStatusLive() + session.syncService().getSyncRequestStateLive() .asFlow() - .filterIsInstance() + .filterIsInstance() .map { session.spaceService().getRootSpaceSummaries().size } .distinctUntilChanged() .onEach { spacesNumber -> diff --git a/vector/src/main/java/im/vector/app/AutoRageShaker.kt b/vector/src/main/java/im/vector/app/AutoRageShaker.kt index c77ce2b647..dc561aa821 100644 --- a/vector/src/main/java/im/vector/app/AutoRageShaker.kt +++ b/vector/src/main/java/im/vector/app/AutoRageShaker.kt @@ -36,7 +36,7 @@ import kotlinx.coroutines.launch import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.toContent -import org.matrix.android.sdk.api.session.initsync.SyncStatusService +import org.matrix.android.sdk.api.session.sync.SyncRequestState import timber.log.Timber import javax.inject.Inject import javax.inject.Singleton @@ -260,11 +260,11 @@ class AutoRageShaker @Inject constructor( } this.currentActiveSessionId = sessionId - hasSynced = session.hasAlreadySynced() - session.syncStatusService().getSyncStatusLive() + hasSynced = session.syncService().hasAlreadySynced() + session.syncService().getSyncRequestStateLive() .asFlow() .onEach { - hasSynced = it !is SyncStatusService.Status.InitialSyncProgressing + hasSynced = it !is SyncRequestState.InitialSyncProgressing } .launchIn(session.coroutineScope) activeSessionIds.add(sessionId) diff --git a/vector/src/main/java/im/vector/app/VectorApplication.kt b/vector/src/main/java/im/vector/app/VectorApplication.kt index a55351f74b..7db0f99f5f 100644 --- a/vector/src/main/java/im/vector/app/VectorApplication.kt +++ b/vector/src/main/java/im/vector/app/VectorApplication.kt @@ -176,7 +176,7 @@ class VectorApplication : Timber.i("App entered foreground") FcmHelper.onEnterForeground(appContext, activeSessionHolder) activeSessionHolder.getSafeActiveSession()?.also { - it.stopAnyBackgroundSync() + it.syncService().stopAnyBackgroundSync() } } diff --git a/vector/src/main/java/im/vector/app/core/extensions/Session.kt b/vector/src/main/java/im/vector/app/core/extensions/Session.kt index 2a2198d96b..caed413e2b 100644 --- a/vector/src/main/java/im/vector/app/core/extensions/Session.kt +++ b/vector/src/main/java/im/vector/app/core/extensions/Session.kt @@ -20,7 +20,7 @@ import android.content.Context import androidx.core.content.ContextCompat import androidx.lifecycle.Lifecycle import androidx.lifecycle.ProcessLifecycleOwner -import im.vector.app.core.services.VectorSyncService +import im.vector.app.core.services.VectorSyncAndroidService import im.vector.app.features.session.VectorSessionStore import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupState @@ -40,9 +40,9 @@ fun Session.configureAndStart(context: Context, startSyncing: Boolean = true) { fun Session.startSyncing(context: Context) { val applicationContext = context.applicationContext - if (!hasAlreadySynced()) { + if (!syncService().hasAlreadySynced()) { // initial sync is done as a service so it can continue below app lifecycle - VectorSyncService.newOneShotIntent( + VectorSyncAndroidService.newOneShotIntent( context = applicationContext, sessionId = sessionId ) @@ -57,7 +57,7 @@ fun Session.startSyncing(context: Context) { } else { val isAtLeastStarted = ProcessLifecycleOwner.get().lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED) Timber.v("--> is at least started? $isAtLeastStarted") - startSync(isAtLeastStarted) + syncService().startSync(isAtLeastStarted) } } diff --git a/vector/src/main/java/im/vector/app/core/resources/LocaleProvider.kt b/vector/src/main/java/im/vector/app/core/resources/LocaleProvider.kt index 2f1b46b555..d91a09e6df 100644 --- a/vector/src/main/java/im/vector/app/core/resources/LocaleProvider.kt +++ b/vector/src/main/java/im/vector/app/core/resources/LocaleProvider.kt @@ -26,7 +26,7 @@ import javax.inject.Inject class LocaleProvider @Inject constructor(private val resources: Resources) { fun current(): Locale { - return ConfigurationCompat.getLocales(resources.configuration)[0] + return ConfigurationCompat.getLocales(resources.configuration).get(0) ?: Locale.getDefault() } } diff --git a/vector/src/main/java/im/vector/app/core/services/VectorSyncService.kt b/vector/src/main/java/im/vector/app/core/services/VectorSyncAndroidService.kt similarity index 95% rename from vector/src/main/java/im/vector/app/core/services/VectorSyncService.kt rename to vector/src/main/java/im/vector/app/core/services/VectorSyncAndroidService.kt index 1ac7b83f44..864f69a136 100644 --- a/vector/src/main/java/im/vector/app/core/services/VectorSyncService.kt +++ b/vector/src/main/java/im/vector/app/core/services/VectorSyncAndroidService.kt @@ -38,12 +38,12 @@ import im.vector.app.core.time.DefaultClock import im.vector.app.features.notifications.NotificationUtils import im.vector.app.features.settings.BackgroundSyncMode import org.matrix.android.sdk.api.Matrix -import org.matrix.android.sdk.api.session.sync.job.SyncService +import org.matrix.android.sdk.api.session.sync.job.SyncAndroidService import timber.log.Timber import javax.inject.Inject @AndroidEntryPoint -class VectorSyncService : SyncService() { +class VectorSyncAndroidService : SyncAndroidService() { companion object { @@ -51,7 +51,7 @@ class VectorSyncService : SyncService() { context: Context, sessionId: String ): Intent { - return Intent(context, VectorSyncService::class.java).also { + return Intent(context, VectorSyncAndroidService::class.java).also { it.putExtra(EXTRA_SESSION_ID, sessionId) it.putExtra(EXTRA_TIMEOUT_SECONDS, 0) it.putExtra(EXTRA_PERIODIC, false) @@ -65,7 +65,7 @@ class VectorSyncService : SyncService() { syncDelaySeconds: Int, isNetworkBack: Boolean ): Intent { - return Intent(context, VectorSyncService::class.java).also { + return Intent(context, VectorSyncAndroidService::class.java).also { it.putExtra(EXTRA_SESSION_ID, sessionId) it.putExtra(EXTRA_TIMEOUT_SECONDS, syncTimeoutSeconds) it.putExtra(EXTRA_PERIODIC, true) @@ -75,7 +75,7 @@ class VectorSyncService : SyncService() { } fun stopIntent(context: Context): Intent { - return Intent(context, VectorSyncService::class.java).also { + return Intent(context, VectorSyncAndroidService::class.java).also { it.action = ACTION_STOP } } @@ -209,7 +209,7 @@ private fun Context.rescheduleSyncService( ) { Timber.d("## Sync: rescheduleSyncService") val intent = if (isPeriodic) { - VectorSyncService.newPeriodicIntent( + VectorSyncAndroidService.newPeriodicIntent( context = this, sessionId = sessionId, syncTimeoutSeconds = syncTimeoutSeconds, @@ -217,7 +217,7 @@ private fun Context.rescheduleSyncService( isNetworkBack = isNetworkBack ) } else { - VectorSyncService.newOneShotIntent( + VectorSyncAndroidService.newOneShotIntent( context = this, sessionId = sessionId ) diff --git a/vector/src/main/java/im/vector/app/features/analytics/accountdata/AnalyticsAccountDataViewModel.kt b/vector/src/main/java/im/vector/app/features/analytics/accountdata/AnalyticsAccountDataViewModel.kt index 221a9d8843..05358decc9 100644 --- a/vector/src/main/java/im/vector/app/features/analytics/accountdata/AnalyticsAccountDataViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/analytics/accountdata/AnalyticsAccountDataViewModel.kt @@ -37,7 +37,7 @@ import kotlinx.coroutines.launch import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.events.model.toContent import org.matrix.android.sdk.api.session.events.model.toModel -import org.matrix.android.sdk.api.session.initsync.SyncStatusService +import org.matrix.android.sdk.api.session.sync.SyncRequestState import org.matrix.android.sdk.flow.flow import timber.log.Timber import java.util.UUID @@ -66,11 +66,11 @@ class AnalyticsAccountDataViewModel @AssistedInject constructor( private fun observeInitSync() { combine( - session.syncStatusService().getSyncStatusLive().asFlow(), + session.syncService().getSyncRequestStateLive().asFlow(), analytics.getUserConsent(), analytics.getAnalyticsId() ) { status, userConsent, analyticsId -> - if (status is SyncStatusService.Status.IncrementalSyncIdle && + if (status is SyncRequestState.IncrementalSyncIdle && userConsent && analyticsId.isEmpty() && !checkDone) { diff --git a/vector/src/main/java/im/vector/app/features/analytics/plan/Interaction.kt b/vector/src/main/java/im/vector/app/features/analytics/plan/Interaction.kt index 4e4bfe53be..deb9088259 100644 --- a/vector/src/main/java/im/vector/app/features/analytics/plan/Interaction.kt +++ b/vector/src/main/java/im/vector/app/features/analytics/plan/Interaction.kt @@ -105,6 +105,12 @@ data class Interaction( */ WebHomeExploreRoomsButton, + /** + * User clicked on the mini avatar uploader in the home page of Element + * Web/Desktop. + */ + WebHomeMiniAvatarUploadButton, + /** * User clicked the explore rooms button next to the search field at the * top of the left panel in Element Web/Desktop. diff --git a/vector/src/main/java/im/vector/app/features/call/webrtc/WebRtcCallManager.kt b/vector/src/main/java/im/vector/app/features/call/webrtc/WebRtcCallManager.kt index 5f50747d77..fa991501ea 100644 --- a/vector/src/main/java/im/vector/app/features/call/webrtc/WebRtcCallManager.kt +++ b/vector/src/main/java/im/vector/app/features/call/webrtc/WebRtcCallManager.kt @@ -273,7 +273,7 @@ class WebRtcCallManager @Inject constructor( // did we start background sync? so we should stop it if (isInBackground) { if (FcmHelper.isPushSupported()) { - currentSession?.stopAnyBackgroundSync() + currentSession?.syncService()?.stopAnyBackgroundSync() } else { // for fdroid we should not stop, it should continue syncing // maybe we should restore default timeout/delay though? @@ -380,7 +380,7 @@ class WebRtcCallManager @Inject constructor( if (isInBackground) { if (FcmHelper.isPushSupported()) { // only for push version as fdroid version is already doing it? - currentSession?.startAutomaticBackgroundSync(30, 0) + currentSession?.syncService()?.startAutomaticBackgroundSync(30, 0) } else { // Maybe increase sync freq? but how to set back to default values? } diff --git a/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt b/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt index 244b77eefe..cfc0672119 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt @@ -81,9 +81,9 @@ import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch import kotlinx.parcelize.Parcelize -import org.matrix.android.sdk.api.session.initsync.SyncStatusService import org.matrix.android.sdk.api.session.permalinks.PermalinkService import org.matrix.android.sdk.api.session.sync.InitialSyncStrategy +import org.matrix.android.sdk.api.session.sync.SyncRequestState import org.matrix.android.sdk.api.session.sync.initialSyncStrategy import org.matrix.android.sdk.api.util.MatrixItem import timber.log.Timber @@ -199,15 +199,15 @@ class HomeActivity : .stream() .onEach { sharedAction -> when (sharedAction) { - is HomeActivitySharedAction.OpenDrawer -> views.drawerLayout.openDrawer(GravityCompat.START) - is HomeActivitySharedAction.CloseDrawer -> views.drawerLayout.closeDrawer(GravityCompat.START) - is HomeActivitySharedAction.OpenGroup -> openGroup(sharedAction.shouldClearFragment) - is HomeActivitySharedAction.OpenSpacePreview -> startActivity(SpacePreviewActivity.newIntent(this, sharedAction.spaceId)) - is HomeActivitySharedAction.AddSpace -> createSpaceResultLauncher.launch(SpaceCreationActivity.newIntent(this)) + is HomeActivitySharedAction.OpenDrawer -> views.drawerLayout.openDrawer(GravityCompat.START) + is HomeActivitySharedAction.CloseDrawer -> views.drawerLayout.closeDrawer(GravityCompat.START) + is HomeActivitySharedAction.OpenGroup -> openGroup(sharedAction.shouldClearFragment) + is HomeActivitySharedAction.OpenSpacePreview -> startActivity(SpacePreviewActivity.newIntent(this, sharedAction.spaceId)) + is HomeActivitySharedAction.AddSpace -> createSpaceResultLauncher.launch(SpaceCreationActivity.newIntent(this)) is HomeActivitySharedAction.ShowSpaceSettings -> showSpaceSettings(sharedAction.spaceId) - is HomeActivitySharedAction.OpenSpaceInvite -> openSpaceInvite(sharedAction.spaceId) - HomeActivitySharedAction.SendSpaceFeedBack -> bugReporter.openBugReportScreen(this, ReportType.SPACE_BETA_FEEDBACK) - HomeActivitySharedAction.CloseGroup -> closeGroup() + is HomeActivitySharedAction.OpenSpaceInvite -> openSpaceInvite(sharedAction.spaceId) + HomeActivitySharedAction.SendSpaceFeedBack -> bugReporter.openBugReportScreen(this, ReportType.SPACE_BETA_FEEDBACK) + HomeActivitySharedAction.CloseGroup -> closeGroup() } } .launchIn(lifecycleScope) @@ -226,20 +226,20 @@ class HomeActivity : homeActivityViewModel.observeViewEvents { when (it) { is HomeActivityViewEvents.AskPasswordToInitCrossSigning -> handleAskPasswordToInitCrossSigning(it) - is HomeActivityViewEvents.OnNewSession -> handleOnNewSession(it) - HomeActivityViewEvents.PromptToEnableSessionPush -> handlePromptToEnablePush() - HomeActivityViewEvents.StartRecoverySetupFlow -> handleStartRecoverySetup() - is HomeActivityViewEvents.ForceVerification -> { + is HomeActivityViewEvents.OnNewSession -> handleOnNewSession(it) + HomeActivityViewEvents.PromptToEnableSessionPush -> handlePromptToEnablePush() + HomeActivityViewEvents.StartRecoverySetupFlow -> handleStartRecoverySetup() + is HomeActivityViewEvents.ForceVerification -> { if (it.sendRequest) { navigator.requestSelfSessionVerification(this) } else { navigator.waitSessionVerification(this) } } - is HomeActivityViewEvents.OnCrossSignedInvalidated -> handleCrossSigningInvalidated(it) - HomeActivityViewEvents.ShowAnalyticsOptIn -> handleShowAnalyticsOptIn() - HomeActivityViewEvents.NotifyUserForThreadsMigration -> handleNotifyUserForThreadsMigration() - is HomeActivityViewEvents.MigrateThreads -> migrateThreadsIfNeeded(it.checkSession) + is HomeActivityViewEvents.OnCrossSignedInvalidated -> handleCrossSigningInvalidated(it) + HomeActivityViewEvents.ShowAnalyticsOptIn -> handleShowAnalyticsOptIn() + HomeActivityViewEvents.NotifyUserForThreadsMigration -> handleNotifyUserForThreadsMigration() + is HomeActivityViewEvents.MigrateThreads -> migrateThreadsIfNeeded(it.checkSession) } } homeActivityViewModel.onEach { renderState(it) } @@ -337,12 +337,12 @@ class HomeActivity : when { deepLink.startsWith(USER_LINK_PREFIX) -> deepLink.substring(USER_LINK_PREFIX.length) deepLink.startsWith(ROOM_LINK_PREFIX) -> deepLink.substring(ROOM_LINK_PREFIX.length) - else -> null + else -> null }?.let { permalinkId -> activeSessionHolder.getSafeActiveSession()?.permalinkService()?.createPermalink(permalinkId) } } - else -> deepLink + else -> deepLink } lifecycleScope.launch { @@ -373,9 +373,9 @@ class HomeActivity : } private fun renderState(state: HomeActivityViewState) { - when (val status = state.syncStatusServiceStatus) { - is SyncStatusService.Status.InitialSyncProgressing -> { - val initSyncStepStr = initSyncStepFormatter.format(status.initSyncStep) + when (val status = state.syncRequestState) { + is SyncRequestState.InitialSyncProgressing -> { + val initSyncStepStr = initSyncStepFormatter.format(status.initialSyncStep) Timber.v("$initSyncStepStr ${status.percentProgress}") views.waitingView.root.setOnClickListener { // block interactions @@ -392,7 +392,7 @@ class HomeActivity : } views.waitingView.root.isVisible = true } - else -> { + else -> { // Idle or Incremental sync status views.waitingView.root.isVisible = false } @@ -544,15 +544,15 @@ class HomeActivity : override fun onOptionsItemSelected(item: MenuItem): Boolean { when (item.itemId) { - R.id.menu_home_suggestion -> { + R.id.menu_home_suggestion -> { bugReporter.openBugReportScreen(this, ReportType.SUGGESTION) return true } - R.id.menu_home_report_bug -> { + R.id.menu_home_report_bug -> { bugReporter.openBugReportScreen(this, ReportType.BUG_REPORT) return true } - R.id.menu_home_init_sync_legacy -> { + R.id.menu_home_init_sync_legacy -> { // Configure the SDK initialSyncStrategy = InitialSyncStrategy.Legacy // And clear cache @@ -566,11 +566,11 @@ class HomeActivity : MainActivity.restartApp(this, MainActivityArgs(clearCache = true)) return true } - R.id.menu_home_filter -> { + R.id.menu_home_filter -> { navigator.openRoomsFiltering(this) return true } - R.id.menu_home_setting -> { + R.id.menu_home_setting -> { navigator.openSettings(this) return true } diff --git a/vector/src/main/java/im/vector/app/features/home/HomeActivityViewModel.kt b/vector/src/main/java/im/vector/app/features/home/HomeActivityViewModel.kt index 581e11ac8a..a97c86e960 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeActivityViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeActivityViewModel.kt @@ -60,10 +60,10 @@ import org.matrix.android.sdk.api.session.crypto.crosssigning.CrossSigningServic import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo import org.matrix.android.sdk.api.session.crypto.model.MXUsersDevicesMap import org.matrix.android.sdk.api.session.getUser -import org.matrix.android.sdk.api.session.initsync.SyncStatusService import org.matrix.android.sdk.api.session.pushrules.RuleIds import org.matrix.android.sdk.api.session.room.model.Membership import org.matrix.android.sdk.api.session.room.roomSummaryQueryParams +import org.matrix.android.sdk.api.session.sync.SyncRequestState import org.matrix.android.sdk.api.settings.LightweightSettingsStorage import org.matrix.android.sdk.api.util.awaitCallback import org.matrix.android.sdk.api.util.toMatrixItem @@ -198,7 +198,7 @@ class HomeActivityViewModel @AssistedInject constructor( vectorPreferences.userNotifiedAboutThreads() } // Migrate users with enabled lab settings - vectorPreferences.shouldNotifyUserAboutThreads() && vectorPreferences.shouldMigrateThreads() -> { + vectorPreferences.shouldNotifyUserAboutThreads() && vectorPreferences.shouldMigrateThreads() -> { Timber.i("----> Migrate threads with enabled labs") // If user had io.element.thread enabled then enable the new thread support, // clear cache to sync messages appropriately @@ -208,7 +208,7 @@ class HomeActivityViewModel @AssistedInject constructor( _viewEvents.post(HomeActivityViewEvents.MigrateThreads(checkSession = false)) } // Enable all users - vectorPreferences.shouldMigrateThreads() && vectorPreferences.areThreadMessagesEnabled() -> { + vectorPreferences.shouldMigrateThreads() && vectorPreferences.areThreadMessagesEnabled() -> { Timber.i("----> Try to migrate threads") _viewEvents.post(HomeActivityViewEvents.MigrateThreads(checkSession = true)) } @@ -218,25 +218,25 @@ class HomeActivityViewModel @AssistedInject constructor( private fun observeInitialSync() { val session = activeSessionHolder.getSafeActiveSession() ?: return - session.syncStatusService().getSyncStatusLive() + session.syncService().getSyncRequestStateLive() .asFlow() .onEach { status -> when (status) { - is SyncStatusService.Status.Idle -> { + is SyncRequestState.Idle -> { maybeVerifyOrBootstrapCrossSigning() } - else -> Unit + else -> Unit } setState { copy( - syncStatusServiceStatus = status + syncRequestState = status ) } } .launchIn(viewModelScope) - if (session.hasAlreadySynced()) { + if (session.syncService().hasAlreadySynced()) { maybeVerifyOrBootstrapCrossSigning() } } @@ -426,7 +426,7 @@ class HomeActivityViewModel @AssistedInject constructor( HomeActivityViewActions.PushPromptHasBeenReviewed -> { vectorPreferences.setDidAskUserToEnableSessionPush() } - HomeActivityViewActions.ViewStarted -> { + HomeActivityViewActions.ViewStarted -> { initialize() } } diff --git a/vector/src/main/java/im/vector/app/features/home/HomeActivityViewState.kt b/vector/src/main/java/im/vector/app/features/home/HomeActivityViewState.kt index 95ab75549f..843f9bdfec 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeActivityViewState.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeActivityViewState.kt @@ -18,9 +18,9 @@ package im.vector.app.features.home import com.airbnb.mvrx.MavericksState import im.vector.app.features.onboarding.AuthenticationDescription -import org.matrix.android.sdk.api.session.initsync.SyncStatusService +import org.matrix.android.sdk.api.session.sync.SyncRequestState data class HomeActivityViewState( - val syncStatusServiceStatus: SyncStatusService.Status = SyncStatusService.Status.Idle, + val syncRequestState: SyncRequestState = SyncRequestState.Idle, val authenticationDescription: AuthenticationDescription? = null ) : MavericksState diff --git a/vector/src/main/java/im/vector/app/features/home/HomeDetailFragment.kt b/vector/src/main/java/im/vector/app/features/home/HomeDetailFragment.kt index 3fd86a9728..9deae0970b 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeDetailFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeDetailFragment.kt @@ -444,7 +444,7 @@ class HomeDetailFragment @Inject constructor( views.bottomNavigationView.getOrCreateBadge(R.id.bottom_action_notification).render(it.notificationCountCatchup, it.notificationHighlightCatchup) views.syncStateView.render( it.syncState, - it.incrementalSyncStatus, + it.incrementalSyncRequestState, it.pushCounter, vectorPreferences.developerShowDebugInfo() ) diff --git a/vector/src/main/java/im/vector/app/features/home/HomeDetailViewModel.kt b/vector/src/main/java/im/vector/app/features/home/HomeDetailViewModel.kt index 820ce2ef49..7aa121e6cc 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeDetailViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeDetailViewModel.kt @@ -50,10 +50,10 @@ import org.matrix.android.sdk.api.query.SpaceFilter import org.matrix.android.sdk.api.query.toActiveSpaceOrOrphanRooms import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.crypto.NewSessionListener -import org.matrix.android.sdk.api.session.initsync.SyncStatusService import org.matrix.android.sdk.api.session.room.RoomSortOrder import org.matrix.android.sdk.api.session.room.model.Membership import org.matrix.android.sdk.api.session.room.roomSummaryQueryParams +import org.matrix.android.sdk.api.session.sync.SyncRequestState import org.matrix.android.sdk.api.util.toMatrixItem import org.matrix.android.sdk.flow.flow import timber.log.Timber @@ -199,11 +199,11 @@ class HomeDetailViewModel @AssistedInject constructor( copy(syncState = syncState) } - session.syncStatusService().getSyncStatusLive() + session.syncService().getSyncRequestStateLive() .asFlow() - .filterIsInstance() + .filterIsInstance() .setOnEach { - copy(incrementalSyncStatus = it) + copy(incrementalSyncRequestState = it) } } diff --git a/vector/src/main/java/im/vector/app/features/home/HomeDetailViewState.kt b/vector/src/main/java/im/vector/app/features/home/HomeDetailViewState.kt index fbf67cdcff..7b8319d8d1 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeDetailViewState.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeDetailViewState.kt @@ -22,8 +22,8 @@ import com.airbnb.mvrx.MavericksState import com.airbnb.mvrx.Uninitialized import im.vector.app.R import im.vector.app.RoomGroupingMethod -import org.matrix.android.sdk.api.session.initsync.SyncStatusService import org.matrix.android.sdk.api.session.room.model.RoomSummary +import org.matrix.android.sdk.api.session.sync.SyncRequestState import org.matrix.android.sdk.api.session.sync.SyncState import org.matrix.android.sdk.api.util.MatrixItem @@ -40,7 +40,7 @@ data class HomeDetailViewState( val notificationHighlightRooms: Boolean = false, val hasUnreadMessages: Boolean = false, val syncState: SyncState = SyncState.Idle, - val incrementalSyncStatus: SyncStatusService.Status.IncrementalSyncStatus = SyncStatusService.Status.IncrementalSyncIdle, + val incrementalSyncRequestState: SyncRequestState.IncrementalSyncRequestState = SyncRequestState.IncrementalSyncIdle, val pushCounter: Int = 0, val pstnSupportFlag: Boolean = false, val forceDialPadTab: Boolean = false diff --git a/vector/src/main/java/im/vector/app/features/home/InitSyncStepFormatter.kt b/vector/src/main/java/im/vector/app/features/home/InitSyncStepFormatter.kt index d2d414971f..3978bc43d8 100644 --- a/vector/src/main/java/im/vector/app/features/home/InitSyncStepFormatter.kt +++ b/vector/src/main/java/im/vector/app/features/home/InitSyncStepFormatter.kt @@ -18,25 +18,25 @@ package im.vector.app.features.home import im.vector.app.R import im.vector.app.core.resources.StringProvider -import org.matrix.android.sdk.api.session.initsync.InitSyncStep +import org.matrix.android.sdk.api.session.sync.InitialSyncStep import javax.inject.Inject class InitSyncStepFormatter @Inject constructor( private val stringProvider: StringProvider ) { - fun format(initSyncStep: InitSyncStep): String { + fun format(initialSyncStep: InitialSyncStep): String { return stringProvider.getString( - when (initSyncStep) { - InitSyncStep.ServerComputing -> R.string.initial_sync_start_server_computing - InitSyncStep.Downloading -> R.string.initial_sync_start_downloading - InitSyncStep.ImportingAccount -> R.string.initial_sync_start_importing_account - InitSyncStep.ImportingAccountCrypto -> R.string.initial_sync_start_importing_account_crypto - InitSyncStep.ImportingAccountRoom -> R.string.initial_sync_start_importing_account_rooms - InitSyncStep.ImportingAccountGroups -> R.string.initial_sync_start_importing_account_groups - InitSyncStep.ImportingAccountData -> R.string.initial_sync_start_importing_account_data - InitSyncStep.ImportingAccountJoinedRooms -> R.string.initial_sync_start_importing_account_joined_rooms - InitSyncStep.ImportingAccountInvitedRooms -> R.string.initial_sync_start_importing_account_invited_rooms - InitSyncStep.ImportingAccountLeftRooms -> R.string.initial_sync_start_importing_account_left_rooms + when (initialSyncStep) { + InitialSyncStep.ServerComputing -> R.string.initial_sync_start_server_computing + InitialSyncStep.Downloading -> R.string.initial_sync_start_downloading + InitialSyncStep.ImportingAccount -> R.string.initial_sync_start_importing_account + InitialSyncStep.ImportingAccountCrypto -> R.string.initial_sync_start_importing_account_crypto + InitialSyncStep.ImportingAccountRoom -> R.string.initial_sync_start_importing_account_rooms + InitialSyncStep.ImportingAccountGroups -> R.string.initial_sync_start_importing_account_groups + InitialSyncStep.ImportingAccountData -> R.string.initial_sync_start_importing_account_data + InitialSyncStep.ImportingAccountJoinedRooms -> R.string.initial_sync_start_importing_account_joined_rooms + InitialSyncStep.ImportingAccountInvitedRooms -> R.string.initial_sync_start_importing_account_invited_rooms + InitialSyncStep.ImportingAccountLeftRooms -> R.string.initial_sync_start_importing_account_left_rooms } ) } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewState.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewState.kt index e01c5ba3b7..47db50d0d4 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewState.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewState.kt @@ -22,11 +22,11 @@ import com.airbnb.mvrx.Uninitialized import im.vector.app.features.home.room.detail.arguments.TimelineArgs import org.matrix.android.sdk.api.extensions.orFalse import org.matrix.android.sdk.api.session.events.model.Event -import org.matrix.android.sdk.api.session.initsync.SyncStatusService import org.matrix.android.sdk.api.session.room.members.ChangeMembershipState import org.matrix.android.sdk.api.session.room.model.RoomMemberSummary import org.matrix.android.sdk.api.session.room.model.RoomSummary import org.matrix.android.sdk.api.session.room.sender.SenderInfo +import org.matrix.android.sdk.api.session.sync.SyncRequestState import org.matrix.android.sdk.api.session.sync.SyncState import org.matrix.android.sdk.api.session.threads.ThreadNotificationBadgeState import org.matrix.android.sdk.api.session.widgets.model.Widget @@ -59,7 +59,7 @@ data class RoomDetailViewState( val tombstoneEvent: Event? = null, val joinUpgradedRoomAsync: Async = Uninitialized, val syncState: SyncState = SyncState.Idle, - val incrementalSyncStatus: SyncStatusService.Status.IncrementalSyncStatus = SyncStatusService.Status.IncrementalSyncIdle, + val incrementalSyncRequestState: SyncRequestState.IncrementalSyncRequestState = SyncRequestState.IncrementalSyncIdle, val pushCounter: Int = 0, val highlightedEventId: String? = null, val unreadState: UnreadState = UnreadState.Unknown, diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt index 07bc4366e2..2b99bc67ef 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt @@ -68,6 +68,7 @@ import com.airbnb.mvrx.fragmentViewModel import com.airbnb.mvrx.withState import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.vanniktech.emoji.EmojiPopup +import im.vector.app.BuildConfig import im.vector.app.R import im.vector.app.core.animations.play import im.vector.app.core.dialogs.ConfirmationDialogBuilder @@ -430,7 +431,7 @@ class TimelineFragment @Inject constructor( timelineViewModel.onEach( RoomDetailViewState::syncState, - RoomDetailViewState::incrementalSyncStatus, + RoomDetailViewState::incrementalSyncRequestState, RoomDetailViewState::pushCounter ) { syncState, incrementalSyncStatus, pushCounter -> views.syncStateView.render( @@ -1552,7 +1553,7 @@ class TimelineFragment @Inject constructor( attachmentTypeSelector = AttachmentTypeSelectorView(vectorBaseActivity, vectorBaseActivity.layoutInflater, this@TimelineFragment) attachmentTypeSelector.setAttachmentVisibility( AttachmentTypeSelectorView.Type.LOCATION, - vectorPreferences.isLocationSharingEnabled() + BuildConfig.enableLocationSharing ) attachmentTypeSelector.setAttachmentVisibility( AttachmentTypeSelectorView.Type.POLL, !isThreadTimeLine() diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineViewModel.kt index 2a6357e088..0fcc44910c 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineViewModel.kt @@ -90,7 +90,6 @@ import org.matrix.android.sdk.api.session.events.model.toContent import org.matrix.android.sdk.api.session.events.model.toModel import org.matrix.android.sdk.api.session.file.FileService import org.matrix.android.sdk.api.session.getRoom -import org.matrix.android.sdk.api.session.initsync.SyncStatusService import org.matrix.android.sdk.api.session.room.getStateEvent import org.matrix.android.sdk.api.session.room.getTimelineEvent import org.matrix.android.sdk.api.session.room.members.ChangeMembershipState @@ -105,6 +104,7 @@ import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper import org.matrix.android.sdk.api.session.room.read.ReadService import org.matrix.android.sdk.api.session.room.timeline.Timeline import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent +import org.matrix.android.sdk.api.session.sync.SyncRequestState import org.matrix.android.sdk.api.session.threads.ThreadNotificationBadgeState import org.matrix.android.sdk.api.session.threads.ThreadNotificationState import org.matrix.android.sdk.api.session.widgets.model.WidgetType @@ -1130,11 +1130,11 @@ class TimelineViewModel @AssistedInject constructor( copy(syncState = syncState) } - session.syncStatusService().getSyncStatusLive() + session.syncService().getSyncRequestStateLive() .asFlow() - .filterIsInstance() + .filterIsInstance() .setOnEach { - copy(incrementalSyncStatus = it) + copy(incrementalSyncRequestState = it) } } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MessageItemFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MessageItemFactory.kt index ef8c41975b..19ae4e873d 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MessageItemFactory.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MessageItemFactory.kt @@ -200,24 +200,18 @@ class MessageItemFactory @Inject constructor( // val all = event.root.toContent() // val ev = all.toModel() val messageItem = when (messageContent) { - is MessageEmoteContent -> buildEmoteMessageItem(messageContent, informationData, highlight, callback, attributes) - is MessageTextContent -> buildItemForTextContent(messageContent, informationData, highlight, callback, attributes) - is MessageImageInfoContent -> buildImageMessageItem(messageContent, informationData, highlight, callback, attributes) - is MessageNoticeContent -> buildNoticeMessageItem(messageContent, informationData, highlight, callback, attributes) - is MessageVideoContent -> buildVideoMessageItem(messageContent, informationData, highlight, callback, attributes) - is MessageFileContent -> buildFileMessageItem(messageContent, highlight, attributes) - is MessageAudioContent -> buildAudioContent(params, messageContent, informationData, highlight, attributes) + is MessageEmoteContent -> buildEmoteMessageItem(messageContent, informationData, highlight, callback, attributes) + is MessageTextContent -> buildItemForTextContent(messageContent, informationData, highlight, callback, attributes) + is MessageImageInfoContent -> buildImageMessageItem(messageContent, informationData, highlight, callback, attributes) + is MessageNoticeContent -> buildNoticeMessageItem(messageContent, informationData, highlight, callback, attributes) + is MessageVideoContent -> buildVideoMessageItem(messageContent, informationData, highlight, callback, attributes) + is MessageFileContent -> buildFileMessageItem(messageContent, highlight, attributes) + is MessageAudioContent -> buildAudioContent(params, messageContent, informationData, highlight, attributes) is MessageVerificationRequestContent -> buildVerificationRequestMessageItem(messageContent, informationData, highlight, callback, attributes) - is MessagePollContent -> buildPollItem(messageContent, informationData, highlight, callback, attributes) - is MessageLocationContent -> { - if (vectorPreferences.labsRenderLocationsInTimeline()) { - buildLocationItem(messageContent, informationData, highlight, attributes) - } else { - buildMessageTextItem(messageContent.body, false, informationData, highlight, callback, attributes) - } - } - is MessageBeaconInfoContent -> liveLocationShareMessageItemFactory.create(params.event, highlight, attributes) - else -> buildNotHandledMessageItem(messageContent, informationData, highlight, callback, attributes) + is MessagePollContent -> buildPollItem(messageContent, informationData, highlight, callback, attributes) + is MessageLocationContent -> buildLocationItem(messageContent, informationData, highlight, attributes) + is MessageBeaconInfoContent -> liveLocationShareMessageItemFactory.create(params.event, highlight, attributes) + else -> buildNotHandledMessageItem(messageContent, informationData, highlight, callback, attributes) } return messageItem?.apply { layout(informationData.messageLayout.layoutRes) @@ -283,11 +277,11 @@ class MessageItemFactory @Inject constructor( pollResponseSummary: PollResponseData?, pollContent: MessagePollContent, ): PollState = when { - !informationData.sendState.isSent() -> Sending - pollResponseSummary?.isClosed.orFalse() -> Ended + !informationData.sendState.isSent() -> Sending + pollResponseSummary?.isClosed.orFalse() -> Ended pollContent.getBestPollCreationInfo()?.kind == PollType.UNDISCLOSED -> Undisclosed - pollResponseSummary?.myVote?.isNotEmpty().orFalse() -> Voted(pollResponseSummary?.totalVotes ?: 0) - else -> Ready + pollResponseSummary?.myVote?.isNotEmpty().orFalse() -> Voted(pollResponseSummary?.totalVotes ?: 0) + else -> Ready } private fun List.mapToOptions( @@ -305,11 +299,11 @@ class MessageItemFactory @Inject constructor( val isWinner = winnerVoteCount != 0 && voteCount == winnerVoteCount when (pollState) { - Sending -> PollSending(optionId, optionAnswer) - Ready -> PollReady(optionId, optionAnswer) - is Voted -> PollVoted(optionId, optionAnswer, voteCount, votePercentage, isMyVote) + Sending -> PollSending(optionId, optionAnswer) + Ready -> PollReady(optionId, optionAnswer) + is Voted -> PollVoted(optionId, optionAnswer, voteCount, votePercentage, isMyVote) Undisclosed -> PollUndisclosed(optionId, optionAnswer, isMyVote) - Ended -> PollEnded(optionId, optionAnswer, voteCount, votePercentage, isWinner) + Ended -> PollEnded(optionId, optionAnswer, voteCount, votePercentage, isWinner) } } @@ -329,11 +323,11 @@ class MessageItemFactory @Inject constructor( ): String { val votes = pollResponseSummary?.totalVotes ?: 0 return when { - pollState is Ended -> stringProvider.getQuantityString(R.plurals.poll_total_vote_count_after_ended, votes, votes) + pollState is Ended -> stringProvider.getQuantityString(R.plurals.poll_total_vote_count_after_ended, votes, votes) pollState is Undisclosed -> "" - pollState is Voted -> stringProvider.getQuantityString(R.plurals.poll_total_vote_count_before_ended_and_voted, votes, votes) - votes == 0 -> stringProvider.getString(R.string.poll_no_votes_cast) - else -> stringProvider.getQuantityString(R.plurals.poll_total_vote_count_before_ended_and_not_voted, votes, votes) + pollState is Voted -> stringProvider.getQuantityString(R.plurals.poll_total_vote_count_before_ended_and_voted, votes, votes) + votes == 0 -> stringProvider.getString(R.string.poll_no_votes_cast) + else -> stringProvider.getQuantityString(R.plurals.poll_total_vote_count_before_ended_and_not_voted, votes, votes) } } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/style/TimelineMessageLayoutFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/style/TimelineMessageLayoutFactory.kt index 580465d1c1..3d6dee371f 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/style/TimelineMessageLayoutFactory.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/style/TimelineMessageLayoutFactory.kt @@ -62,16 +62,15 @@ class TimelineMessageLayoutFactory @Inject constructor( MessageType.MSGTYPE_STICKER_LOCAL, MessageType.MSGTYPE_EMOTE, MessageType.MSGTYPE_BEACON_INFO, + MessageType.MSGTYPE_LOCATION, + MessageType.MSGTYPE_BEACON_LOCATION_DATA, ) private val MSG_TYPES_WITH_TIMESTAMP_INSIDE_MESSAGE = setOf( MessageType.MSGTYPE_IMAGE, MessageType.MSGTYPE_VIDEO, MessageType.MSGTYPE_BEACON_INFO, - ) - - private val MSG_TYPES_WITH_LOCATION_DATA = setOf( MessageType.MSGTYPE_LOCATION, - MessageType.MSGTYPE_BEACON_LOCATION_DATA + MessageType.MSGTYPE_BEACON_LOCATION_DATA, ) } @@ -147,23 +146,20 @@ class TimelineMessageLayoutFactory @Inject constructor( private fun MessageContent?.isPseudoBubble(): Boolean { if (this == null) return false - if (msgType == MessageType.MSGTYPE_LOCATION) return vectorPreferences.labsRenderLocationsInTimeline() return this.msgType in MSG_TYPES_WITH_PSEUDO_BUBBLE_LAYOUT } private fun MessageContent?.timestampInsideMessage(): Boolean { return when { - this == null -> false - msgType in MSG_TYPES_WITH_LOCATION_DATA -> vectorPreferences.labsRenderLocationsInTimeline() - else -> msgType in MSG_TYPES_WITH_TIMESTAMP_INSIDE_MESSAGE + this == null -> false + else -> msgType in MSG_TYPES_WITH_TIMESTAMP_INSIDE_MESSAGE } } private fun MessageContent?.shouldAddMessageOverlay(): Boolean { return when { this == null || msgType == MessageType.MSGTYPE_BEACON_INFO -> false - msgType == MessageType.MSGTYPE_LOCATION -> vectorPreferences.labsRenderLocationsInTimeline() - else -> msgType in MSG_TYPES_WITH_TIMESTAMP_INSIDE_MESSAGE + else -> msgType in MSG_TYPES_WITH_TIMESTAMP_INSIDE_MESSAGE } } @@ -214,10 +210,10 @@ class TimelineMessageLayoutFactory @Inject constructor( return when (event?.root?.getClearType()) { EventType.KEY_VERIFICATION_DONE, EventType.KEY_VERIFICATION_CANCEL -> true - EventType.MESSAGE -> { + EventType.MESSAGE -> { event.getLastMessageContent() is MessageVerificationRequestContent } - else -> false + else -> false } } } diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorPreferences.kt b/vector/src/main/java/im/vector/app/features/settings/VectorPreferences.kt index 24de4d47a5..ce9c068c9c 100755 --- a/vector/src/main/java/im/vector/app/features/settings/VectorPreferences.kt +++ b/vector/src/main/java/im/vector/app/features/settings/VectorPreferences.kt @@ -191,9 +191,6 @@ class VectorPreferences @Inject constructor( private const val DID_ASK_TO_ENABLE_SESSION_PUSH = "DID_ASK_TO_ENABLE_SESSION_PUSH" - // Location Sharing - const val SETTINGS_PREF_ENABLE_LOCATION_SHARING = "SETTINGS_PREF_ENABLE_LOCATION_SHARING" - private const val MEDIA_SAVING_3_DAYS = 0 private const val MEDIA_SAVING_1_WEEK = 1 private const val MEDIA_SAVING_1_MONTH = 2 @@ -203,7 +200,6 @@ class VectorPreferences @Inject constructor( private const val TAKE_PHOTO_VIDEO_MODE = "TAKE_PHOTO_VIDEO_MODE" - private const val SETTINGS_LABS_RENDER_LOCATIONS_IN_TIMELINE = "SETTINGS_LABS_RENDER_LOCATIONS_IN_TIMELINE" private const val SETTINGS_LABS_ENABLE_LIVE_LOCATION = "SETTINGS_LABS_ENABLE_LIVE_LOCATION" // This key will be used to identify clients with the old thread support enabled io.element.thread @@ -1044,14 +1040,6 @@ class VectorPreferences @Inject constructor( } } - fun isLocationSharingEnabled(): Boolean { - return defaultPrefs.getBoolean(SETTINGS_PREF_ENABLE_LOCATION_SHARING, false) && BuildConfig.enableLocationSharing - } - - fun labsRenderLocationsInTimeline(): Boolean { - return defaultPrefs.getBoolean(SETTINGS_LABS_RENDER_LOCATIONS_IN_TIMELINE, true) - } - fun labsEnableLiveLocation(): Boolean { return defaultPrefs.getBoolean(SETTINGS_LABS_ENABLE_LIVE_LOCATION, false) } diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsPreferencesFragment.kt b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsPreferencesFragment.kt index 0b4b3542b0..9f9afc8ef1 100644 --- a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsPreferencesFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsPreferencesFragment.kt @@ -24,7 +24,6 @@ import androidx.core.view.children import androidx.lifecycle.lifecycleScope import androidx.preference.Preference import com.google.android.material.dialog.MaterialAlertDialogBuilder -import im.vector.app.BuildConfig import im.vector.app.R import im.vector.app.core.dialogs.PhotoOrVideoDialog import im.vector.app.core.extensions.restart @@ -173,8 +172,6 @@ class VectorSettingsPreferencesFragment @Inject constructor( }) true } - - findPreference(VectorPreferences.SETTINGS_PREF_ENABLE_LOCATION_SHARING)?.isVisible = BuildConfig.enableLocationSharing } private fun updateTakePhotoOrVideoPreferenceSummary() { diff --git a/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutViewModel.kt b/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutViewModel.kt index 2422bc1195..34d001caad 100644 --- a/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutViewModel.kt @@ -211,7 +211,7 @@ class SoftLogoutViewModel @AssistedInject constructor( private fun onSessionRestored() { activeSessionHolder.setActiveSession(session) // Start the sync - session.startSync(true) + session.syncService().startSync(true) // TODO Configure and start ? Check that the push still works... setState { diff --git a/vector/src/main/java/im/vector/app/features/sync/widget/SyncStateView.kt b/vector/src/main/java/im/vector/app/features/sync/widget/SyncStateView.kt index 0cab972585..0e9eb91317 100755 --- a/vector/src/main/java/im/vector/app/features/sync/widget/SyncStateView.kt +++ b/vector/src/main/java/im/vector/app/features/sync/widget/SyncStateView.kt @@ -24,7 +24,7 @@ import androidx.core.view.isVisible import im.vector.app.R import im.vector.app.core.utils.isAirplaneModeOn import im.vector.app.databinding.ViewSyncStateBinding -import org.matrix.android.sdk.api.session.initsync.SyncStatusService +import org.matrix.android.sdk.api.session.sync.SyncRequestState import org.matrix.android.sdk.api.session.sync.SyncState class SyncStateView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyle: Int = 0) : @@ -41,14 +41,14 @@ class SyncStateView @JvmOverloads constructor(context: Context, attrs: Attribute @SuppressLint("SetTextI18n") fun render( newState: SyncState, - incrementalSyncStatus: SyncStatusService.Status.IncrementalSyncStatus, + incrementalSyncRequestState: SyncRequestState.IncrementalSyncRequestState, pushCounter: Int, showDebugInfo: Boolean ) { views.syncStateDebugInfo.isVisible = showDebugInfo if (showDebugInfo) { views.syncStateDebugInfoText.text = - "Sync thread : ${newState.toHumanReadable()}\nSync request: ${incrementalSyncStatus.toHumanReadable()}" + "Sync thread : ${newState.toHumanReadable()}\nSync request: ${incrementalSyncRequestState.toHumanReadable()}" views.syncStateDebugInfoPushCounter.text = "Push: $pushCounter" } @@ -66,23 +66,23 @@ class SyncStateView @JvmOverloads constructor(context: Context, attrs: Attribute private fun SyncState.toHumanReadable(): String { return when (this) { - SyncState.Idle -> "Idle" + SyncState.Idle -> "Idle" SyncState.InvalidToken -> "InvalidToken" - SyncState.Killed -> "Killed" - SyncState.Killing -> "Killing" - SyncState.NoNetwork -> "NoNetwork" - SyncState.Paused -> "Paused" - is SyncState.Running -> "$this" + SyncState.Killed -> "Killed" + SyncState.Killing -> "Killing" + SyncState.NoNetwork -> "NoNetwork" + SyncState.Paused -> "Paused" + is SyncState.Running -> "$this" } } - private fun SyncStatusService.Status.IncrementalSyncStatus.toHumanReadable(): String { + private fun SyncRequestState.IncrementalSyncRequestState.toHumanReadable(): String { return when (this) { - SyncStatusService.Status.IncrementalSyncIdle -> "Idle" - is SyncStatusService.Status.IncrementalSyncParsing -> "Parsing ${this.rooms} room(s) ${this.toDevice} toDevice(s)" - SyncStatusService.Status.IncrementalSyncError -> "Error" - SyncStatusService.Status.IncrementalSyncDone -> "Done" - else -> "?" + SyncRequestState.IncrementalSyncIdle -> "Idle" + is SyncRequestState.IncrementalSyncParsing -> "Parsing ${this.rooms} room(s) ${this.toDevice} toDevice(s)" + SyncRequestState.IncrementalSyncError -> "Error" + SyncRequestState.IncrementalSyncDone -> "Done" + else -> "?" } } } diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml index 788dee1bc3..97ef900ce3 100644 --- a/vector/src/main/res/values/strings.xml +++ b/vector/src/main/res/values/strings.xml @@ -3017,9 +3017,12 @@ ${app_name} could not access your location ${app_name} could not access your location. Please try again later. Open with - Enable location sharing - Once enabled you will be able to send your location to any room - Render user locations in the timeline + + Enable location sharing + + Once enabled you will be able to send your location to any room + + Render user locations in the timeline Failed to load map Live location enabled Loading live location… diff --git a/vector/src/main/res/xml/vector_settings_labs.xml b/vector/src/main/res/xml/vector_settings_labs.xml index 19ee7e366f..9b9293e2e2 100644 --- a/vector/src/main/res/xml/vector_settings_labs.xml +++ b/vector/src/main/res/xml/vector_settings_labs.xml @@ -64,11 +64,6 @@ android:summary="@string/labs_auto_report_uisi_desc" android:title="@string/labs_auto_report_uisi" /> - - - -