Merge remote-tracking branch 'origin/develop' into task/eric/when-arrow-alignment
# Conflicts: # matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/GroupSyncHandler.kt # matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt # vector/src/main/java/im/vector/app/features/home/HomeActivity.kt # vector/src/main/java/im/vector/app/features/home/HomeActivityViewModel.kt # vector/src/main/java/im/vector/app/features/home/InitSyncStepFormatter.kt # vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MessageItemFactory.kt # vector/src/main/java/im/vector/app/features/home/room/detail/timeline/style/TimelineMessageLayoutFactory.kt # vector/src/main/java/im/vector/app/features/sync/widget/SyncStateView.kt
This commit is contained in:
commit
6df88fba59
|
@ -49,24 +49,34 @@ body:
|
||||||
|
|
||||||
### Once tested and validated internally
|
### 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
|
- [ ] Check that the version codes are correct
|
||||||
- [ ] Copy the fastlane change to the GooglePlay console in the section en-GB.
|
- [ ] Copy the fastlane change to the GooglePlay console in the section en-GB.
|
||||||
- [ ] Push to beta release to 100% of the users
|
- [ ] Push the open testing release to 100% of the users
|
||||||
- [ ] Notify the F-Droid team so that they can schedule the publication on F-Droid
|
- [ ] 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
|
- [ ] 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 [rageshakes](https://github.com/matrix-org/element-android-rageshakes/issues)
|
||||||
- [ ] Check the crash reports on the GooglePlay console
|
- [ ] Check the crash reports on the GooglePlay console
|
||||||
- [ ] Check the Android Element room for any reported issues on the new version
|
- [ ] 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
|
- [ ] 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.
|
||||||
- [ ] Ping the Android public room and update its topic with the new available version
|
- [ ] 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
|
### Android SDK2
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,7 @@ plugins {
|
||||||
id "io.gitlab.arturbosch.detekt" version "1.20.0"
|
id "io.gitlab.arturbosch.detekt" version "1.20.0"
|
||||||
|
|
||||||
// Dependency Analysis
|
// 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
|
// https://github.com/jeremylong/DependencyCheck
|
||||||
|
|
|
@ -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
|
|
@ -0,0 +1 @@
|
||||||
|
Fix wrong status of live location sharing in timeline
|
|
@ -0,0 +1 @@
|
||||||
|
Re-organize location settings flags
|
|
@ -50,7 +50,7 @@ ext.libs = [
|
||||||
androidx : [
|
androidx : [
|
||||||
'activity' : "androidx.activity:activity:1.4.0",
|
'activity' : "androidx.activity:activity:1.4.0",
|
||||||
'appCompat' : "androidx.appcompat:appcompat:1.4.2",
|
'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",
|
'recyclerview' : "androidx.recyclerview:recyclerview:1.2.1",
|
||||||
'exifinterface' : "androidx.exifinterface:exifinterface:1.3.3",
|
'exifinterface' : "androidx.exifinterface:exifinterface:1.3.3",
|
||||||
'fragmentKtx' : "androidx.fragment:fragment-ktx:1.4.1",
|
'fragmentKtx' : "androidx.fragment:fragment-ktx:1.4.1",
|
||||||
|
|
|
@ -88,7 +88,7 @@ class FlowSession(private val session: Session) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun liveSyncState(): Flow<SyncState> {
|
fun liveSyncState(): Flow<SyncState> {
|
||||||
return session.getSyncStateLive().asFlow()
|
return session.syncService().getSyncStateLive().asFlow()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun livePushers(): Flow<List<Pusher>> {
|
fun livePushers(): Flow<List<Pusher>> {
|
||||||
|
|
|
@ -176,7 +176,7 @@ dependencies {
|
||||||
implementation libs.androidx.work
|
implementation libs.androidx.work
|
||||||
|
|
||||||
// olm lib is now hosted in MavenCentral
|
// 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
|
// DI
|
||||||
implementation libs.dagger.dagger
|
implementation libs.dagger.dagger
|
||||||
|
|
|
@ -137,11 +137,11 @@ class CommonTestHelper private constructor(context: Context) {
|
||||||
fun syncSession(session: Session, timeout: Long = TestConstants.timeOutMillis * 10) {
|
fun syncSession(session: Session, timeout: Long = TestConstants.timeOutMillis * 10) {
|
||||||
val lock = CountDownLatch(1)
|
val lock = CountDownLatch(1)
|
||||||
coroutineScope.launch {
|
coroutineScope.launch {
|
||||||
session.startSync(true)
|
session.syncService().startSync(true)
|
||||||
val syncLiveData = session.getSyncStateLive()
|
val syncLiveData = session.syncService().getSyncStateLive()
|
||||||
val syncObserver = object : Observer<SyncState> {
|
val syncObserver = object : Observer<SyncState> {
|
||||||
override fun onChanged(t: SyncState?) {
|
override fun onChanged(t: SyncState?) {
|
||||||
if (session.hasAlreadySynced()) {
|
if (session.syncService().hasAlreadySynced()) {
|
||||||
lock.countDown()
|
lock.countDown()
|
||||||
syncLiveData.removeObserver(this)
|
syncLiveData.removeObserver(this)
|
||||||
}
|
}
|
||||||
|
@ -160,10 +160,10 @@ class CommonTestHelper private constructor(context: Context) {
|
||||||
fun clearCacheAndSync(session: Session, timeout: Long = TestConstants.timeOutMillis) {
|
fun clearCacheAndSync(session: Session, timeout: Long = TestConstants.timeOutMillis) {
|
||||||
waitWithLatch(timeout) { latch ->
|
waitWithLatch(timeout) { latch ->
|
||||||
session.clearCache()
|
session.clearCache()
|
||||||
val syncLiveData = session.getSyncStateLive()
|
val syncLiveData = session.syncService().getSyncStateLive()
|
||||||
val syncObserver = object : Observer<SyncState> {
|
val syncObserver = object : Observer<SyncState> {
|
||||||
override fun onChanged(t: SyncState?) {
|
override fun onChanged(t: SyncState?) {
|
||||||
if (session.hasAlreadySynced()) {
|
if (session.syncService().hasAlreadySynced()) {
|
||||||
Timber.v("Clear cache and synced")
|
Timber.v("Clear cache and synced")
|
||||||
syncLiveData.removeObserver(this)
|
syncLiveData.removeObserver(this)
|
||||||
latch.countDown()
|
latch.countDown()
|
||||||
|
@ -171,7 +171,7 @@ class CommonTestHelper private constructor(context: Context) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
syncLiveData.observeForever(syncObserver)
|
syncLiveData.observeForever(syncObserver)
|
||||||
session.startSync(true)
|
session.syncService().startSync(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -424,7 +424,7 @@ class KeyShareTests : InstrumentedTest {
|
||||||
|
|
||||||
// /!\ Stop initial alice session syncing so that it can't reply
|
// /!\ Stop initial alice session syncing so that it can't reply
|
||||||
aliceSession.cryptoService().enableKeyGossiping(false)
|
aliceSession.cryptoService().enableKeyGossiping(false)
|
||||||
aliceSession.stopSync()
|
aliceSession.syncService().stopSync()
|
||||||
|
|
||||||
// Let's now try to request
|
// Let's now try to request
|
||||||
aliceNewSession.cryptoService().reRequestRoomKeyForEvent(sentEvents.first().root)
|
aliceNewSession.cryptoService().reRequestRoomKeyForEvent(sentEvents.first().root)
|
||||||
|
@ -447,7 +447,7 @@ class KeyShareTests : InstrumentedTest {
|
||||||
|
|
||||||
// let's wake up alice
|
// let's wake up alice
|
||||||
aliceSession.cryptoService().enableKeyGossiping(true)
|
aliceSession.cryptoService().enableKeyGossiping(true)
|
||||||
aliceSession.startSync(true)
|
aliceSession.syncService().startSync(true)
|
||||||
|
|
||||||
// We should now get a reply from first session
|
// We should now get a reply from first session
|
||||||
commonTestHelper.waitWithLatch { latch ->
|
commonTestHelper.waitWithLatch { latch ->
|
||||||
|
|
|
@ -83,7 +83,7 @@ class ThreadMessagingTest : InstrumentedTest {
|
||||||
val timeline = aliceRoom.timelineService().createTimeline(null, TimelineSettings(30))
|
val timeline = aliceRoom.timelineService().createTimeline(null, TimelineSettings(30))
|
||||||
timeline.start()
|
timeline.start()
|
||||||
|
|
||||||
aliceSession.startSync(true)
|
aliceSession.syncService().startSync(true)
|
||||||
run {
|
run {
|
||||||
val lock = CountDownLatch(1)
|
val lock = CountDownLatch(1)
|
||||||
val eventsListener = commonTestHelper.createEventListener(lock) { snapshot ->
|
val eventsListener = commonTestHelper.createEventListener(lock) { snapshot ->
|
||||||
|
@ -97,7 +97,7 @@ class ThreadMessagingTest : InstrumentedTest {
|
||||||
timeline.addListener(eventsListener)
|
timeline.addListener(eventsListener)
|
||||||
commonTestHelper.await(lock, 600_000)
|
commonTestHelper.await(lock, 600_000)
|
||||||
}
|
}
|
||||||
aliceSession.stopSync()
|
aliceSession.syncService().stopSync()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -144,7 +144,7 @@ class ThreadMessagingTest : InstrumentedTest {
|
||||||
val timeline = aliceRoom.timelineService().createTimeline(null, TimelineSettings(30))
|
val timeline = aliceRoom.timelineService().createTimeline(null, TimelineSettings(30))
|
||||||
timeline.start()
|
timeline.start()
|
||||||
|
|
||||||
aliceSession.startSync(true)
|
aliceSession.syncService().startSync(true)
|
||||||
run {
|
run {
|
||||||
val lock = CountDownLatch(1)
|
val lock = CountDownLatch(1)
|
||||||
val eventsListener = commonTestHelper.createEventListener(lock) { snapshot ->
|
val eventsListener = commonTestHelper.createEventListener(lock) { snapshot ->
|
||||||
|
@ -156,9 +156,9 @@ class ThreadMessagingTest : InstrumentedTest {
|
||||||
timeline.addListener(eventsListener)
|
timeline.addListener(eventsListener)
|
||||||
commonTestHelper.await(lock, 600_000)
|
commonTestHelper.await(lock, 600_000)
|
||||||
}
|
}
|
||||||
aliceSession.stopSync()
|
aliceSession.syncService().stopSync()
|
||||||
|
|
||||||
bobSession.startSync(true)
|
bobSession.syncService().startSync(true)
|
||||||
run {
|
run {
|
||||||
val lock = CountDownLatch(1)
|
val lock = CountDownLatch(1)
|
||||||
val eventsListener = commonTestHelper.createEventListener(lock) { snapshot ->
|
val eventsListener = commonTestHelper.createEventListener(lock) { snapshot ->
|
||||||
|
@ -170,7 +170,7 @@ class ThreadMessagingTest : InstrumentedTest {
|
||||||
timeline.addListener(eventsListener)
|
timeline.addListener(eventsListener)
|
||||||
commonTestHelper.await(lock, 600_000)
|
commonTestHelper.await(lock, 600_000)
|
||||||
}
|
}
|
||||||
bobSession.stopSync()
|
bobSession.syncService().stopSync()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -217,7 +217,7 @@ class ThreadMessagingTest : InstrumentedTest {
|
||||||
val timeline = aliceRoom.timelineService().createTimeline(null, TimelineSettings(30))
|
val timeline = aliceRoom.timelineService().createTimeline(null, TimelineSettings(30))
|
||||||
timeline.start()
|
timeline.start()
|
||||||
|
|
||||||
aliceSession.startSync(true)
|
aliceSession.syncService().startSync(true)
|
||||||
run {
|
run {
|
||||||
val lock = CountDownLatch(1)
|
val lock = CountDownLatch(1)
|
||||||
val eventsListener = commonTestHelper.createEventListener(lock) { snapshot ->
|
val eventsListener = commonTestHelper.createEventListener(lock) { snapshot ->
|
||||||
|
@ -233,7 +233,7 @@ class ThreadMessagingTest : InstrumentedTest {
|
||||||
timeline.addListener(eventsListener)
|
timeline.addListener(eventsListener)
|
||||||
commonTestHelper.await(lock, 600_000)
|
commonTestHelper.await(lock, 600_000)
|
||||||
}
|
}
|
||||||
aliceSession.stopSync()
|
aliceSession.syncService().stopSync()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -314,7 +314,7 @@ class ThreadMessagingTest : InstrumentedTest {
|
||||||
val timeline = aliceRoom.timelineService().createTimeline(null, TimelineSettings(30))
|
val timeline = aliceRoom.timelineService().createTimeline(null, TimelineSettings(30))
|
||||||
timeline.start()
|
timeline.start()
|
||||||
|
|
||||||
aliceSession.startSync(true)
|
aliceSession.syncService().startSync(true)
|
||||||
run {
|
run {
|
||||||
val lock = CountDownLatch(1)
|
val lock = CountDownLatch(1)
|
||||||
val eventsListener = commonTestHelper.createEventListener(lock) { snapshot ->
|
val eventsListener = commonTestHelper.createEventListener(lock) { snapshot ->
|
||||||
|
@ -338,6 +338,6 @@ class ThreadMessagingTest : InstrumentedTest {
|
||||||
timeline.addListener(eventsListener)
|
timeline.addListener(eventsListener)
|
||||||
commonTestHelper.await(lock, 600_000)
|
commonTestHelper.await(lock, 600_000)
|
||||||
}
|
}
|
||||||
aliceSession.stopSync()
|
aliceSession.syncService().stopSync()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,7 +57,7 @@ class PollAggregationTest : InstrumentedTest {
|
||||||
// Bob creates a poll
|
// Bob creates a poll
|
||||||
roomFromBobPOV.sendService().sendPoll(PollType.DISCLOSED, pollQuestion, pollOptions)
|
roomFromBobPOV.sendService().sendPoll(PollType.DISCLOSED, pollQuestion, pollOptions)
|
||||||
|
|
||||||
aliceSession.startSync(true)
|
aliceSession.syncService().startSync(true)
|
||||||
val aliceTimeline = roomFromAlicePOV.timelineService().createTimeline(null, TimelineSettings(30))
|
val aliceTimeline = roomFromAlicePOV.timelineService().createTimeline(null, TimelineSettings(30))
|
||||||
aliceTimeline.start()
|
aliceTimeline.start()
|
||||||
|
|
||||||
|
@ -133,7 +133,7 @@ class PollAggregationTest : InstrumentedTest {
|
||||||
|
|
||||||
aliceTimeline.removeAllListeners()
|
aliceTimeline.removeAllListeners()
|
||||||
|
|
||||||
aliceSession.stopSync()
|
aliceSession.syncService().stopSync()
|
||||||
aliceTimeline.dispose()
|
aliceTimeline.dispose()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -88,7 +88,7 @@ class TimelinePreviousLastForwardTest : InstrumentedTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bob stop to sync
|
// Bob stop to sync
|
||||||
bobSession.stopSync()
|
bobSession.syncService().stopSync()
|
||||||
|
|
||||||
val firstMessage = "First messages from Alice"
|
val firstMessage = "First messages from Alice"
|
||||||
// Alice sends 30 messages
|
// Alice sends 30 messages
|
||||||
|
@ -101,7 +101,7 @@ class TimelinePreviousLastForwardTest : InstrumentedTest {
|
||||||
.eventId
|
.eventId
|
||||||
|
|
||||||
// Bob start to sync
|
// Bob start to sync
|
||||||
bobSession.startSync(true)
|
bobSession.syncService().startSync(true)
|
||||||
|
|
||||||
run {
|
run {
|
||||||
val lock = CountDownLatch(1)
|
val lock = CountDownLatch(1)
|
||||||
|
@ -125,7 +125,7 @@ class TimelinePreviousLastForwardTest : InstrumentedTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bob stop to sync
|
// Bob stop to sync
|
||||||
bobSession.stopSync()
|
bobSession.syncService().stopSync()
|
||||||
|
|
||||||
val secondMessage = "Second messages from Alice"
|
val secondMessage = "Second messages from Alice"
|
||||||
// Alice sends again 30 messages
|
// Alice sends again 30 messages
|
||||||
|
@ -136,7 +136,7 @@ class TimelinePreviousLastForwardTest : InstrumentedTest {
|
||||||
)
|
)
|
||||||
|
|
||||||
// Bob start to sync
|
// Bob start to sync
|
||||||
bobSession.startSync(true)
|
bobSession.syncService().startSync(true)
|
||||||
|
|
||||||
run {
|
run {
|
||||||
val lock = CountDownLatch(1)
|
val lock = CountDownLatch(1)
|
||||||
|
|
|
@ -71,7 +71,7 @@ class TimelineWithManyMembersTest : InstrumentedTest {
|
||||||
val timelineForCurrentMember = roomForCurrentMember.timelineService().createTimeline(null, TimelineSettings(30))
|
val timelineForCurrentMember = roomForCurrentMember.timelineService().createTimeline(null, TimelineSettings(30))
|
||||||
timelineForCurrentMember.start()
|
timelineForCurrentMember.start()
|
||||||
|
|
||||||
session.startSync(true)
|
session.syncService().startSync(true)
|
||||||
|
|
||||||
run {
|
run {
|
||||||
val lock = CountDownLatch(1)
|
val lock = CountDownLatch(1)
|
||||||
|
@ -92,7 +92,7 @@ class TimelineWithManyMembersTest : InstrumentedTest {
|
||||||
timelineForCurrentMember.addListener(eventsListener)
|
timelineForCurrentMember.addListener(eventsListener)
|
||||||
commonTestHelper.await(lock, 600_000)
|
commonTestHelper.await(lock, 600_000)
|
||||||
}
|
}
|
||||||
session.stopSync()
|
session.syncService().stopSync()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,8 +17,6 @@
|
||||||
package org.matrix.android.sdk.api.session
|
package org.matrix.android.sdk.api.session
|
||||||
|
|
||||||
import androidx.annotation.MainThread
|
import androidx.annotation.MainThread
|
||||||
import androidx.lifecycle.LiveData
|
|
||||||
import kotlinx.coroutines.flow.SharedFlow
|
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
import org.matrix.android.sdk.api.MatrixCoroutineDispatchers
|
import org.matrix.android.sdk.api.MatrixCoroutineDispatchers
|
||||||
import org.matrix.android.sdk.api.auth.data.SessionParams
|
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.group.GroupService
|
||||||
import org.matrix.android.sdk.api.session.homeserver.HomeServerCapabilitiesService
|
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.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.integrationmanager.IntegrationManagerService
|
||||||
import org.matrix.android.sdk.api.session.media.MediaService
|
import org.matrix.android.sdk.api.session.media.MediaService
|
||||||
import org.matrix.android.sdk.api.session.openid.OpenIdService
|
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.space.SpaceService
|
||||||
import org.matrix.android.sdk.api.session.statistics.StatisticsListener
|
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.FilterService
|
||||||
import org.matrix.android.sdk.api.session.sync.SyncState
|
import org.matrix.android.sdk.api.session.sync.SyncService
|
||||||
import org.matrix.android.sdk.api.session.sync.model.SyncResponse
|
|
||||||
import org.matrix.android.sdk.api.session.terms.TermsService
|
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.thirdparty.ThirdPartyService
|
||||||
import org.matrix.android.sdk.api.session.typing.TypingUsersTracker
|
import org.matrix.android.sdk.api.session.typing.TypingUsersTracker
|
||||||
|
@ -98,59 +94,11 @@ interface Session {
|
||||||
@MainThread
|
@MainThread
|
||||||
fun open()
|
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.
|
* Clear cache of the session.
|
||||||
*/
|
*/
|
||||||
suspend fun clearCache()
|
suspend fun clearCache()
|
||||||
|
|
||||||
/**
|
|
||||||
* This method allows to listen the sync state.
|
|
||||||
* @return a [LiveData] of [SyncState].
|
|
||||||
*/
|
|
||||||
fun getSyncStateLive(): LiveData<SyncState>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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<SyncResponse>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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.
|
* This method allow to close a session. It does stop some services.
|
||||||
*/
|
*/
|
||||||
|
@ -247,9 +195,9 @@ interface Session {
|
||||||
fun termsService(): TermsService
|
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.
|
* Returns the SecureStorageService associated with the session.
|
||||||
|
|
|
@ -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<Status>
|
|
||||||
|
|
||||||
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()
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -14,9 +14,9 @@
|
||||||
* limitations under the License.
|
* 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,
|
ServerComputing,
|
||||||
Downloading,
|
Downloading,
|
||||||
ImportingAccount,
|
ImportingAccount,
|
|
@ -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
|
||||||
|
}
|
|
@ -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<SyncState>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the [SyncRequestState] as a LiveData.
|
||||||
|
*/
|
||||||
|
fun getSyncRequestStateLive(): LiveData<SyncRequestState>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method returns a flow of SyncResponse. New value will be pushed through the sync thread.
|
||||||
|
*/
|
||||||
|
fun syncFlow(): SharedFlow<SyncResponse>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This methods return true if an initial sync has been processed.
|
||||||
|
*/
|
||||||
|
fun hasAlreadySynced(): Boolean
|
||||||
|
}
|
|
@ -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.
|
* in order to be able to perform a sync even if the app is not running.
|
||||||
* The <receiver> and <service> must be declared in the Manifest or the app using the SDK
|
* The <receiver> and <service> 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 sessionId: String? = null
|
||||||
private var mIsSelfDestroyed: Boolean = false
|
private var mIsSelfDestroyed: Boolean = false
|
||||||
|
@ -158,9 +158,9 @@ abstract class SyncService : Service() {
|
||||||
// never do that in foreground, let the syncThread work
|
// never do that in foreground, let the syncThread work
|
||||||
syncTask.execute(params)
|
syncTask.execute(params)
|
||||||
// Start sync if we were doing an initial sync and the syncThread is not launched yet
|
// 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
|
val isForeground = !backgroundDetectionObserver.isInBackground
|
||||||
session.startSync(isForeground)
|
session.syncService().startSync(isForeground)
|
||||||
}
|
}
|
||||||
stopMe()
|
stopMe()
|
||||||
} catch (throwable: Throwable) {
|
} catch (throwable: Throwable) {
|
||||||
|
@ -210,7 +210,7 @@ abstract class SyncService : Service() {
|
||||||
session = sessionComponent.session()
|
session = sessionComponent.session()
|
||||||
sessionId = safeSessionId
|
sessionId = safeSessionId
|
||||||
syncTask = sessionComponent.syncTask()
|
syncTask = sessionComponent.syncTask()
|
||||||
isInitialSync = !session.hasAlreadySynced()
|
isInitialSync = !session.syncService().hasAlreadySynced()
|
||||||
networkConnectivityChecker = sessionComponent.networkConnectivityChecker()
|
networkConnectivityChecker = sessionComponent.networkConnectivityChecker()
|
||||||
taskExecutor = sessionComponent.taskExecutor()
|
taskExecutor = sessionComponent.taskExecutor()
|
||||||
coroutineDispatchers = sessionComponent.coroutineDispatchers()
|
coroutineDispatchers = sessionComponent.coroutineDispatchers()
|
|
@ -55,7 +55,7 @@ internal class SessionManager @Inject constructor(
|
||||||
|
|
||||||
fun stopSession(sessionId: String) {
|
fun stopSession(sessionId: String) {
|
||||||
val sessionComponent = sessionComponents[sessionId] ?: throw RuntimeException("You don't have a session for id $sessionId")
|
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 {
|
fun getOrCreateSessionComponent(sessionParams: SessionParams): SessionComponent {
|
||||||
|
|
|
@ -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.group.GroupService
|
||||||
import org.matrix.android.sdk.api.session.homeserver.HomeServerCapabilitiesService
|
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.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.integrationmanager.IntegrationManagerService
|
||||||
import org.matrix.android.sdk.api.session.media.MediaService
|
import org.matrix.android.sdk.api.session.media.MediaService
|
||||||
import org.matrix.android.sdk.api.session.openid.OpenIdService
|
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.signout.SignOutService
|
||||||
import org.matrix.android.sdk.api.session.space.SpaceService
|
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.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.terms.TermsService
|
||||||
import org.matrix.android.sdk.api.session.thirdparty.ThirdPartyService
|
import org.matrix.android.sdk.api.session.thirdparty.ThirdPartyService
|
||||||
import org.matrix.android.sdk.api.session.typing.TypingUsersTracker
|
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.UnauthenticatedWithCertificate
|
||||||
import org.matrix.android.sdk.internal.di.WorkManagerProvider
|
import org.matrix.android.sdk.internal.di.WorkManagerProvider
|
||||||
import org.matrix.android.sdk.internal.network.GlobalErrorHandler
|
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 org.matrix.android.sdk.internal.util.createUIHandler
|
||||||
import timber.log.Timber
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Provider
|
|
||||||
|
|
||||||
@SessionScope
|
@SessionScope
|
||||||
internal class DefaultSession @Inject constructor(
|
internal class DefaultSession @Inject constructor(
|
||||||
|
@ -112,16 +107,14 @@ internal class DefaultSession @Inject constructor(
|
||||||
private val permalinkService: Lazy<PermalinkService>,
|
private val permalinkService: Lazy<PermalinkService>,
|
||||||
private val secureStorageService: Lazy<SecureStorageService>,
|
private val secureStorageService: Lazy<SecureStorageService>,
|
||||||
private val profileService: Lazy<ProfileService>,
|
private val profileService: Lazy<ProfileService>,
|
||||||
|
private val syncService: Lazy<SyncService>,
|
||||||
private val mediaService: Lazy<MediaService>,
|
private val mediaService: Lazy<MediaService>,
|
||||||
private val widgetService: Lazy<WidgetService>,
|
private val widgetService: Lazy<WidgetService>,
|
||||||
private val syncThreadProvider: Provider<SyncThread>,
|
|
||||||
private val contentUrlResolver: ContentUrlResolver,
|
private val contentUrlResolver: ContentUrlResolver,
|
||||||
private val syncTokenStore: SyncTokenStore,
|
|
||||||
private val sessionParamsStore: SessionParamsStore,
|
private val sessionParamsStore: SessionParamsStore,
|
||||||
private val contentUploadProgressTracker: ContentUploadStateTracker,
|
private val contentUploadProgressTracker: ContentUploadStateTracker,
|
||||||
private val typingUsersTracker: TypingUsersTracker,
|
private val typingUsersTracker: TypingUsersTracker,
|
||||||
private val contentDownloadStateTracker: ContentDownloadStateTracker,
|
private val contentDownloadStateTracker: ContentDownloadStateTracker,
|
||||||
private val syncStatusService: Lazy<SyncStatusService>,
|
|
||||||
private val homeServerCapabilitiesService: Lazy<HomeServerCapabilitiesService>,
|
private val homeServerCapabilitiesService: Lazy<HomeServerCapabilitiesService>,
|
||||||
private val accountDataService: Lazy<SessionAccountDataService>,
|
private val accountDataService: Lazy<SessionAccountDataService>,
|
||||||
private val sharedSecretStorageService: Lazy<SharedSecretStorageService>,
|
private val sharedSecretStorageService: Lazy<SharedSecretStorageService>,
|
||||||
|
@ -138,14 +131,11 @@ internal class DefaultSession @Inject constructor(
|
||||||
private val toDeviceService: Lazy<ToDeviceService>,
|
private val toDeviceService: Lazy<ToDeviceService>,
|
||||||
private val eventStreamService: Lazy<EventStreamService>,
|
private val eventStreamService: Lazy<EventStreamService>,
|
||||||
@UnauthenticatedWithCertificate
|
@UnauthenticatedWithCertificate
|
||||||
private val unauthenticatedWithCertificateOkHttpClient: Lazy<OkHttpClient>
|
private val unauthenticatedWithCertificateOkHttpClient: Lazy<OkHttpClient>,
|
||||||
|
private val sessionState: SessionState,
|
||||||
) : Session,
|
) : Session,
|
||||||
GlobalErrorHandler.Listener {
|
GlobalErrorHandler.Listener {
|
||||||
|
|
||||||
private var isOpen = false
|
|
||||||
|
|
||||||
private var syncThread: SyncThread? = null
|
|
||||||
|
|
||||||
private val uiHandler = createUIHandler()
|
private val uiHandler = createUIHandler()
|
||||||
|
|
||||||
override val isOpenable: Boolean
|
override val isOpenable: Boolean
|
||||||
|
@ -153,8 +143,7 @@ internal class DefaultSession @Inject constructor(
|
||||||
|
|
||||||
@MainThread
|
@MainThread
|
||||||
override fun open() {
|
override fun open() {
|
||||||
assert(!isOpen)
|
sessionState.setIsOpen(true)
|
||||||
isOpen = true
|
|
||||||
globalErrorHandler.listener = this
|
globalErrorHandler.listener = this
|
||||||
cryptoService.get().ensureDevice()
|
cryptoService.get().ensureDevice()
|
||||||
uiHandler.post {
|
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() {
|
override fun close() {
|
||||||
assert(isOpen)
|
assert(sessionState.isOpen)
|
||||||
stopSync()
|
syncService.get().stopSync()
|
||||||
// timelineEventDecryptor.destroy()
|
// timelineEventDecryptor.destroy()
|
||||||
uiHandler.post {
|
uiHandler.post {
|
||||||
lifecycleObservers.forEach { it.onSessionStopped(this) }
|
lifecycleObservers.forEach { it.onSessionStopped(this) }
|
||||||
|
@ -210,28 +168,12 @@ internal class DefaultSession @Inject constructor(
|
||||||
}
|
}
|
||||||
cryptoService.get().close()
|
cryptoService.get().close()
|
||||||
globalErrorHandler.listener = null
|
globalErrorHandler.listener = null
|
||||||
isOpen = false
|
sessionState.setIsOpen(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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun clearCache() {
|
override suspend fun clearCache() {
|
||||||
stopSync()
|
syncService.get().stopSync()
|
||||||
stopAnyBackgroundSync()
|
syncService.get().stopAnyBackgroundSync()
|
||||||
uiHandler.post {
|
uiHandler.post {
|
||||||
lifecycleObservers.forEach {
|
lifecycleObservers.forEach {
|
||||||
it.onClearCache(this)
|
it.onClearCache(this)
|
||||||
|
@ -271,7 +213,7 @@ internal class DefaultSession @Inject constructor(
|
||||||
override fun pushersService(): PushersService = pushersService.get()
|
override fun pushersService(): PushersService = pushersService.get()
|
||||||
override fun eventService(): EventService = eventService.get()
|
override fun eventService(): EventService = eventService.get()
|
||||||
override fun termsService(): TermsService = termsService.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 secureStorageService(): SecureStorageService = secureStorageService.get()
|
||||||
override fun profileService(): ProfileService = profileService.get()
|
override fun profileService(): ProfileService = profileService.get()
|
||||||
override fun presenceService(): PresenceService = presenceService.get()
|
override fun presenceService(): PresenceService = presenceService.get()
|
||||||
|
|
|
@ -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.accountdata.SessionAccountDataService
|
||||||
import org.matrix.android.sdk.api.session.events.EventService
|
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.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.openid.OpenIdService
|
||||||
import org.matrix.android.sdk.api.session.permalinks.PermalinkService
|
import org.matrix.android.sdk.api.session.permalinks.PermalinkService
|
||||||
import org.matrix.android.sdk.api.session.securestorage.SecureStorageService
|
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.events.DefaultEventService
|
||||||
import org.matrix.android.sdk.internal.session.homeserver.DefaultHomeServerCapabilitiesService
|
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.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.integrationmanager.IntegrationManager
|
||||||
import org.matrix.android.sdk.internal.session.openid.DefaultOpenIdService
|
import org.matrix.android.sdk.internal.session.openid.DefaultOpenIdService
|
||||||
import org.matrix.android.sdk.internal.session.permalinks.DefaultPermalinkService
|
import org.matrix.android.sdk.internal.session.permalinks.DefaultPermalinkService
|
||||||
|
@ -362,9 +360,6 @@ internal abstract class SessionModule {
|
||||||
@IntoSet
|
@IntoSet
|
||||||
abstract fun bindEventSenderProcessorAsSessionLifecycleObserver(processor: EventSenderProcessorCoroutine): SessionLifecycleObserver
|
abstract fun bindEventSenderProcessorAsSessionLifecycleObserver(processor: EventSenderProcessorCoroutine): SessionLifecycleObserver
|
||||||
|
|
||||||
@Binds
|
|
||||||
abstract fun bindSyncStatusService(service: DefaultSyncStatusService): SyncStatusService
|
|
||||||
|
|
||||||
@Binds
|
@Binds
|
||||||
abstract fun bindSecureStorageService(service: DefaultSecureStorageService): SecureStorageService
|
abstract fun bindSecureStorageService(service: DefaultSecureStorageService): SecureStorageService
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
|
@ -75,6 +75,7 @@ internal class DeactivateLiveLocationShareWorker(context: Context, params: Worke
|
||||||
|
|
||||||
private suspend fun deactivateLiveLocationShare(params: Params) {
|
private suspend fun deactivateLiveLocationShare(params: Params) {
|
||||||
awaitTransaction(realmConfiguration) { realm ->
|
awaitTransaction(realmConfiguration) { realm ->
|
||||||
|
Timber.d("deactivating live with id=${params.eventId}")
|
||||||
val aggregatedSummary = LiveLocationShareAggregatedSummaryEntity.get(
|
val aggregatedSummary = LiveLocationShareAggregatedSummaryEntity.get(
|
||||||
realm = realm,
|
realm = realm,
|
||||||
roomId = params.roomId,
|
roomId = params.roomId,
|
||||||
|
|
|
@ -67,16 +67,18 @@ internal class LiveLocationAggregationProcessor @Inject constructor(
|
||||||
eventId = targetEventId
|
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) }
|
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.endOfLiveTimestampMillis = endOfLiveTimestampMillis
|
||||||
aggregatedSummary.isActive = isLive
|
aggregatedSummary.isActive = isActive
|
||||||
aggregatedSummary.userId = event.senderId
|
aggregatedSummary.userId = event.senderId
|
||||||
|
|
||||||
deactivateAllPreviousBeacons(realm, roomId, event.senderId, targetEventId)
|
deactivateAllPreviousBeacons(realm, roomId, event.senderId, targetEventId)
|
||||||
|
|
||||||
if (isLive) {
|
if (isActive) {
|
||||||
scheduleDeactivationAfterTimeout(targetEventId, roomId, endOfLiveTimestampMillis)
|
scheduleDeactivationAfterTimeout(targetEventId, roomId, endOfLiveTimestampMillis)
|
||||||
} else {
|
} else {
|
||||||
cancelDeactivationAfterTimeout(targetEventId, roomId)
|
cancelDeactivationAfterTimeout(targetEventId, roomId)
|
||||||
|
@ -90,6 +92,7 @@ internal class LiveLocationAggregationProcessor @Inject constructor(
|
||||||
val workData = WorkerParamsFactory.toData(workParams)
|
val workData = WorkerParamsFactory.toData(workParams)
|
||||||
val workName = DeactivateLiveLocationShareWorker.getWorkName(eventId = eventId, roomId = roomId)
|
val workName = DeactivateLiveLocationShareWorker.getWorkName(eventId = eventId, roomId = roomId)
|
||||||
val workDelayMillis = (endOfLiveTimestampMillis - clock.epochMillis()).coerceAtLeast(0)
|
val workDelayMillis = (endOfLiveTimestampMillis - clock.epochMillis()).coerceAtLeast(0)
|
||||||
|
Timber.d("scheduling deactivation of $eventId after $workDelayMillis millis")
|
||||||
val workRequest = workManagerProvider.matrixOneTimeWorkRequestBuilder<DeactivateLiveLocationShareWorker>()
|
val workRequest = workManagerProvider.matrixOneTimeWorkRequestBuilder<DeactivateLiveLocationShareWorker>()
|
||||||
.setInitialDelay(workDelayMillis, TimeUnit.MILLISECONDS)
|
.setInitialDelay(workDelayMillis, TimeUnit.MILLISECONDS)
|
||||||
.setInputData(workData)
|
.setInputData(workData)
|
||||||
|
|
|
@ -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<SyncThread>,
|
||||||
|
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<SyncRequestState> {
|
||||||
|
return syncRequestStateTracker.syncRequestState
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hasAlreadySynced(): Boolean {
|
||||||
|
return syncTokenStore.getLastToken() != null
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getSyncThread(): SyncThread {
|
||||||
|
return syncThread ?: syncThreadProvider.get().also {
|
||||||
|
syncThread = it
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -14,18 +14,18 @@
|
||||||
* limitations under the License.
|
* 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 <T> reportSubtask(
|
internal inline fun <T> reportSubtask(
|
||||||
reporter: ProgressReporter?,
|
reporter: ProgressReporter?,
|
||||||
initSyncStep: InitSyncStep,
|
initialSyncStep: InitialSyncStep,
|
||||||
totalProgress: Int,
|
totalProgress: Int,
|
||||||
parentWeight: Float,
|
parentWeight: Float,
|
||||||
block: () -> T
|
block: () -> T
|
||||||
): T {
|
): T {
|
||||||
reporter?.startTask(initSyncStep, totalProgress, parentWeight)
|
reporter?.startTask(initialSyncStep, totalProgress, parentWeight)
|
||||||
return block().also {
|
return block().also {
|
||||||
reporter?.endTask()
|
reporter?.endTask()
|
||||||
}
|
}
|
||||||
|
@ -33,12 +33,12 @@ internal inline fun <T> reportSubtask(
|
||||||
|
|
||||||
internal inline fun <K, V, R> Map<out K, V>.mapWithProgress(
|
internal inline fun <K, V, R> Map<out K, V>.mapWithProgress(
|
||||||
reporter: ProgressReporter?,
|
reporter: ProgressReporter?,
|
||||||
initSyncStep: InitSyncStep,
|
initialSyncStep: InitialSyncStep,
|
||||||
parentWeight: Float,
|
parentWeight: Float,
|
||||||
transform: (Map.Entry<K, V>) -> R
|
transform: (Map.Entry<K, V>) -> R
|
||||||
): List<R> {
|
): List<R> {
|
||||||
var current = 0F
|
var current = 0F
|
||||||
reporter?.startTask(initSyncStep, count() + 1, parentWeight)
|
reporter?.startTask(initialSyncStep, count() + 1, parentWeight)
|
||||||
return map {
|
return map {
|
||||||
reporter?.reportProgress(current)
|
reporter?.reportProgress(current)
|
||||||
current++
|
current++
|
|
@ -14,13 +14,13 @@
|
||||||
* limitations under the License.
|
* 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 {
|
internal interface ProgressReporter {
|
||||||
fun startTask(
|
fun startTask(
|
||||||
initSyncStep: InitSyncStep,
|
initialSyncStep: InitialSyncStep,
|
||||||
totalProgress: Int,
|
totalProgress: Int,
|
||||||
parentWeight: Float
|
parentWeight: Float
|
||||||
)
|
)
|
|
@ -19,6 +19,7 @@ package org.matrix.android.sdk.internal.session.sync
|
||||||
import dagger.Binds
|
import dagger.Binds
|
||||||
import dagger.Module
|
import dagger.Module
|
||||||
import dagger.Provides
|
import dagger.Provides
|
||||||
|
import org.matrix.android.sdk.api.session.sync.SyncService
|
||||||
import org.matrix.android.sdk.internal.session.SessionScope
|
import org.matrix.android.sdk.internal.session.SessionScope
|
||||||
import retrofit2.Retrofit
|
import retrofit2.Retrofit
|
||||||
|
|
||||||
|
@ -35,6 +36,9 @@ internal abstract class SyncModule {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
abstract fun bindSyncService(service: DefaultSyncService): SyncService
|
||||||
|
|
||||||
@Binds
|
@Binds
|
||||||
abstract fun bindSyncTask(task: DefaultSyncTask): SyncTask
|
abstract fun bindSyncTask(task: DefaultSyncTask): SyncTask
|
||||||
|
|
||||||
|
|
|
@ -13,42 +13,37 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* 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 androidx.lifecycle.MutableLiveData
|
||||||
import org.matrix.android.sdk.api.session.initsync.InitSyncStep
|
import org.matrix.android.sdk.api.session.sync.InitialSyncStep
|
||||||
import org.matrix.android.sdk.api.session.initsync.SyncStatusService
|
import org.matrix.android.sdk.api.session.sync.SyncRequestState
|
||||||
import org.matrix.android.sdk.internal.session.SessionScope
|
import org.matrix.android.sdk.internal.session.SessionScope
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@SessionScope
|
@SessionScope
|
||||||
internal class DefaultSyncStatusService @Inject constructor() :
|
internal class SyncRequestStateTracker @Inject constructor() :
|
||||||
SyncStatusService,
|
|
||||||
ProgressReporter {
|
ProgressReporter {
|
||||||
|
|
||||||
private val status = MutableLiveData<SyncStatusService.Status>()
|
val syncRequestState = MutableLiveData<SyncRequestState>()
|
||||||
|
|
||||||
private var rootTask: TaskInfo? = null
|
private var rootTask: TaskInfo? = null
|
||||||
|
|
||||||
override fun getSyncStatusLive(): LiveData<SyncStatusService.Status> {
|
|
||||||
return status
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only to be used for incremental sync
|
// Only to be used for incremental sync
|
||||||
fun setStatus(newStatus: SyncStatusService.Status.IncrementalSyncStatus) {
|
fun setSyncRequestState(newSyncRequestState: SyncRequestState.IncrementalSyncRequestState) {
|
||||||
status.postValue(newStatus)
|
syncRequestState.postValue(newSyncRequestState)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a rootTask.
|
* Create a rootTask.
|
||||||
*/
|
*/
|
||||||
fun startRoot(
|
fun startRoot(
|
||||||
initSyncStep: InitSyncStep,
|
initialSyncStep: InitialSyncStep,
|
||||||
totalProgress: Int
|
totalProgress: Int
|
||||||
) {
|
) {
|
||||||
endAll()
|
endAll()
|
||||||
rootTask = TaskInfo(initSyncStep, totalProgress, null, 1F)
|
rootTask = TaskInfo(initialSyncStep, totalProgress, null, 1F)
|
||||||
reportProgress(0F)
|
reportProgress(0F)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,13 +51,13 @@ internal class DefaultSyncStatusService @Inject constructor() :
|
||||||
* Add a child to the leaf.
|
* Add a child to the leaf.
|
||||||
*/
|
*/
|
||||||
override fun startTask(
|
override fun startTask(
|
||||||
initSyncStep: InitSyncStep,
|
initialSyncStep: InitialSyncStep,
|
||||||
totalProgress: Int,
|
totalProgress: Int,
|
||||||
parentWeight: Float
|
parentWeight: Float
|
||||||
) {
|
) {
|
||||||
val currentLeaf = rootTask?.leaf() ?: return
|
val currentLeaf = rootTask?.leaf() ?: return
|
||||||
currentLeaf.child = TaskInfo(
|
currentLeaf.child = TaskInfo(
|
||||||
initSyncStep = initSyncStep,
|
initialSyncStep = initialSyncStep,
|
||||||
totalProgress = totalProgress,
|
totalProgress = totalProgress,
|
||||||
parent = currentLeaf,
|
parent = currentLeaf,
|
||||||
parentWeight = parentWeight
|
parentWeight = parentWeight
|
||||||
|
@ -76,7 +71,7 @@ internal class DefaultSyncStatusService @Inject constructor() :
|
||||||
// Update the progress of the leaf and all its parents
|
// Update the progress of the leaf and all its parents
|
||||||
leaf.setProgress(progress)
|
leaf.setProgress(progress)
|
||||||
// Then update the live data using leaf wording and root 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
|
// And close it
|
||||||
endedTask.parent.child = null
|
endedTask.parent.child = null
|
||||||
} else {
|
} else {
|
||||||
status.postValue(SyncStatusService.Status.Idle)
|
syncRequestState.postValue(SyncRequestState.Idle)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun endAll() {
|
fun endAll() {
|
||||||
rootTask = null
|
rootTask = null
|
||||||
status.postValue(SyncStatusService.Status.Idle)
|
syncRequestState.postValue(SyncRequestState.Idle)
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -18,9 +18,9 @@ package org.matrix.android.sdk.internal.session.sync
|
||||||
|
|
||||||
import androidx.work.ExistingPeriodicWorkPolicy
|
import androidx.work.ExistingPeriodicWorkPolicy
|
||||||
import com.zhuinden.monarchy.Monarchy
|
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.PushRuleService
|
||||||
import org.matrix.android.sdk.api.session.pushrules.RuleScope
|
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.GroupsSyncResponse
|
||||||
import org.matrix.android.sdk.api.session.sync.model.RoomsSyncResponse
|
import org.matrix.android.sdk.api.session.sync.model.RoomsSyncResponse
|
||||||
import org.matrix.android.sdk.api.session.sync.model.SyncResponse
|
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.SessionListeners
|
||||||
import org.matrix.android.sdk.internal.session.dispatchTo
|
import org.matrix.android.sdk.internal.session.dispatchTo
|
||||||
import org.matrix.android.sdk.internal.session.group.GetGroupDataWorker
|
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.pushrules.ProcessEventForPushTask
|
||||||
import org.matrix.android.sdk.internal.session.sync.handler.CryptoSyncHandler
|
import org.matrix.android.sdk.internal.session.sync.handler.CryptoSyncHandler
|
||||||
import org.matrix.android.sdk.internal.session.sync.handler.GroupSyncHandler
|
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
|
// to ensure to decrypt them properly
|
||||||
measureTimeMillis {
|
measureTimeMillis {
|
||||||
Timber.v("Handle toDevice")
|
Timber.v("Handle toDevice")
|
||||||
reportSubtask(reporter, InitSyncStep.ImportingAccountCrypto, 100, 0.1f) {
|
reportSubtask(reporter, InitialSyncStep.ImportingAccountCrypto, 100, 0.1f) {
|
||||||
if (syncResponse.toDevice != null) {
|
if (syncResponse.toDevice != null) {
|
||||||
cryptoSyncHandler.handleToDevice(syncResponse.toDevice, reporter)
|
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)
|
// IMPORTANT nothing should be suspend here as we are accessing the realm instance (thread local)
|
||||||
measureTimeMillis {
|
measureTimeMillis {
|
||||||
Timber.v("Handle rooms")
|
Timber.v("Handle rooms")
|
||||||
reportSubtask(reporter, InitSyncStep.ImportingAccountRoom, 1, 0.7f) {
|
reportSubtask(reporter, InitialSyncStep.ImportingAccountRoom, 1, 0.7f) {
|
||||||
if (syncResponse.rooms != null) {
|
if (syncResponse.rooms != null) {
|
||||||
roomSyncHandler.handle(realm, syncResponse.rooms, isInitialSync, aggregator, reporter)
|
roomSyncHandler.handle(realm, syncResponse.rooms, isInitialSync, aggregator, reporter)
|
||||||
}
|
}
|
||||||
|
@ -121,7 +119,7 @@ internal class SyncResponseHandler @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
measureTimeMillis {
|
measureTimeMillis {
|
||||||
reportSubtask(reporter, InitSyncStep.ImportingAccountGroups, 1, 0.1f) {
|
reportSubtask(reporter, InitialSyncStep.ImportingAccountGroups, 1, 0.1f) {
|
||||||
Timber.v("Handle groups")
|
Timber.v("Handle groups")
|
||||||
if (syncResponse.groups != null) {
|
if (syncResponse.groups != null) {
|
||||||
groupSyncHandler.handle(realm, syncResponse.groups, reporter)
|
groupSyncHandler.handle(realm, syncResponse.groups, reporter)
|
||||||
|
@ -132,7 +130,7 @@ internal class SyncResponseHandler @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
measureTimeMillis {
|
measureTimeMillis {
|
||||||
reportSubtask(reporter, InitSyncStep.ImportingAccountData, 1, 0.1f) {
|
reportSubtask(reporter, InitialSyncStep.ImportingAccountData, 1, 0.1f) {
|
||||||
Timber.v("Handle accountData")
|
Timber.v("Handle accountData")
|
||||||
userAccountDataSyncHandler.handle(realm, syncResponse.accountData)
|
userAccountDataSyncHandler.handle(realm, syncResponse.accountData)
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,10 +21,10 @@ import okhttp3.ResponseBody
|
||||||
import org.matrix.android.sdk.api.extensions.tryOrNull
|
import org.matrix.android.sdk.api.extensions.tryOrNull
|
||||||
import org.matrix.android.sdk.api.logger.LoggerTag
|
import org.matrix.android.sdk.api.logger.LoggerTag
|
||||||
import org.matrix.android.sdk.api.session.Session
|
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.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.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.initialSyncStrategy
|
||||||
import org.matrix.android.sdk.api.session.sync.model.LazyRoomSyncEphemeral
|
import org.matrix.android.sdk.api.session.sync.model.LazyRoomSyncEphemeral
|
||||||
import org.matrix.android.sdk.api.session.sync.model.SyncResponse
|
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.dispatchTo
|
||||||
import org.matrix.android.sdk.internal.session.filter.FilterRepository
|
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.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.sync.parsing.InitialSyncResponseParser
|
||||||
import org.matrix.android.sdk.internal.session.user.UserStore
|
import org.matrix.android.sdk.internal.session.user.UserStore
|
||||||
import org.matrix.android.sdk.internal.task.Task
|
import org.matrix.android.sdk.internal.task.Task
|
||||||
|
@ -68,7 +66,7 @@ internal class DefaultSyncTask @Inject constructor(
|
||||||
@UserId private val userId: String,
|
@UserId private val userId: String,
|
||||||
private val filterRepository: FilterRepository,
|
private val filterRepository: FilterRepository,
|
||||||
private val syncResponseHandler: SyncResponseHandler,
|
private val syncResponseHandler: SyncResponseHandler,
|
||||||
private val defaultSyncStatusService: DefaultSyncStatusService,
|
private val syncRequestStateTracker: SyncRequestStateTracker,
|
||||||
private val syncTokenStore: SyncTokenStore,
|
private val syncTokenStore: SyncTokenStore,
|
||||||
private val getHomeServerCapabilitiesTask: GetHomeServerCapabilitiesTask,
|
private val getHomeServerCapabilitiesTask: GetHomeServerCapabilitiesTask,
|
||||||
private val userStore: UserStore,
|
private val userStore: UserStore,
|
||||||
|
@ -115,7 +113,7 @@ internal class DefaultSyncTask @Inject constructor(
|
||||||
displayName = user?.displayName,
|
displayName = user?.displayName,
|
||||||
avatarUrl = user?.avatarUrl
|
avatarUrl = user?.avatarUrl
|
||||||
)
|
)
|
||||||
defaultSyncStatusService.startRoot(InitSyncStep.ImportingAccount, 100)
|
syncRequestStateTracker.startRoot(InitialSyncStep.ImportingAccount, 100)
|
||||||
}
|
}
|
||||||
// Maybe refresh the homeserver capabilities data we know
|
// Maybe refresh the homeserver capabilities data we know
|
||||||
getHomeServerCapabilitiesTask.execute(GetHomeServerCapabilitiesTask.Params(forceRefresh = false))
|
getHomeServerCapabilitiesTask.execute(GetHomeServerCapabilitiesTask.Params(forceRefresh = false))
|
||||||
|
@ -132,7 +130,7 @@ internal class DefaultSyncTask @Inject constructor(
|
||||||
roomSyncEphemeralTemporaryStore.reset()
|
roomSyncEphemeralTemporaryStore.reset()
|
||||||
workingDir.mkdirs()
|
workingDir.mkdirs()
|
||||||
val file = downloadInitSyncResponse(requestParams, syncStatisticsData)
|
val file = downloadInitSyncResponse(requestParams, syncStatisticsData)
|
||||||
syncResponseToReturn = reportSubtask(defaultSyncStatusService, InitSyncStep.ImportingAccount, 1, 0.7F) {
|
syncResponseToReturn = reportSubtask(syncRequestStateTracker, InitialSyncStep.ImportingAccount, 1, 0.7F) {
|
||||||
handleSyncFile(file, initSyncStrategy)
|
handleSyncFile(file, initSyncStrategy)
|
||||||
}
|
}
|
||||||
// Delete all files
|
// Delete all files
|
||||||
|
@ -150,15 +148,15 @@ internal class DefaultSyncTask @Inject constructor(
|
||||||
syncStatisticsData.requestInitSyncTime = SystemClock.elapsedRealtime()
|
syncStatisticsData.requestInitSyncTime = SystemClock.elapsedRealtime()
|
||||||
syncStatisticsData.downloadInitSyncTime = syncStatisticsData.requestInitSyncTime
|
syncStatisticsData.downloadInitSyncTime = syncStatisticsData.requestInitSyncTime
|
||||||
logDuration("INIT_SYNC Database insertion", loggerTag, clock) {
|
logDuration("INIT_SYNC Database insertion", loggerTag, clock) {
|
||||||
syncResponseHandler.handleResponse(syncResponse, token, defaultSyncStatusService)
|
syncResponseHandler.handleResponse(syncResponse, token, syncRequestStateTracker)
|
||||||
}
|
}
|
||||||
syncResponseToReturn = syncResponse
|
syncResponseToReturn = syncResponse
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
defaultSyncStatusService.endAll()
|
syncRequestStateTracker.endAll()
|
||||||
} else {
|
} else {
|
||||||
Timber.tag(loggerTag.value).d("Start incremental sync request with since token $token")
|
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 {
|
val syncResponse = try {
|
||||||
executeRequest(globalErrorReceiver) {
|
executeRequest(globalErrorReceiver) {
|
||||||
syncAPI.sync(
|
syncAPI.sync(
|
||||||
|
@ -168,7 +166,7 @@ internal class DefaultSyncTask @Inject constructor(
|
||||||
}
|
}
|
||||||
} catch (throwable: Throwable) {
|
} catch (throwable: Throwable) {
|
||||||
Timber.tag(loggerTag.value).e(throwable, "Incremental sync request error")
|
Timber.tag(loggerTag.value).e(throwable, "Incremental sync request error")
|
||||||
defaultSyncStatusService.setStatus(SyncStatusService.Status.IncrementalSyncError)
|
syncRequestStateTracker.setSyncRequestState(SyncRequestState.IncrementalSyncError)
|
||||||
throw throwable
|
throw throwable
|
||||||
}
|
}
|
||||||
val nbRooms = syncResponse.rooms?.invite.orEmpty().size + syncResponse.rooms?.join.orEmpty().size + syncResponse.rooms?.leave.orEmpty().size
|
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(
|
Timber.tag(loggerTag.value).d(
|
||||||
"Incremental sync request parsing, $nbRooms room(s) $nbToDevice toDevice(s). Got nextBatch: $nextBatch"
|
"Incremental sync request parsing, $nbRooms room(s) $nbToDevice toDevice(s). Got nextBatch: $nextBatch"
|
||||||
)
|
)
|
||||||
defaultSyncStatusService.setStatus(
|
syncRequestStateTracker.setSyncRequestState(
|
||||||
SyncStatusService.Status.IncrementalSyncParsing(
|
SyncRequestState.IncrementalSyncParsing(
|
||||||
rooms = nbRooms,
|
rooms = nbRooms,
|
||||||
toDevice = nbToDevice
|
toDevice = nbToDevice
|
||||||
)
|
)
|
||||||
|
@ -186,7 +184,7 @@ internal class DefaultSyncTask @Inject constructor(
|
||||||
syncResponseHandler.handleResponse(syncResponse, token, null)
|
syncResponseHandler.handleResponse(syncResponse, token, null)
|
||||||
syncResponseToReturn = syncResponse
|
syncResponseToReturn = syncResponse
|
||||||
Timber.tag(loggerTag.value).d("Incremental sync done")
|
Timber.tag(loggerTag.value).d("Incremental sync done")
|
||||||
defaultSyncStatusService.setStatus(SyncStatusService.Status.IncrementalSyncDone)
|
syncRequestStateTracker.setSyncRequestState(SyncRequestState.IncrementalSyncDone)
|
||||||
}
|
}
|
||||||
syncStatisticsData.treatmentSyncTime = SystemClock.elapsedRealtime()
|
syncStatisticsData.treatmentSyncTime = SystemClock.elapsedRealtime()
|
||||||
syncStatisticsData.nbOfRooms = syncResponseToReturn?.rooms?.join?.size ?: 0
|
syncStatisticsData.nbOfRooms = syncResponseToReturn?.rooms?.join?.size ?: 0
|
||||||
|
@ -201,20 +199,20 @@ internal class DefaultSyncTask @Inject constructor(
|
||||||
val status = initialSyncStatusRepository.getStep()
|
val status = initialSyncStatusRepository.getStep()
|
||||||
if (workingFile.exists() && status >= InitialSyncStatus.STEP_DOWNLOADED) {
|
if (workingFile.exists() && status >= InitialSyncStatus.STEP_DOWNLOADED) {
|
||||||
Timber.tag(loggerTag.value).d("INIT_SYNC file is already here")
|
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
|
// Empty task
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
initialSyncStatusRepository.setStep(InitialSyncStatus.STEP_DOWNLOADING)
|
initialSyncStatusRepository.setStep(InitialSyncStatus.STEP_DOWNLOADING)
|
||||||
val syncResponse = logDuration("INIT_SYNC Perform server request", loggerTag, clock) {
|
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)
|
getSyncResponse(requestParams, MAX_NUMBER_OF_RETRY_AFTER_TIMEOUT)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
syncStatisticsData.requestInitSyncTime = SystemClock.elapsedRealtime()
|
syncStatisticsData.requestInitSyncTime = SystemClock.elapsedRealtime()
|
||||||
if (syncResponse.isSuccessful) {
|
if (syncResponse.isSuccessful) {
|
||||||
logDuration("INIT_SYNC Download and save to file", loggerTag, clock) {
|
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 ->
|
syncResponse.body()?.byteStream()?.use { inputStream ->
|
||||||
workingFile.outputStream().use { outputStream ->
|
workingFile.outputStream().use { outputStream ->
|
||||||
inputStream.copyTo(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")
|
Timber.tag(loggerTag.value).d("INIT_SYNC $nbOfJoinedRooms rooms, $nbOfJoinedRoomsInFile ephemeral stored into files")
|
||||||
|
|
||||||
logDuration("INIT_SYNC Database insertion", loggerTag, clock) {
|
logDuration("INIT_SYNC Database insertion", loggerTag, clock) {
|
||||||
syncResponseHandler.handleResponse(syncResponse, null, defaultSyncStatusService)
|
syncResponseHandler.handleResponse(syncResponse, null, syncRequestStateTracker)
|
||||||
}
|
}
|
||||||
initialSyncStatusRepository.setStep(InitialSyncStatus.STEP_SUCCESS)
|
initialSyncStatusRepository.setStep(InitialSyncStatus.STEP_SUCCESS)
|
||||||
syncResponse
|
syncResponse
|
||||||
|
|
|
@ -14,13 +14,13 @@
|
||||||
* limitations under the License.
|
* 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
|
import timber.log.Timber
|
||||||
|
|
||||||
internal class TaskInfo(
|
internal class TaskInfo(
|
||||||
val initSyncStep: InitSyncStep,
|
val initialSyncStep: InitialSyncStep,
|
||||||
val totalProgress: Int,
|
val totalProgress: Int,
|
||||||
val parent: TaskInfo?,
|
val parent: TaskInfo?,
|
||||||
val parentWeight: Float
|
val parentWeight: Float
|
|
@ -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.api.session.sync.model.ToDeviceSyncResponse
|
||||||
import org.matrix.android.sdk.internal.crypto.DefaultCryptoService
|
import org.matrix.android.sdk.internal.crypto.DefaultCryptoService
|
||||||
import org.matrix.android.sdk.internal.crypto.verification.DefaultVerificationService
|
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 timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
|
|
@ -17,16 +17,16 @@
|
||||||
package org.matrix.android.sdk.internal.session.sync.handler
|
package org.matrix.android.sdk.internal.session.sync.handler
|
||||||
|
|
||||||
import io.realm.Realm
|
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.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.GroupsSyncResponse
|
||||||
import org.matrix.android.sdk.api.session.sync.model.InvitedGroupSync
|
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.GroupEntity
|
||||||
import org.matrix.android.sdk.internal.database.model.GroupSummaryEntity
|
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.getOrCreate
|
||||||
import org.matrix.android.sdk.internal.database.query.where
|
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.sync.ProgressReporter
|
||||||
import org.matrix.android.sdk.internal.session.initsync.mapWithProgress
|
import org.matrix.android.sdk.internal.session.sync.mapWithProgress
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
internal class GroupSyncHandler @Inject constructor() {
|
internal class GroupSyncHandler @Inject constructor() {
|
||||||
|
@ -51,18 +51,18 @@ internal class GroupSyncHandler @Inject constructor() {
|
||||||
|
|
||||||
private fun handleGroupSync(realm: Realm, handlingStrategy: HandlingStrategy, reporter: ProgressReporter?) {
|
private fun handleGroupSync(realm: Realm, handlingStrategy: HandlingStrategy, reporter: ProgressReporter?) {
|
||||||
val groups = when (handlingStrategy) {
|
val groups = when (handlingStrategy) {
|
||||||
is HandlingStrategy.JOINED ->
|
is HandlingStrategy.JOINED ->
|
||||||
handlingStrategy.data.mapWithProgress(reporter, InitSyncStep.ImportingAccountGroups, 0.6f) {
|
handlingStrategy.data.mapWithProgress(reporter, InitialSyncStep.ImportingAccountGroups, 0.6f) {
|
||||||
handleJoinedGroup(realm, it.key)
|
handleJoinedGroup(realm, it.key)
|
||||||
}
|
}
|
||||||
|
|
||||||
is HandlingStrategy.INVITED ->
|
is HandlingStrategy.INVITED ->
|
||||||
handlingStrategy.data.mapWithProgress(reporter, InitSyncStep.ImportingAccountGroups, 0.3f) {
|
handlingStrategy.data.mapWithProgress(reporter, InitialSyncStep.ImportingAccountGroups, 0.3f) {
|
||||||
handleInvitedGroup(realm, it.key)
|
handleInvitedGroup(realm, it.key)
|
||||||
}
|
}
|
||||||
|
|
||||||
is HandlingStrategy.LEFT ->
|
is HandlingStrategy.LEFT ->
|
||||||
handlingStrategy.data.mapWithProgress(reporter, InitSyncStep.ImportingAccountGroups, 0.1f) {
|
handlingStrategy.data.mapWithProgress(reporter, InitialSyncStep.ImportingAccountGroups, 0.1f) {
|
||||||
handleLeftGroup(realm, it.key)
|
handleLeftGroup(realm, it.key)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.EventType
|
||||||
import org.matrix.android.sdk.api.session.events.model.toModel
|
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.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.Membership
|
||||||
import org.matrix.android.sdk.api.session.room.model.RoomMemberContent
|
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.send.SendState
|
||||||
import org.matrix.android.sdk.api.session.room.threads.model.ThreadSummaryUpdateType
|
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.initialSyncStrategy
|
import org.matrix.android.sdk.api.session.sync.initialSyncStrategy
|
||||||
import org.matrix.android.sdk.api.session.sync.model.InvitedRoomSync
|
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.extensions.clearWith
|
||||||
import org.matrix.android.sdk.internal.session.StreamEventsManager
|
import org.matrix.android.sdk.internal.session.StreamEventsManager
|
||||||
import org.matrix.android.sdk.internal.session.events.getFixedRoomMemberContent
|
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.RoomChangeMembershipStateDataSource
|
||||||
import org.matrix.android.sdk.internal.session.room.membership.RoomMemberEventHandler
|
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.summary.RoomSummaryUpdater
|
||||||
import org.matrix.android.sdk.internal.session.room.timeline.PaginationDirection
|
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.timeline.TimelineInput
|
||||||
import org.matrix.android.sdk.internal.session.room.typing.TypingEventContent
|
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.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.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.computeBestChunkSize
|
||||||
import org.matrix.android.sdk.internal.util.time.Clock
|
import org.matrix.android.sdk.internal.util.time.Clock
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
@ -140,24 +140,24 @@ internal class RoomSyncHandler @Inject constructor(
|
||||||
}
|
}
|
||||||
val syncLocalTimeStampMillis = clock.epochMillis()
|
val syncLocalTimeStampMillis = clock.epochMillis()
|
||||||
val rooms = when (handlingStrategy) {
|
val rooms = when (handlingStrategy) {
|
||||||
is HandlingStrategy.JOINED -> {
|
is HandlingStrategy.JOINED -> {
|
||||||
if (isInitialSync && initialSyncStrategy is InitialSyncStrategy.Optimized) {
|
if (isInitialSync && initialSyncStrategy is InitialSyncStrategy.Optimized) {
|
||||||
insertJoinRoomsFromInitSync(realm, handlingStrategy, syncLocalTimeStampMillis, aggregator, reporter)
|
insertJoinRoomsFromInitSync(realm, handlingStrategy, syncLocalTimeStampMillis, aggregator, reporter)
|
||||||
// Rooms are already inserted, return an empty list
|
// Rooms are already inserted, return an empty list
|
||||||
emptyList()
|
emptyList()
|
||||||
} else {
|
} 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)
|
handleJoinedRoom(realm, it.key, it.value, insertType, syncLocalTimeStampMillis, aggregator)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is HandlingStrategy.INVITED ->
|
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)
|
handleInvitedRoom(realm, it.key, it.value, insertType, syncLocalTimeStampMillis)
|
||||||
}
|
}
|
||||||
|
|
||||||
is HandlingStrategy.LEFT -> {
|
is HandlingStrategy.LEFT -> {
|
||||||
handlingStrategy.data.mapWithProgress(reporter, InitSyncStep.ImportingAccountLeftRooms, 0.3f) {
|
handlingStrategy.data.mapWithProgress(reporter, InitialSyncStep.ImportingAccountLeftRooms, 0.3f) {
|
||||||
handleLeftRoom(realm, it.key, it.value, insertType, syncLocalTimeStampMillis)
|
handleLeftRoom(realm, it.key, it.value, insertType, syncLocalTimeStampMillis)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -178,7 +178,7 @@ internal class RoomSyncHandler @Inject constructor(
|
||||||
)
|
)
|
||||||
|
|
||||||
if (bestChunkSize.shouldChunk()) {
|
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")
|
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
|
// I cannot find a better way to chunk a map, so chunk the keys and then create new maps
|
||||||
handlingStrategy.data.keys
|
handlingStrategy.data.keys
|
||||||
|
@ -202,7 +202,7 @@ internal class RoomSyncHandler @Inject constructor(
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// No need to split
|
// 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)
|
handleJoinedRoom(realm, it.key, it.value, EventInsertType.INITIAL_SYNC, syncLocalTimeStampMillis, aggregator)
|
||||||
}
|
}
|
||||||
realm.insertOrUpdate(rooms)
|
realm.insertOrUpdate(rooms)
|
||||||
|
@ -578,12 +578,12 @@ internal class RoomSyncHandler @Inject constructor(
|
||||||
readReceiptHandler.handle(realm, roomId, readReceiptContent, isInitialSync, aggregator)
|
readReceiptHandler.handle(realm, roomId, readReceiptContent, isInitialSync, aggregator)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EventType.TYPING -> {
|
EventType.TYPING -> {
|
||||||
event.content.toModel<TypingEventContent>()?.let { typingEventContent ->
|
event.content.toModel<TypingEventContent>()?.let { typingEventContent ->
|
||||||
result = result.copy(typingUserIds = typingEventContent.typingUserIds)
|
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")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -142,7 +142,7 @@ fun initialSyncIdlingResource(session: Session): IdlingResource {
|
||||||
override fun getName() = "InitialSyncIdlingResource for ${session.myUserId}"
|
override fun getName() = "InitialSyncIdlingResource for ${session.myUserId}"
|
||||||
|
|
||||||
override fun isIdleNow(): Boolean {
|
override fun isIdleNow(): Boolean {
|
||||||
val isIdle = session.hasAlreadySynced()
|
val isIdle = session.syncService().hasAlreadySynced()
|
||||||
return isIdle
|
return isIdle
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,16 +151,16 @@ fun initialSyncIdlingResource(session: Session): IdlingResource {
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onChanged(t: SyncState?) {
|
override fun onChanged(t: SyncState?) {
|
||||||
val isIdle = session.hasAlreadySynced()
|
val isIdle = session.syncService().hasAlreadySynced()
|
||||||
if (isIdle) {
|
if (isIdle) {
|
||||||
callback?.onTransitionToIdle()
|
callback?.onTransitionToIdle()
|
||||||
session.getSyncStateLive().removeObserver(this)
|
session.syncService().getSyncStateLive().removeObserver(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
runOnUiThread {
|
runOnUiThread {
|
||||||
session.getSyncStateLive().observeForever(res)
|
session.syncService().getSyncStateLive().observeForever(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
return res
|
return res
|
||||||
|
|
|
@ -116,14 +116,14 @@ abstract class VerificationTestBase {
|
||||||
|
|
||||||
GlobalScope.launch(Dispatchers.Main) { session.open() }
|
GlobalScope.launch(Dispatchers.Main) { session.open() }
|
||||||
|
|
||||||
session.startSync(true)
|
session.syncService().startSync(true)
|
||||||
|
|
||||||
val syncLiveData = runBlocking(Dispatchers.Main) {
|
val syncLiveData = runBlocking(Dispatchers.Main) {
|
||||||
session.getSyncStateLive()
|
session.syncService().getSyncStateLive()
|
||||||
}
|
}
|
||||||
val syncObserver = object : Observer<SyncState> {
|
val syncObserver = object : Observer<SyncState> {
|
||||||
override fun onChanged(t: SyncState?) {
|
override fun onChanged(t: SyncState?) {
|
||||||
if (session.hasAlreadySynced()) {
|
if (session.syncService().hasAlreadySynced()) {
|
||||||
lock.countDown()
|
lock.countDown()
|
||||||
syncLiveData.removeObserver(this)
|
syncLiveData.removeObserver(this)
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,7 @@ object BackgroundSyncStarter {
|
||||||
BackgroundSyncMode.FDROID_BACKGROUND_SYNC_MODE_FOR_BATTERY -> {
|
BackgroundSyncMode.FDROID_BACKGROUND_SYNC_MODE_FOR_BATTERY -> {
|
||||||
// we rely on periodic worker
|
// we rely on periodic worker
|
||||||
Timber.i("## Sync: Work scheduled to periodically sync in ${vectorPreferences.backgroundSyncDelay()}s")
|
Timber.i("## Sync: Work scheduled to periodically sync in ${vectorPreferences.backgroundSyncDelay()}s")
|
||||||
activeSession.startAutomaticBackgroundSync(
|
activeSession.syncService().startAutomaticBackgroundSync(
|
||||||
vectorPreferences.backgroundSyncTimeOut().toLong(),
|
vectorPreferences.backgroundSyncTimeOut().toLong(),
|
||||||
vectorPreferences.backgroundSyncDelay().toLong()
|
vectorPreferences.backgroundSyncDelay().toLong()
|
||||||
)
|
)
|
||||||
|
|
|
@ -26,9 +26,9 @@ import androidx.core.content.ContextCompat
|
||||||
import androidx.core.content.getSystemService
|
import androidx.core.content.getSystemService
|
||||||
import im.vector.app.core.extensions.singletonEntryPoint
|
import im.vector.app.core.extensions.singletonEntryPoint
|
||||||
import im.vector.app.core.platform.PendingIntentCompat
|
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 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
|
import timber.log.Timber
|
||||||
|
|
||||||
class AlarmSyncBroadcastReceiver : BroadcastReceiver() {
|
class AlarmSyncBroadcastReceiver : BroadcastReceiver() {
|
||||||
|
@ -43,8 +43,8 @@ class AlarmSyncBroadcastReceiver : BroadcastReceiver() {
|
||||||
val vectorPreferences = singletonEntryPoint.vectorPreferences()
|
val vectorPreferences = singletonEntryPoint.vectorPreferences()
|
||||||
val clock = singletonEntryPoint.clock()
|
val clock = singletonEntryPoint.clock()
|
||||||
|
|
||||||
val sessionId = intent.getStringExtra(SyncService.EXTRA_SESSION_ID) ?: return
|
val sessionId = intent.getStringExtra(SyncAndroidService.EXTRA_SESSION_ID) ?: return
|
||||||
VectorSyncService.newPeriodicIntent(
|
VectorSyncAndroidService.newPeriodicIntent(
|
||||||
context = context,
|
context = context,
|
||||||
sessionId = sessionId,
|
sessionId = sessionId,
|
||||||
syncTimeoutSeconds = vectorPreferences.backgroundSyncTimeOut(),
|
syncTimeoutSeconds = vectorPreferences.backgroundSyncTimeOut(),
|
||||||
|
@ -69,8 +69,8 @@ class AlarmSyncBroadcastReceiver : BroadcastReceiver() {
|
||||||
// Reschedule
|
// Reschedule
|
||||||
Timber.v("## Sync: Scheduling alarm for background sync in $delayInSeconds seconds")
|
Timber.v("## Sync: Scheduling alarm for background sync in $delayInSeconds seconds")
|
||||||
val intent = Intent(context, AlarmSyncBroadcastReceiver::class.java).apply {
|
val intent = Intent(context, AlarmSyncBroadcastReceiver::class.java).apply {
|
||||||
putExtra(SyncService.EXTRA_SESSION_ID, sessionId)
|
putExtra(SyncAndroidService.EXTRA_SESSION_ID, sessionId)
|
||||||
putExtra(SyncService.EXTRA_PERIODIC, true)
|
putExtra(SyncAndroidService.EXTRA_PERIODIC, true)
|
||||||
}
|
}
|
||||||
val pIntent = PendingIntent.getBroadcast(
|
val pIntent = PendingIntent.getBroadcast(
|
||||||
context,
|
context,
|
||||||
|
@ -100,7 +100,7 @@ class AlarmSyncBroadcastReceiver : BroadcastReceiver() {
|
||||||
alarmMgr.cancel(pIntent)
|
alarmMgr.cancel(pIntent)
|
||||||
|
|
||||||
// Stop current service to restart
|
// Stop current service to restart
|
||||||
VectorSyncService.stopIntent(context).let {
|
VectorSyncAndroidService.stopIntent(context).let {
|
||||||
try {
|
try {
|
||||||
ContextCompat.startForegroundService(context, it)
|
ContextCompat.startForegroundService(context, it)
|
||||||
} catch (ex: Throwable) {
|
} catch (ex: Throwable) {
|
||||||
|
|
|
@ -63,7 +63,7 @@ object FcmHelper {
|
||||||
|
|
||||||
fun onEnterForeground(context: Context, activeSessionHolder: ActiveSessionHolder) {
|
fun onEnterForeground(context: Context, activeSessionHolder: ActiveSessionHolder) {
|
||||||
// try to stop all regardless of background mode
|
// try to stop all regardless of background mode
|
||||||
activeSessionHolder.getSafeActiveSession()?.stopAnyBackgroundSync()
|
activeSessionHolder.getSafeActiveSession()?.syncService()?.stopAnyBackgroundSync()
|
||||||
AlarmSyncBroadcastReceiver.cancelAlarm(context)
|
AlarmSyncBroadcastReceiver.cancelAlarm(context)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -164,7 +164,7 @@ class VectorFirebaseMessagingService : FirebaseMessagingService() {
|
||||||
getEventFastLane(session, roomId, eventId)
|
getEventFastLane(session, roomId, eventId)
|
||||||
|
|
||||||
Timber.tag(loggerTag.value).d("Requesting background sync")
|
Timber.tag(loggerTag.value).d("Requesting background sync")
|
||||||
session.requireBackgroundSync()
|
session.syncService().requireBackgroundSync()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
|
|
|
@ -358,7 +358,7 @@
|
||||||
|
|
||||||
<!-- Add tools:ignore="Instantiatable" for the error reported only by Buildkite and for lintGplayRelease check :/ -->
|
<!-- Add tools:ignore="Instantiatable" for the error reported only by Buildkite and for lintGplayRelease check :/ -->
|
||||||
<service
|
<service
|
||||||
android:name=".core.services.VectorSyncService"
|
android:name=".core.services.VectorSyncAndroidService"
|
||||||
android:exported="false"
|
android:exported="false"
|
||||||
tools:ignore="Instantiatable" />
|
tools:ignore="Instantiatable" />
|
||||||
|
|
||||||
|
|
|
@ -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.getRoom
|
||||||
import org.matrix.android.sdk.api.session.getRoomSummary
|
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.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.room.model.RoomSummary
|
||||||
|
import org.matrix.android.sdk.api.session.sync.SyncRequestState
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|
||||||
|
@ -147,9 +147,9 @@ class AppStateHandler @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun observeSyncStatus(session: Session) {
|
private fun observeSyncStatus(session: Session) {
|
||||||
session.syncStatusService().getSyncStatusLive()
|
session.syncService().getSyncRequestStateLive()
|
||||||
.asFlow()
|
.asFlow()
|
||||||
.filterIsInstance<SyncStatusService.Status.IncrementalSyncDone>()
|
.filterIsInstance<SyncRequestState.IncrementalSyncDone>()
|
||||||
.map { session.spaceService().getRootSpaceSummaries().size }
|
.map { session.spaceService().getRootSpaceSummaries().size }
|
||||||
.distinctUntilChanged()
|
.distinctUntilChanged()
|
||||||
.onEach { spacesNumber ->
|
.onEach { spacesNumber ->
|
||||||
|
|
|
@ -36,7 +36,7 @@ import kotlinx.coroutines.launch
|
||||||
import org.matrix.android.sdk.api.session.Session
|
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.Event
|
||||||
import org.matrix.android.sdk.api.session.events.model.toContent
|
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 timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
@ -260,11 +260,11 @@ class AutoRageShaker @Inject constructor(
|
||||||
}
|
}
|
||||||
this.currentActiveSessionId = sessionId
|
this.currentActiveSessionId = sessionId
|
||||||
|
|
||||||
hasSynced = session.hasAlreadySynced()
|
hasSynced = session.syncService().hasAlreadySynced()
|
||||||
session.syncStatusService().getSyncStatusLive()
|
session.syncService().getSyncRequestStateLive()
|
||||||
.asFlow()
|
.asFlow()
|
||||||
.onEach {
|
.onEach {
|
||||||
hasSynced = it !is SyncStatusService.Status.InitialSyncProgressing
|
hasSynced = it !is SyncRequestState.InitialSyncProgressing
|
||||||
}
|
}
|
||||||
.launchIn(session.coroutineScope)
|
.launchIn(session.coroutineScope)
|
||||||
activeSessionIds.add(sessionId)
|
activeSessionIds.add(sessionId)
|
||||||
|
|
|
@ -176,7 +176,7 @@ class VectorApplication :
|
||||||
Timber.i("App entered foreground")
|
Timber.i("App entered foreground")
|
||||||
FcmHelper.onEnterForeground(appContext, activeSessionHolder)
|
FcmHelper.onEnterForeground(appContext, activeSessionHolder)
|
||||||
activeSessionHolder.getSafeActiveSession()?.also {
|
activeSessionHolder.getSafeActiveSession()?.also {
|
||||||
it.stopAnyBackgroundSync()
|
it.syncService().stopAnyBackgroundSync()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ import android.content.Context
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.lifecycle.Lifecycle
|
import androidx.lifecycle.Lifecycle
|
||||||
import androidx.lifecycle.ProcessLifecycleOwner
|
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 im.vector.app.features.session.VectorSessionStore
|
||||||
import org.matrix.android.sdk.api.session.Session
|
import org.matrix.android.sdk.api.session.Session
|
||||||
import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupState
|
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) {
|
fun Session.startSyncing(context: Context) {
|
||||||
val applicationContext = context.applicationContext
|
val applicationContext = context.applicationContext
|
||||||
if (!hasAlreadySynced()) {
|
if (!syncService().hasAlreadySynced()) {
|
||||||
// initial sync is done as a service so it can continue below app lifecycle
|
// initial sync is done as a service so it can continue below app lifecycle
|
||||||
VectorSyncService.newOneShotIntent(
|
VectorSyncAndroidService.newOneShotIntent(
|
||||||
context = applicationContext,
|
context = applicationContext,
|
||||||
sessionId = sessionId
|
sessionId = sessionId
|
||||||
)
|
)
|
||||||
|
@ -57,7 +57,7 @@ fun Session.startSyncing(context: Context) {
|
||||||
} else {
|
} else {
|
||||||
val isAtLeastStarted = ProcessLifecycleOwner.get().lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED)
|
val isAtLeastStarted = ProcessLifecycleOwner.get().lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED)
|
||||||
Timber.v("--> is at least started? $isAtLeastStarted")
|
Timber.v("--> is at least started? $isAtLeastStarted")
|
||||||
startSync(isAtLeastStarted)
|
syncService().startSync(isAtLeastStarted)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@ import javax.inject.Inject
|
||||||
class LocaleProvider @Inject constructor(private val resources: Resources) {
|
class LocaleProvider @Inject constructor(private val resources: Resources) {
|
||||||
|
|
||||||
fun current(): Locale {
|
fun current(): Locale {
|
||||||
return ConfigurationCompat.getLocales(resources.configuration)[0]
|
return ConfigurationCompat.getLocales(resources.configuration).get(0) ?: Locale.getDefault()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,12 +38,12 @@ import im.vector.app.core.time.DefaultClock
|
||||||
import im.vector.app.features.notifications.NotificationUtils
|
import im.vector.app.features.notifications.NotificationUtils
|
||||||
import im.vector.app.features.settings.BackgroundSyncMode
|
import im.vector.app.features.settings.BackgroundSyncMode
|
||||||
import org.matrix.android.sdk.api.Matrix
|
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 timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
class VectorSyncService : SyncService() {
|
class VectorSyncAndroidService : SyncAndroidService() {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ class VectorSyncService : SyncService() {
|
||||||
context: Context,
|
context: Context,
|
||||||
sessionId: String
|
sessionId: String
|
||||||
): Intent {
|
): Intent {
|
||||||
return Intent(context, VectorSyncService::class.java).also {
|
return Intent(context, VectorSyncAndroidService::class.java).also {
|
||||||
it.putExtra(EXTRA_SESSION_ID, sessionId)
|
it.putExtra(EXTRA_SESSION_ID, sessionId)
|
||||||
it.putExtra(EXTRA_TIMEOUT_SECONDS, 0)
|
it.putExtra(EXTRA_TIMEOUT_SECONDS, 0)
|
||||||
it.putExtra(EXTRA_PERIODIC, false)
|
it.putExtra(EXTRA_PERIODIC, false)
|
||||||
|
@ -65,7 +65,7 @@ class VectorSyncService : SyncService() {
|
||||||
syncDelaySeconds: Int,
|
syncDelaySeconds: Int,
|
||||||
isNetworkBack: Boolean
|
isNetworkBack: Boolean
|
||||||
): Intent {
|
): Intent {
|
||||||
return Intent(context, VectorSyncService::class.java).also {
|
return Intent(context, VectorSyncAndroidService::class.java).also {
|
||||||
it.putExtra(EXTRA_SESSION_ID, sessionId)
|
it.putExtra(EXTRA_SESSION_ID, sessionId)
|
||||||
it.putExtra(EXTRA_TIMEOUT_SECONDS, syncTimeoutSeconds)
|
it.putExtra(EXTRA_TIMEOUT_SECONDS, syncTimeoutSeconds)
|
||||||
it.putExtra(EXTRA_PERIODIC, true)
|
it.putExtra(EXTRA_PERIODIC, true)
|
||||||
|
@ -75,7 +75,7 @@ class VectorSyncService : SyncService() {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun stopIntent(context: Context): Intent {
|
fun stopIntent(context: Context): Intent {
|
||||||
return Intent(context, VectorSyncService::class.java).also {
|
return Intent(context, VectorSyncAndroidService::class.java).also {
|
||||||
it.action = ACTION_STOP
|
it.action = ACTION_STOP
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -209,7 +209,7 @@ private fun Context.rescheduleSyncService(
|
||||||
) {
|
) {
|
||||||
Timber.d("## Sync: rescheduleSyncService")
|
Timber.d("## Sync: rescheduleSyncService")
|
||||||
val intent = if (isPeriodic) {
|
val intent = if (isPeriodic) {
|
||||||
VectorSyncService.newPeriodicIntent(
|
VectorSyncAndroidService.newPeriodicIntent(
|
||||||
context = this,
|
context = this,
|
||||||
sessionId = sessionId,
|
sessionId = sessionId,
|
||||||
syncTimeoutSeconds = syncTimeoutSeconds,
|
syncTimeoutSeconds = syncTimeoutSeconds,
|
||||||
|
@ -217,7 +217,7 @@ private fun Context.rescheduleSyncService(
|
||||||
isNetworkBack = isNetworkBack
|
isNetworkBack = isNetworkBack
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
VectorSyncService.newOneShotIntent(
|
VectorSyncAndroidService.newOneShotIntent(
|
||||||
context = this,
|
context = this,
|
||||||
sessionId = sessionId
|
sessionId = sessionId
|
||||||
)
|
)
|
|
@ -37,7 +37,7 @@ import kotlinx.coroutines.launch
|
||||||
import org.matrix.android.sdk.api.session.Session
|
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.toContent
|
||||||
import org.matrix.android.sdk.api.session.events.model.toModel
|
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 org.matrix.android.sdk.flow.flow
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
|
@ -66,11 +66,11 @@ class AnalyticsAccountDataViewModel @AssistedInject constructor(
|
||||||
|
|
||||||
private fun observeInitSync() {
|
private fun observeInitSync() {
|
||||||
combine(
|
combine(
|
||||||
session.syncStatusService().getSyncStatusLive().asFlow(),
|
session.syncService().getSyncRequestStateLive().asFlow(),
|
||||||
analytics.getUserConsent(),
|
analytics.getUserConsent(),
|
||||||
analytics.getAnalyticsId()
|
analytics.getAnalyticsId()
|
||||||
) { status, userConsent, analyticsId ->
|
) { status, userConsent, analyticsId ->
|
||||||
if (status is SyncStatusService.Status.IncrementalSyncIdle &&
|
if (status is SyncRequestState.IncrementalSyncIdle &&
|
||||||
userConsent &&
|
userConsent &&
|
||||||
analyticsId.isEmpty() &&
|
analyticsId.isEmpty() &&
|
||||||
!checkDone) {
|
!checkDone) {
|
||||||
|
|
|
@ -105,6 +105,12 @@ data class Interaction(
|
||||||
*/
|
*/
|
||||||
WebHomeExploreRoomsButton,
|
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
|
* User clicked the explore rooms button next to the search field at the
|
||||||
* top of the left panel in Element Web/Desktop.
|
* top of the left panel in Element Web/Desktop.
|
||||||
|
|
|
@ -273,7 +273,7 @@ class WebRtcCallManager @Inject constructor(
|
||||||
// did we start background sync? so we should stop it
|
// did we start background sync? so we should stop it
|
||||||
if (isInBackground) {
|
if (isInBackground) {
|
||||||
if (FcmHelper.isPushSupported()) {
|
if (FcmHelper.isPushSupported()) {
|
||||||
currentSession?.stopAnyBackgroundSync()
|
currentSession?.syncService()?.stopAnyBackgroundSync()
|
||||||
} else {
|
} else {
|
||||||
// for fdroid we should not stop, it should continue syncing
|
// for fdroid we should not stop, it should continue syncing
|
||||||
// maybe we should restore default timeout/delay though?
|
// maybe we should restore default timeout/delay though?
|
||||||
|
@ -380,7 +380,7 @@ class WebRtcCallManager @Inject constructor(
|
||||||
if (isInBackground) {
|
if (isInBackground) {
|
||||||
if (FcmHelper.isPushSupported()) {
|
if (FcmHelper.isPushSupported()) {
|
||||||
// only for push version as fdroid version is already doing it?
|
// only for push version as fdroid version is already doing it?
|
||||||
currentSession?.startAutomaticBackgroundSync(30, 0)
|
currentSession?.syncService()?.startAutomaticBackgroundSync(30, 0)
|
||||||
} else {
|
} else {
|
||||||
// Maybe increase sync freq? but how to set back to default values?
|
// Maybe increase sync freq? but how to set back to default values?
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,9 +81,9 @@ import kotlinx.coroutines.flow.launchIn
|
||||||
import kotlinx.coroutines.flow.onEach
|
import kotlinx.coroutines.flow.onEach
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.parcelize.Parcelize
|
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.permalinks.PermalinkService
|
||||||
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.SyncRequestState
|
||||||
import org.matrix.android.sdk.api.session.sync.initialSyncStrategy
|
import org.matrix.android.sdk.api.session.sync.initialSyncStrategy
|
||||||
import org.matrix.android.sdk.api.util.MatrixItem
|
import org.matrix.android.sdk.api.util.MatrixItem
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
@ -199,15 +199,15 @@ class HomeActivity :
|
||||||
.stream()
|
.stream()
|
||||||
.onEach { sharedAction ->
|
.onEach { sharedAction ->
|
||||||
when (sharedAction) {
|
when (sharedAction) {
|
||||||
is HomeActivitySharedAction.OpenDrawer -> views.drawerLayout.openDrawer(GravityCompat.START)
|
is HomeActivitySharedAction.OpenDrawer -> views.drawerLayout.openDrawer(GravityCompat.START)
|
||||||
is HomeActivitySharedAction.CloseDrawer -> views.drawerLayout.closeDrawer(GravityCompat.START)
|
is HomeActivitySharedAction.CloseDrawer -> views.drawerLayout.closeDrawer(GravityCompat.START)
|
||||||
is HomeActivitySharedAction.OpenGroup -> openGroup(sharedAction.shouldClearFragment)
|
is HomeActivitySharedAction.OpenGroup -> openGroup(sharedAction.shouldClearFragment)
|
||||||
is HomeActivitySharedAction.OpenSpacePreview -> startActivity(SpacePreviewActivity.newIntent(this, sharedAction.spaceId))
|
is HomeActivitySharedAction.OpenSpacePreview -> startActivity(SpacePreviewActivity.newIntent(this, sharedAction.spaceId))
|
||||||
is HomeActivitySharedAction.AddSpace -> createSpaceResultLauncher.launch(SpaceCreationActivity.newIntent(this))
|
is HomeActivitySharedAction.AddSpace -> createSpaceResultLauncher.launch(SpaceCreationActivity.newIntent(this))
|
||||||
is HomeActivitySharedAction.ShowSpaceSettings -> showSpaceSettings(sharedAction.spaceId)
|
is HomeActivitySharedAction.ShowSpaceSettings -> showSpaceSettings(sharedAction.spaceId)
|
||||||
is HomeActivitySharedAction.OpenSpaceInvite -> openSpaceInvite(sharedAction.spaceId)
|
is HomeActivitySharedAction.OpenSpaceInvite -> openSpaceInvite(sharedAction.spaceId)
|
||||||
HomeActivitySharedAction.SendSpaceFeedBack -> bugReporter.openBugReportScreen(this, ReportType.SPACE_BETA_FEEDBACK)
|
HomeActivitySharedAction.SendSpaceFeedBack -> bugReporter.openBugReportScreen(this, ReportType.SPACE_BETA_FEEDBACK)
|
||||||
HomeActivitySharedAction.CloseGroup -> closeGroup()
|
HomeActivitySharedAction.CloseGroup -> closeGroup()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.launchIn(lifecycleScope)
|
.launchIn(lifecycleScope)
|
||||||
|
@ -226,20 +226,20 @@ class HomeActivity :
|
||||||
homeActivityViewModel.observeViewEvents {
|
homeActivityViewModel.observeViewEvents {
|
||||||
when (it) {
|
when (it) {
|
||||||
is HomeActivityViewEvents.AskPasswordToInitCrossSigning -> handleAskPasswordToInitCrossSigning(it)
|
is HomeActivityViewEvents.AskPasswordToInitCrossSigning -> handleAskPasswordToInitCrossSigning(it)
|
||||||
is HomeActivityViewEvents.OnNewSession -> handleOnNewSession(it)
|
is HomeActivityViewEvents.OnNewSession -> handleOnNewSession(it)
|
||||||
HomeActivityViewEvents.PromptToEnableSessionPush -> handlePromptToEnablePush()
|
HomeActivityViewEvents.PromptToEnableSessionPush -> handlePromptToEnablePush()
|
||||||
HomeActivityViewEvents.StartRecoverySetupFlow -> handleStartRecoverySetup()
|
HomeActivityViewEvents.StartRecoverySetupFlow -> handleStartRecoverySetup()
|
||||||
is HomeActivityViewEvents.ForceVerification -> {
|
is HomeActivityViewEvents.ForceVerification -> {
|
||||||
if (it.sendRequest) {
|
if (it.sendRequest) {
|
||||||
navigator.requestSelfSessionVerification(this)
|
navigator.requestSelfSessionVerification(this)
|
||||||
} else {
|
} else {
|
||||||
navigator.waitSessionVerification(this)
|
navigator.waitSessionVerification(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is HomeActivityViewEvents.OnCrossSignedInvalidated -> handleCrossSigningInvalidated(it)
|
is HomeActivityViewEvents.OnCrossSignedInvalidated -> handleCrossSigningInvalidated(it)
|
||||||
HomeActivityViewEvents.ShowAnalyticsOptIn -> handleShowAnalyticsOptIn()
|
HomeActivityViewEvents.ShowAnalyticsOptIn -> handleShowAnalyticsOptIn()
|
||||||
HomeActivityViewEvents.NotifyUserForThreadsMigration -> handleNotifyUserForThreadsMigration()
|
HomeActivityViewEvents.NotifyUserForThreadsMigration -> handleNotifyUserForThreadsMigration()
|
||||||
is HomeActivityViewEvents.MigrateThreads -> migrateThreadsIfNeeded(it.checkSession)
|
is HomeActivityViewEvents.MigrateThreads -> migrateThreadsIfNeeded(it.checkSession)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
homeActivityViewModel.onEach { renderState(it) }
|
homeActivityViewModel.onEach { renderState(it) }
|
||||||
|
@ -337,12 +337,12 @@ class HomeActivity :
|
||||||
when {
|
when {
|
||||||
deepLink.startsWith(USER_LINK_PREFIX) -> deepLink.substring(USER_LINK_PREFIX.length)
|
deepLink.startsWith(USER_LINK_PREFIX) -> deepLink.substring(USER_LINK_PREFIX.length)
|
||||||
deepLink.startsWith(ROOM_LINK_PREFIX) -> deepLink.substring(ROOM_LINK_PREFIX.length)
|
deepLink.startsWith(ROOM_LINK_PREFIX) -> deepLink.substring(ROOM_LINK_PREFIX.length)
|
||||||
else -> null
|
else -> null
|
||||||
}?.let { permalinkId ->
|
}?.let { permalinkId ->
|
||||||
activeSessionHolder.getSafeActiveSession()?.permalinkService()?.createPermalink(permalinkId)
|
activeSessionHolder.getSafeActiveSession()?.permalinkService()?.createPermalink(permalinkId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else -> deepLink
|
else -> deepLink
|
||||||
}
|
}
|
||||||
|
|
||||||
lifecycleScope.launch {
|
lifecycleScope.launch {
|
||||||
|
@ -373,9 +373,9 @@ class HomeActivity :
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun renderState(state: HomeActivityViewState) {
|
private fun renderState(state: HomeActivityViewState) {
|
||||||
when (val status = state.syncStatusServiceStatus) {
|
when (val status = state.syncRequestState) {
|
||||||
is SyncStatusService.Status.InitialSyncProgressing -> {
|
is SyncRequestState.InitialSyncProgressing -> {
|
||||||
val initSyncStepStr = initSyncStepFormatter.format(status.initSyncStep)
|
val initSyncStepStr = initSyncStepFormatter.format(status.initialSyncStep)
|
||||||
Timber.v("$initSyncStepStr ${status.percentProgress}")
|
Timber.v("$initSyncStepStr ${status.percentProgress}")
|
||||||
views.waitingView.root.setOnClickListener {
|
views.waitingView.root.setOnClickListener {
|
||||||
// block interactions
|
// block interactions
|
||||||
|
@ -392,7 +392,7 @@ class HomeActivity :
|
||||||
}
|
}
|
||||||
views.waitingView.root.isVisible = true
|
views.waitingView.root.isVisible = true
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
// Idle or Incremental sync status
|
// Idle or Incremental sync status
|
||||||
views.waitingView.root.isVisible = false
|
views.waitingView.root.isVisible = false
|
||||||
}
|
}
|
||||||
|
@ -544,15 +544,15 @@ class HomeActivity :
|
||||||
|
|
||||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||||
when (item.itemId) {
|
when (item.itemId) {
|
||||||
R.id.menu_home_suggestion -> {
|
R.id.menu_home_suggestion -> {
|
||||||
bugReporter.openBugReportScreen(this, ReportType.SUGGESTION)
|
bugReporter.openBugReportScreen(this, ReportType.SUGGESTION)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
R.id.menu_home_report_bug -> {
|
R.id.menu_home_report_bug -> {
|
||||||
bugReporter.openBugReportScreen(this, ReportType.BUG_REPORT)
|
bugReporter.openBugReportScreen(this, ReportType.BUG_REPORT)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
R.id.menu_home_init_sync_legacy -> {
|
R.id.menu_home_init_sync_legacy -> {
|
||||||
// Configure the SDK
|
// Configure the SDK
|
||||||
initialSyncStrategy = InitialSyncStrategy.Legacy
|
initialSyncStrategy = InitialSyncStrategy.Legacy
|
||||||
// And clear cache
|
// And clear cache
|
||||||
|
@ -566,11 +566,11 @@ class HomeActivity :
|
||||||
MainActivity.restartApp(this, MainActivityArgs(clearCache = true))
|
MainActivity.restartApp(this, MainActivityArgs(clearCache = true))
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
R.id.menu_home_filter -> {
|
R.id.menu_home_filter -> {
|
||||||
navigator.openRoomsFiltering(this)
|
navigator.openRoomsFiltering(this)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
R.id.menu_home_setting -> {
|
R.id.menu_home_setting -> {
|
||||||
navigator.openSettings(this)
|
navigator.openSettings(this)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.CryptoDeviceInfo
|
||||||
import org.matrix.android.sdk.api.session.crypto.model.MXUsersDevicesMap
|
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.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.pushrules.RuleIds
|
||||||
import org.matrix.android.sdk.api.session.room.model.Membership
|
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.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.settings.LightweightSettingsStorage
|
||||||
import org.matrix.android.sdk.api.util.awaitCallback
|
import org.matrix.android.sdk.api.util.awaitCallback
|
||||||
import org.matrix.android.sdk.api.util.toMatrixItem
|
import org.matrix.android.sdk.api.util.toMatrixItem
|
||||||
|
@ -198,7 +198,7 @@ class HomeActivityViewModel @AssistedInject constructor(
|
||||||
vectorPreferences.userNotifiedAboutThreads()
|
vectorPreferences.userNotifiedAboutThreads()
|
||||||
}
|
}
|
||||||
// Migrate users with enabled lab settings
|
// Migrate users with enabled lab settings
|
||||||
vectorPreferences.shouldNotifyUserAboutThreads() && vectorPreferences.shouldMigrateThreads() -> {
|
vectorPreferences.shouldNotifyUserAboutThreads() && vectorPreferences.shouldMigrateThreads() -> {
|
||||||
Timber.i("----> Migrate threads with enabled labs")
|
Timber.i("----> Migrate threads with enabled labs")
|
||||||
// If user had io.element.thread enabled then enable the new thread support,
|
// If user had io.element.thread enabled then enable the new thread support,
|
||||||
// clear cache to sync messages appropriately
|
// clear cache to sync messages appropriately
|
||||||
|
@ -208,7 +208,7 @@ class HomeActivityViewModel @AssistedInject constructor(
|
||||||
_viewEvents.post(HomeActivityViewEvents.MigrateThreads(checkSession = false))
|
_viewEvents.post(HomeActivityViewEvents.MigrateThreads(checkSession = false))
|
||||||
}
|
}
|
||||||
// Enable all users
|
// Enable all users
|
||||||
vectorPreferences.shouldMigrateThreads() && vectorPreferences.areThreadMessagesEnabled() -> {
|
vectorPreferences.shouldMigrateThreads() && vectorPreferences.areThreadMessagesEnabled() -> {
|
||||||
Timber.i("----> Try to migrate threads")
|
Timber.i("----> Try to migrate threads")
|
||||||
_viewEvents.post(HomeActivityViewEvents.MigrateThreads(checkSession = true))
|
_viewEvents.post(HomeActivityViewEvents.MigrateThreads(checkSession = true))
|
||||||
}
|
}
|
||||||
|
@ -218,25 +218,25 @@ class HomeActivityViewModel @AssistedInject constructor(
|
||||||
private fun observeInitialSync() {
|
private fun observeInitialSync() {
|
||||||
val session = activeSessionHolder.getSafeActiveSession() ?: return
|
val session = activeSessionHolder.getSafeActiveSession() ?: return
|
||||||
|
|
||||||
session.syncStatusService().getSyncStatusLive()
|
session.syncService().getSyncRequestStateLive()
|
||||||
.asFlow()
|
.asFlow()
|
||||||
.onEach { status ->
|
.onEach { status ->
|
||||||
when (status) {
|
when (status) {
|
||||||
is SyncStatusService.Status.Idle -> {
|
is SyncRequestState.Idle -> {
|
||||||
maybeVerifyOrBootstrapCrossSigning()
|
maybeVerifyOrBootstrapCrossSigning()
|
||||||
}
|
}
|
||||||
else -> Unit
|
else -> Unit
|
||||||
}
|
}
|
||||||
|
|
||||||
setState {
|
setState {
|
||||||
copy(
|
copy(
|
||||||
syncStatusServiceStatus = status
|
syncRequestState = status
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.launchIn(viewModelScope)
|
.launchIn(viewModelScope)
|
||||||
|
|
||||||
if (session.hasAlreadySynced()) {
|
if (session.syncService().hasAlreadySynced()) {
|
||||||
maybeVerifyOrBootstrapCrossSigning()
|
maybeVerifyOrBootstrapCrossSigning()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -426,7 +426,7 @@ class HomeActivityViewModel @AssistedInject constructor(
|
||||||
HomeActivityViewActions.PushPromptHasBeenReviewed -> {
|
HomeActivityViewActions.PushPromptHasBeenReviewed -> {
|
||||||
vectorPreferences.setDidAskUserToEnableSessionPush()
|
vectorPreferences.setDidAskUserToEnableSessionPush()
|
||||||
}
|
}
|
||||||
HomeActivityViewActions.ViewStarted -> {
|
HomeActivityViewActions.ViewStarted -> {
|
||||||
initialize()
|
initialize()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,9 +18,9 @@ package im.vector.app.features.home
|
||||||
|
|
||||||
import com.airbnb.mvrx.MavericksState
|
import com.airbnb.mvrx.MavericksState
|
||||||
import im.vector.app.features.onboarding.AuthenticationDescription
|
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(
|
data class HomeActivityViewState(
|
||||||
val syncStatusServiceStatus: SyncStatusService.Status = SyncStatusService.Status.Idle,
|
val syncRequestState: SyncRequestState = SyncRequestState.Idle,
|
||||||
val authenticationDescription: AuthenticationDescription? = null
|
val authenticationDescription: AuthenticationDescription? = null
|
||||||
) : MavericksState
|
) : MavericksState
|
||||||
|
|
|
@ -444,7 +444,7 @@ class HomeDetailFragment @Inject constructor(
|
||||||
views.bottomNavigationView.getOrCreateBadge(R.id.bottom_action_notification).render(it.notificationCountCatchup, it.notificationHighlightCatchup)
|
views.bottomNavigationView.getOrCreateBadge(R.id.bottom_action_notification).render(it.notificationCountCatchup, it.notificationHighlightCatchup)
|
||||||
views.syncStateView.render(
|
views.syncStateView.render(
|
||||||
it.syncState,
|
it.syncState,
|
||||||
it.incrementalSyncStatus,
|
it.incrementalSyncRequestState,
|
||||||
it.pushCounter,
|
it.pushCounter,
|
||||||
vectorPreferences.developerShowDebugInfo()
|
vectorPreferences.developerShowDebugInfo()
|
||||||
)
|
)
|
||||||
|
|
|
@ -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.query.toActiveSpaceOrOrphanRooms
|
||||||
import org.matrix.android.sdk.api.session.Session
|
import org.matrix.android.sdk.api.session.Session
|
||||||
import org.matrix.android.sdk.api.session.crypto.NewSessionListener
|
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.RoomSortOrder
|
||||||
import org.matrix.android.sdk.api.session.room.model.Membership
|
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.room.roomSummaryQueryParams
|
||||||
|
import org.matrix.android.sdk.api.session.sync.SyncRequestState
|
||||||
import org.matrix.android.sdk.api.util.toMatrixItem
|
import org.matrix.android.sdk.api.util.toMatrixItem
|
||||||
import org.matrix.android.sdk.flow.flow
|
import org.matrix.android.sdk.flow.flow
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
@ -199,11 +199,11 @@ class HomeDetailViewModel @AssistedInject constructor(
|
||||||
copy(syncState = syncState)
|
copy(syncState = syncState)
|
||||||
}
|
}
|
||||||
|
|
||||||
session.syncStatusService().getSyncStatusLive()
|
session.syncService().getSyncRequestStateLive()
|
||||||
.asFlow()
|
.asFlow()
|
||||||
.filterIsInstance<SyncStatusService.Status.IncrementalSyncStatus>()
|
.filterIsInstance<SyncRequestState.IncrementalSyncRequestState>()
|
||||||
.setOnEach {
|
.setOnEach {
|
||||||
copy(incrementalSyncStatus = it)
|
copy(incrementalSyncRequestState = it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,8 +22,8 @@ import com.airbnb.mvrx.MavericksState
|
||||||
import com.airbnb.mvrx.Uninitialized
|
import com.airbnb.mvrx.Uninitialized
|
||||||
import im.vector.app.R
|
import im.vector.app.R
|
||||||
import im.vector.app.RoomGroupingMethod
|
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.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.session.sync.SyncState
|
||||||
import org.matrix.android.sdk.api.util.MatrixItem
|
import org.matrix.android.sdk.api.util.MatrixItem
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ data class HomeDetailViewState(
|
||||||
val notificationHighlightRooms: Boolean = false,
|
val notificationHighlightRooms: Boolean = false,
|
||||||
val hasUnreadMessages: Boolean = false,
|
val hasUnreadMessages: Boolean = false,
|
||||||
val syncState: SyncState = SyncState.Idle,
|
val syncState: SyncState = SyncState.Idle,
|
||||||
val incrementalSyncStatus: SyncStatusService.Status.IncrementalSyncStatus = SyncStatusService.Status.IncrementalSyncIdle,
|
val incrementalSyncRequestState: SyncRequestState.IncrementalSyncRequestState = SyncRequestState.IncrementalSyncIdle,
|
||||||
val pushCounter: Int = 0,
|
val pushCounter: Int = 0,
|
||||||
val pstnSupportFlag: Boolean = false,
|
val pstnSupportFlag: Boolean = false,
|
||||||
val forceDialPadTab: Boolean = false
|
val forceDialPadTab: Boolean = false
|
||||||
|
|
|
@ -18,25 +18,25 @@ package im.vector.app.features.home
|
||||||
|
|
||||||
import im.vector.app.R
|
import im.vector.app.R
|
||||||
import im.vector.app.core.resources.StringProvider
|
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
|
import javax.inject.Inject
|
||||||
|
|
||||||
class InitSyncStepFormatter @Inject constructor(
|
class InitSyncStepFormatter @Inject constructor(
|
||||||
private val stringProvider: StringProvider
|
private val stringProvider: StringProvider
|
||||||
) {
|
) {
|
||||||
fun format(initSyncStep: InitSyncStep): String {
|
fun format(initialSyncStep: InitialSyncStep): String {
|
||||||
return stringProvider.getString(
|
return stringProvider.getString(
|
||||||
when (initSyncStep) {
|
when (initialSyncStep) {
|
||||||
InitSyncStep.ServerComputing -> R.string.initial_sync_start_server_computing
|
InitialSyncStep.ServerComputing -> R.string.initial_sync_start_server_computing
|
||||||
InitSyncStep.Downloading -> R.string.initial_sync_start_downloading
|
InitialSyncStep.Downloading -> R.string.initial_sync_start_downloading
|
||||||
InitSyncStep.ImportingAccount -> R.string.initial_sync_start_importing_account
|
InitialSyncStep.ImportingAccount -> R.string.initial_sync_start_importing_account
|
||||||
InitSyncStep.ImportingAccountCrypto -> R.string.initial_sync_start_importing_account_crypto
|
InitialSyncStep.ImportingAccountCrypto -> R.string.initial_sync_start_importing_account_crypto
|
||||||
InitSyncStep.ImportingAccountRoom -> R.string.initial_sync_start_importing_account_rooms
|
InitialSyncStep.ImportingAccountRoom -> R.string.initial_sync_start_importing_account_rooms
|
||||||
InitSyncStep.ImportingAccountGroups -> R.string.initial_sync_start_importing_account_groups
|
InitialSyncStep.ImportingAccountGroups -> R.string.initial_sync_start_importing_account_groups
|
||||||
InitSyncStep.ImportingAccountData -> R.string.initial_sync_start_importing_account_data
|
InitialSyncStep.ImportingAccountData -> R.string.initial_sync_start_importing_account_data
|
||||||
InitSyncStep.ImportingAccountJoinedRooms -> R.string.initial_sync_start_importing_account_joined_rooms
|
InitialSyncStep.ImportingAccountJoinedRooms -> R.string.initial_sync_start_importing_account_joined_rooms
|
||||||
InitSyncStep.ImportingAccountInvitedRooms -> R.string.initial_sync_start_importing_account_invited_rooms
|
InitialSyncStep.ImportingAccountInvitedRooms -> R.string.initial_sync_start_importing_account_invited_rooms
|
||||||
InitSyncStep.ImportingAccountLeftRooms -> R.string.initial_sync_start_importing_account_left_rooms
|
InitialSyncStep.ImportingAccountLeftRooms -> R.string.initial_sync_start_importing_account_left_rooms
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,11 +22,11 @@ import com.airbnb.mvrx.Uninitialized
|
||||||
import im.vector.app.features.home.room.detail.arguments.TimelineArgs
|
import im.vector.app.features.home.room.detail.arguments.TimelineArgs
|
||||||
import org.matrix.android.sdk.api.extensions.orFalse
|
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.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.members.ChangeMembershipState
|
||||||
import org.matrix.android.sdk.api.session.room.model.RoomMemberSummary
|
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.model.RoomSummary
|
||||||
import org.matrix.android.sdk.api.session.room.sender.SenderInfo
|
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.sync.SyncState
|
||||||
import org.matrix.android.sdk.api.session.threads.ThreadNotificationBadgeState
|
import org.matrix.android.sdk.api.session.threads.ThreadNotificationBadgeState
|
||||||
import org.matrix.android.sdk.api.session.widgets.model.Widget
|
import org.matrix.android.sdk.api.session.widgets.model.Widget
|
||||||
|
@ -59,7 +59,7 @@ data class RoomDetailViewState(
|
||||||
val tombstoneEvent: Event? = null,
|
val tombstoneEvent: Event? = null,
|
||||||
val joinUpgradedRoomAsync: Async<String> = Uninitialized,
|
val joinUpgradedRoomAsync: Async<String> = Uninitialized,
|
||||||
val syncState: SyncState = SyncState.Idle,
|
val syncState: SyncState = SyncState.Idle,
|
||||||
val incrementalSyncStatus: SyncStatusService.Status.IncrementalSyncStatus = SyncStatusService.Status.IncrementalSyncIdle,
|
val incrementalSyncRequestState: SyncRequestState.IncrementalSyncRequestState = SyncRequestState.IncrementalSyncIdle,
|
||||||
val pushCounter: Int = 0,
|
val pushCounter: Int = 0,
|
||||||
val highlightedEventId: String? = null,
|
val highlightedEventId: String? = null,
|
||||||
val unreadState: UnreadState = UnreadState.Unknown,
|
val unreadState: UnreadState = UnreadState.Unknown,
|
||||||
|
|
|
@ -68,6 +68,7 @@ import com.airbnb.mvrx.fragmentViewModel
|
||||||
import com.airbnb.mvrx.withState
|
import com.airbnb.mvrx.withState
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
import com.vanniktech.emoji.EmojiPopup
|
import com.vanniktech.emoji.EmojiPopup
|
||||||
|
import im.vector.app.BuildConfig
|
||||||
import im.vector.app.R
|
import im.vector.app.R
|
||||||
import im.vector.app.core.animations.play
|
import im.vector.app.core.animations.play
|
||||||
import im.vector.app.core.dialogs.ConfirmationDialogBuilder
|
import im.vector.app.core.dialogs.ConfirmationDialogBuilder
|
||||||
|
@ -430,7 +431,7 @@ class TimelineFragment @Inject constructor(
|
||||||
|
|
||||||
timelineViewModel.onEach(
|
timelineViewModel.onEach(
|
||||||
RoomDetailViewState::syncState,
|
RoomDetailViewState::syncState,
|
||||||
RoomDetailViewState::incrementalSyncStatus,
|
RoomDetailViewState::incrementalSyncRequestState,
|
||||||
RoomDetailViewState::pushCounter
|
RoomDetailViewState::pushCounter
|
||||||
) { syncState, incrementalSyncStatus, pushCounter ->
|
) { syncState, incrementalSyncStatus, pushCounter ->
|
||||||
views.syncStateView.render(
|
views.syncStateView.render(
|
||||||
|
@ -1552,7 +1553,7 @@ class TimelineFragment @Inject constructor(
|
||||||
attachmentTypeSelector = AttachmentTypeSelectorView(vectorBaseActivity, vectorBaseActivity.layoutInflater, this@TimelineFragment)
|
attachmentTypeSelector = AttachmentTypeSelectorView(vectorBaseActivity, vectorBaseActivity.layoutInflater, this@TimelineFragment)
|
||||||
attachmentTypeSelector.setAttachmentVisibility(
|
attachmentTypeSelector.setAttachmentVisibility(
|
||||||
AttachmentTypeSelectorView.Type.LOCATION,
|
AttachmentTypeSelectorView.Type.LOCATION,
|
||||||
vectorPreferences.isLocationSharingEnabled()
|
BuildConfig.enableLocationSharing
|
||||||
)
|
)
|
||||||
attachmentTypeSelector.setAttachmentVisibility(
|
attachmentTypeSelector.setAttachmentVisibility(
|
||||||
AttachmentTypeSelectorView.Type.POLL, !isThreadTimeLine()
|
AttachmentTypeSelectorView.Type.POLL, !isThreadTimeLine()
|
||||||
|
|
|
@ -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.events.model.toModel
|
||||||
import org.matrix.android.sdk.api.session.file.FileService
|
import org.matrix.android.sdk.api.session.file.FileService
|
||||||
import org.matrix.android.sdk.api.session.getRoom
|
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.getStateEvent
|
||||||
import org.matrix.android.sdk.api.session.room.getTimelineEvent
|
import org.matrix.android.sdk.api.session.room.getTimelineEvent
|
||||||
import org.matrix.android.sdk.api.session.room.members.ChangeMembershipState
|
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.read.ReadService
|
||||||
import org.matrix.android.sdk.api.session.room.timeline.Timeline
|
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.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.ThreadNotificationBadgeState
|
||||||
import org.matrix.android.sdk.api.session.threads.ThreadNotificationState
|
import org.matrix.android.sdk.api.session.threads.ThreadNotificationState
|
||||||
import org.matrix.android.sdk.api.session.widgets.model.WidgetType
|
import org.matrix.android.sdk.api.session.widgets.model.WidgetType
|
||||||
|
@ -1130,11 +1130,11 @@ class TimelineViewModel @AssistedInject constructor(
|
||||||
copy(syncState = syncState)
|
copy(syncState = syncState)
|
||||||
}
|
}
|
||||||
|
|
||||||
session.syncStatusService().getSyncStatusLive()
|
session.syncService().getSyncRequestStateLive()
|
||||||
.asFlow()
|
.asFlow()
|
||||||
.filterIsInstance<SyncStatusService.Status.IncrementalSyncStatus>()
|
.filterIsInstance<SyncRequestState.IncrementalSyncRequestState>()
|
||||||
.setOnEach {
|
.setOnEach {
|
||||||
copy(incrementalSyncStatus = it)
|
copy(incrementalSyncRequestState = it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -200,24 +200,18 @@ class MessageItemFactory @Inject constructor(
|
||||||
// val all = event.root.toContent()
|
// val all = event.root.toContent()
|
||||||
// val ev = all.toModel<Event>()
|
// val ev = all.toModel<Event>()
|
||||||
val messageItem = when (messageContent) {
|
val messageItem = when (messageContent) {
|
||||||
is MessageEmoteContent -> buildEmoteMessageItem(messageContent, informationData, highlight, callback, attributes)
|
is MessageEmoteContent -> buildEmoteMessageItem(messageContent, informationData, highlight, callback, attributes)
|
||||||
is MessageTextContent -> buildItemForTextContent(messageContent, informationData, highlight, callback, attributes)
|
is MessageTextContent -> buildItemForTextContent(messageContent, informationData, highlight, callback, attributes)
|
||||||
is MessageImageInfoContent -> buildImageMessageItem(messageContent, informationData, highlight, callback, attributes)
|
is MessageImageInfoContent -> buildImageMessageItem(messageContent, informationData, highlight, callback, attributes)
|
||||||
is MessageNoticeContent -> buildNoticeMessageItem(messageContent, informationData, highlight, callback, attributes)
|
is MessageNoticeContent -> buildNoticeMessageItem(messageContent, informationData, highlight, callback, attributes)
|
||||||
is MessageVideoContent -> buildVideoMessageItem(messageContent, informationData, highlight, callback, attributes)
|
is MessageVideoContent -> buildVideoMessageItem(messageContent, informationData, highlight, callback, attributes)
|
||||||
is MessageFileContent -> buildFileMessageItem(messageContent, highlight, attributes)
|
is MessageFileContent -> buildFileMessageItem(messageContent, highlight, attributes)
|
||||||
is MessageAudioContent -> buildAudioContent(params, messageContent, informationData, highlight, attributes)
|
is MessageAudioContent -> buildAudioContent(params, messageContent, informationData, highlight, attributes)
|
||||||
is MessageVerificationRequestContent -> buildVerificationRequestMessageItem(messageContent, informationData, highlight, callback, attributes)
|
is MessageVerificationRequestContent -> buildVerificationRequestMessageItem(messageContent, informationData, highlight, callback, attributes)
|
||||||
is MessagePollContent -> buildPollItem(messageContent, informationData, highlight, callback, attributes)
|
is MessagePollContent -> buildPollItem(messageContent, informationData, highlight, callback, attributes)
|
||||||
is MessageLocationContent -> {
|
is MessageLocationContent -> buildLocationItem(messageContent, informationData, highlight, attributes)
|
||||||
if (vectorPreferences.labsRenderLocationsInTimeline()) {
|
is MessageBeaconInfoContent -> liveLocationShareMessageItemFactory.create(params.event, highlight, attributes)
|
||||||
buildLocationItem(messageContent, informationData, highlight, attributes)
|
else -> buildNotHandledMessageItem(messageContent, informationData, highlight, callback, 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)
|
|
||||||
}
|
}
|
||||||
return messageItem?.apply {
|
return messageItem?.apply {
|
||||||
layout(informationData.messageLayout.layoutRes)
|
layout(informationData.messageLayout.layoutRes)
|
||||||
|
@ -283,11 +277,11 @@ class MessageItemFactory @Inject constructor(
|
||||||
pollResponseSummary: PollResponseData?,
|
pollResponseSummary: PollResponseData?,
|
||||||
pollContent: MessagePollContent,
|
pollContent: MessagePollContent,
|
||||||
): PollState = when {
|
): PollState = when {
|
||||||
!informationData.sendState.isSent() -> Sending
|
!informationData.sendState.isSent() -> Sending
|
||||||
pollResponseSummary?.isClosed.orFalse() -> Ended
|
pollResponseSummary?.isClosed.orFalse() -> Ended
|
||||||
pollContent.getBestPollCreationInfo()?.kind == PollType.UNDISCLOSED -> Undisclosed
|
pollContent.getBestPollCreationInfo()?.kind == PollType.UNDISCLOSED -> Undisclosed
|
||||||
pollResponseSummary?.myVote?.isNotEmpty().orFalse() -> Voted(pollResponseSummary?.totalVotes ?: 0)
|
pollResponseSummary?.myVote?.isNotEmpty().orFalse() -> Voted(pollResponseSummary?.totalVotes ?: 0)
|
||||||
else -> Ready
|
else -> Ready
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun List<PollAnswer>.mapToOptions(
|
private fun List<PollAnswer>.mapToOptions(
|
||||||
|
@ -305,11 +299,11 @@ class MessageItemFactory @Inject constructor(
|
||||||
val isWinner = winnerVoteCount != 0 && voteCount == winnerVoteCount
|
val isWinner = winnerVoteCount != 0 && voteCount == winnerVoteCount
|
||||||
|
|
||||||
when (pollState) {
|
when (pollState) {
|
||||||
Sending -> PollSending(optionId, optionAnswer)
|
Sending -> PollSending(optionId, optionAnswer)
|
||||||
Ready -> PollReady(optionId, optionAnswer)
|
Ready -> PollReady(optionId, optionAnswer)
|
||||||
is Voted -> PollVoted(optionId, optionAnswer, voteCount, votePercentage, isMyVote)
|
is Voted -> PollVoted(optionId, optionAnswer, voteCount, votePercentage, isMyVote)
|
||||||
Undisclosed -> PollUndisclosed(optionId, optionAnswer, 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 {
|
): String {
|
||||||
val votes = pollResponseSummary?.totalVotes ?: 0
|
val votes = pollResponseSummary?.totalVotes ?: 0
|
||||||
return when {
|
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 Undisclosed -> ""
|
||||||
pollState is Voted -> stringProvider.getQuantityString(R.plurals.poll_total_vote_count_before_ended_and_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)
|
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)
|
else -> stringProvider.getQuantityString(R.plurals.poll_total_vote_count_before_ended_and_not_voted, votes, votes)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -62,16 +62,15 @@ class TimelineMessageLayoutFactory @Inject constructor(
|
||||||
MessageType.MSGTYPE_STICKER_LOCAL,
|
MessageType.MSGTYPE_STICKER_LOCAL,
|
||||||
MessageType.MSGTYPE_EMOTE,
|
MessageType.MSGTYPE_EMOTE,
|
||||||
MessageType.MSGTYPE_BEACON_INFO,
|
MessageType.MSGTYPE_BEACON_INFO,
|
||||||
|
MessageType.MSGTYPE_LOCATION,
|
||||||
|
MessageType.MSGTYPE_BEACON_LOCATION_DATA,
|
||||||
)
|
)
|
||||||
private val MSG_TYPES_WITH_TIMESTAMP_INSIDE_MESSAGE = setOf(
|
private val MSG_TYPES_WITH_TIMESTAMP_INSIDE_MESSAGE = setOf(
|
||||||
MessageType.MSGTYPE_IMAGE,
|
MessageType.MSGTYPE_IMAGE,
|
||||||
MessageType.MSGTYPE_VIDEO,
|
MessageType.MSGTYPE_VIDEO,
|
||||||
MessageType.MSGTYPE_BEACON_INFO,
|
MessageType.MSGTYPE_BEACON_INFO,
|
||||||
)
|
|
||||||
|
|
||||||
private val MSG_TYPES_WITH_LOCATION_DATA = setOf(
|
|
||||||
MessageType.MSGTYPE_LOCATION,
|
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 {
|
private fun MessageContent?.isPseudoBubble(): Boolean {
|
||||||
if (this == null) return false
|
if (this == null) return false
|
||||||
if (msgType == MessageType.MSGTYPE_LOCATION) return vectorPreferences.labsRenderLocationsInTimeline()
|
|
||||||
return this.msgType in MSG_TYPES_WITH_PSEUDO_BUBBLE_LAYOUT
|
return this.msgType in MSG_TYPES_WITH_PSEUDO_BUBBLE_LAYOUT
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun MessageContent?.timestampInsideMessage(): Boolean {
|
private fun MessageContent?.timestampInsideMessage(): Boolean {
|
||||||
return when {
|
return when {
|
||||||
this == null -> false
|
this == null -> false
|
||||||
msgType in MSG_TYPES_WITH_LOCATION_DATA -> vectorPreferences.labsRenderLocationsInTimeline()
|
else -> msgType in MSG_TYPES_WITH_TIMESTAMP_INSIDE_MESSAGE
|
||||||
else -> msgType in MSG_TYPES_WITH_TIMESTAMP_INSIDE_MESSAGE
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun MessageContent?.shouldAddMessageOverlay(): Boolean {
|
private fun MessageContent?.shouldAddMessageOverlay(): Boolean {
|
||||||
return when {
|
return when {
|
||||||
this == null || msgType == MessageType.MSGTYPE_BEACON_INFO -> false
|
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()) {
|
return when (event?.root?.getClearType()) {
|
||||||
EventType.KEY_VERIFICATION_DONE,
|
EventType.KEY_VERIFICATION_DONE,
|
||||||
EventType.KEY_VERIFICATION_CANCEL -> true
|
EventType.KEY_VERIFICATION_CANCEL -> true
|
||||||
EventType.MESSAGE -> {
|
EventType.MESSAGE -> {
|
||||||
event.getLastMessageContent() is MessageVerificationRequestContent
|
event.getLastMessageContent() is MessageVerificationRequestContent
|
||||||
}
|
}
|
||||||
else -> false
|
else -> false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -191,9 +191,6 @@ class VectorPreferences @Inject constructor(
|
||||||
|
|
||||||
private const val DID_ASK_TO_ENABLE_SESSION_PUSH = "DID_ASK_TO_ENABLE_SESSION_PUSH"
|
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_3_DAYS = 0
|
||||||
private const val MEDIA_SAVING_1_WEEK = 1
|
private const val MEDIA_SAVING_1_WEEK = 1
|
||||||
private const val MEDIA_SAVING_1_MONTH = 2
|
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 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"
|
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
|
// 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 {
|
fun labsEnableLiveLocation(): Boolean {
|
||||||
return defaultPrefs.getBoolean(SETTINGS_LABS_ENABLE_LIVE_LOCATION, false)
|
return defaultPrefs.getBoolean(SETTINGS_LABS_ENABLE_LIVE_LOCATION, false)
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,6 @@ import androidx.core.view.children
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.preference.Preference
|
import androidx.preference.Preference
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
import im.vector.app.BuildConfig
|
|
||||||
import im.vector.app.R
|
import im.vector.app.R
|
||||||
import im.vector.app.core.dialogs.PhotoOrVideoDialog
|
import im.vector.app.core.dialogs.PhotoOrVideoDialog
|
||||||
import im.vector.app.core.extensions.restart
|
import im.vector.app.core.extensions.restart
|
||||||
|
@ -173,8 +172,6 @@ class VectorSettingsPreferencesFragment @Inject constructor(
|
||||||
})
|
})
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
findPreference<VectorSwitchPreference>(VectorPreferences.SETTINGS_PREF_ENABLE_LOCATION_SHARING)?.isVisible = BuildConfig.enableLocationSharing
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateTakePhotoOrVideoPreferenceSummary() {
|
private fun updateTakePhotoOrVideoPreferenceSummary() {
|
||||||
|
|
|
@ -211,7 +211,7 @@ class SoftLogoutViewModel @AssistedInject constructor(
|
||||||
private fun onSessionRestored() {
|
private fun onSessionRestored() {
|
||||||
activeSessionHolder.setActiveSession(session)
|
activeSessionHolder.setActiveSession(session)
|
||||||
// Start the sync
|
// Start the sync
|
||||||
session.startSync(true)
|
session.syncService().startSync(true)
|
||||||
|
|
||||||
// TODO Configure and start ? Check that the push still works...
|
// TODO Configure and start ? Check that the push still works...
|
||||||
setState {
|
setState {
|
||||||
|
|
|
@ -24,7 +24,7 @@ import androidx.core.view.isVisible
|
||||||
import im.vector.app.R
|
import im.vector.app.R
|
||||||
import im.vector.app.core.utils.isAirplaneModeOn
|
import im.vector.app.core.utils.isAirplaneModeOn
|
||||||
import im.vector.app.databinding.ViewSyncStateBinding
|
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
|
import org.matrix.android.sdk.api.session.sync.SyncState
|
||||||
|
|
||||||
class SyncStateView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyle: Int = 0) :
|
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")
|
@SuppressLint("SetTextI18n")
|
||||||
fun render(
|
fun render(
|
||||||
newState: SyncState,
|
newState: SyncState,
|
||||||
incrementalSyncStatus: SyncStatusService.Status.IncrementalSyncStatus,
|
incrementalSyncRequestState: SyncRequestState.IncrementalSyncRequestState,
|
||||||
pushCounter: Int,
|
pushCounter: Int,
|
||||||
showDebugInfo: Boolean
|
showDebugInfo: Boolean
|
||||||
) {
|
) {
|
||||||
views.syncStateDebugInfo.isVisible = showDebugInfo
|
views.syncStateDebugInfo.isVisible = showDebugInfo
|
||||||
if (showDebugInfo) {
|
if (showDebugInfo) {
|
||||||
views.syncStateDebugInfoText.text =
|
views.syncStateDebugInfoText.text =
|
||||||
"Sync thread : ${newState.toHumanReadable()}\nSync request: ${incrementalSyncStatus.toHumanReadable()}"
|
"Sync thread : ${newState.toHumanReadable()}\nSync request: ${incrementalSyncRequestState.toHumanReadable()}"
|
||||||
views.syncStateDebugInfoPushCounter.text =
|
views.syncStateDebugInfoPushCounter.text =
|
||||||
"Push: $pushCounter"
|
"Push: $pushCounter"
|
||||||
}
|
}
|
||||||
|
@ -66,23 +66,23 @@ class SyncStateView @JvmOverloads constructor(context: Context, attrs: Attribute
|
||||||
|
|
||||||
private fun SyncState.toHumanReadable(): String {
|
private fun SyncState.toHumanReadable(): String {
|
||||||
return when (this) {
|
return when (this) {
|
||||||
SyncState.Idle -> "Idle"
|
SyncState.Idle -> "Idle"
|
||||||
SyncState.InvalidToken -> "InvalidToken"
|
SyncState.InvalidToken -> "InvalidToken"
|
||||||
SyncState.Killed -> "Killed"
|
SyncState.Killed -> "Killed"
|
||||||
SyncState.Killing -> "Killing"
|
SyncState.Killing -> "Killing"
|
||||||
SyncState.NoNetwork -> "NoNetwork"
|
SyncState.NoNetwork -> "NoNetwork"
|
||||||
SyncState.Paused -> "Paused"
|
SyncState.Paused -> "Paused"
|
||||||
is SyncState.Running -> "$this"
|
is SyncState.Running -> "$this"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun SyncStatusService.Status.IncrementalSyncStatus.toHumanReadable(): String {
|
private fun SyncRequestState.IncrementalSyncRequestState.toHumanReadable(): String {
|
||||||
return when (this) {
|
return when (this) {
|
||||||
SyncStatusService.Status.IncrementalSyncIdle -> "Idle"
|
SyncRequestState.IncrementalSyncIdle -> "Idle"
|
||||||
is SyncStatusService.Status.IncrementalSyncParsing -> "Parsing ${this.rooms} room(s) ${this.toDevice} toDevice(s)"
|
is SyncRequestState.IncrementalSyncParsing -> "Parsing ${this.rooms} room(s) ${this.toDevice} toDevice(s)"
|
||||||
SyncStatusService.Status.IncrementalSyncError -> "Error"
|
SyncRequestState.IncrementalSyncError -> "Error"
|
||||||
SyncStatusService.Status.IncrementalSyncDone -> "Done"
|
SyncRequestState.IncrementalSyncDone -> "Done"
|
||||||
else -> "?"
|
else -> "?"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3017,9 +3017,12 @@
|
||||||
<string name="location_not_available_dialog_title">${app_name} could not access your location</string>
|
<string name="location_not_available_dialog_title">${app_name} could not access your location</string>
|
||||||
<string name="location_not_available_dialog_content">${app_name} could not access your location. Please try again later.</string>
|
<string name="location_not_available_dialog_content">${app_name} could not access your location. Please try again later.</string>
|
||||||
<string name="location_share_external">Open with</string>
|
<string name="location_share_external">Open with</string>
|
||||||
<string name="settings_enable_location_sharing">Enable location sharing</string>
|
<!--TODO delete-->
|
||||||
<string name="settings_enable_location_sharing_summary">Once enabled you will be able to send your location to any room</string>
|
<string name="settings_enable_location_sharing" tools:ignore="UnusedResources">Enable location sharing</string>
|
||||||
<string name="labs_render_locations_in_timeline">Render user locations in the timeline</string>
|
<!--TODO delete-->
|
||||||
|
<string name="settings_enable_location_sharing_summary" tools:ignore="UnusedResources">Once enabled you will be able to send your location to any room</string>
|
||||||
|
<!--TODO delete-->
|
||||||
|
<string name="labs_render_locations_in_timeline" tools:ignore="UnusedResources">Render user locations in the timeline</string>
|
||||||
<string name="location_timeline_failed_to_load_map">Failed to load map</string>
|
<string name="location_timeline_failed_to_load_map">Failed to load map</string>
|
||||||
<string name="location_share_live_enabled">Live location enabled</string>
|
<string name="location_share_live_enabled">Live location enabled</string>
|
||||||
<string name="location_share_live_started">Loading live location…</string>
|
<string name="location_share_live_started">Loading live location…</string>
|
||||||
|
|
|
@ -64,11 +64,6 @@
|
||||||
android:summary="@string/labs_auto_report_uisi_desc"
|
android:summary="@string/labs_auto_report_uisi_desc"
|
||||||
android:title="@string/labs_auto_report_uisi" />
|
android:title="@string/labs_auto_report_uisi" />
|
||||||
|
|
||||||
<im.vector.app.core.preference.VectorSwitchPreference
|
|
||||||
android:defaultValue="true"
|
|
||||||
android:key="SETTINGS_LABS_RENDER_LOCATIONS_IN_TIMELINE"
|
|
||||||
android:title="@string/labs_render_locations_in_timeline" />
|
|
||||||
|
|
||||||
<im.vector.app.core.preference.VectorSwitchPreference
|
<im.vector.app.core.preference.VectorSwitchPreference
|
||||||
android:defaultValue="false"
|
android:defaultValue="false"
|
||||||
android:key="SETTINGS_LABS_ENABLE_LIVE_LOCATION"
|
android:key="SETTINGS_LABS_ENABLE_LIVE_LOCATION"
|
||||||
|
|
|
@ -72,12 +72,6 @@
|
||||||
android:title="@string/option_take_photo_video"
|
android:title="@string/option_take_photo_video"
|
||||||
tools:summary="@string/option_always_ask" />
|
tools:summary="@string/option_always_ask" />
|
||||||
|
|
||||||
<im.vector.app.core.preference.VectorSwitchPreference
|
|
||||||
android:defaultValue="false"
|
|
||||||
android:key="SETTINGS_PREF_ENABLE_LOCATION_SHARING"
|
|
||||||
android:summary="@string/settings_enable_location_sharing_summary"
|
|
||||||
android:title="@string/settings_enable_location_sharing" />
|
|
||||||
|
|
||||||
</im.vector.app.core.preference.VectorPreferenceCategory>
|
</im.vector.app.core.preference.VectorPreferenceCategory>
|
||||||
|
|
||||||
<im.vector.app.core.preference.VectorPreferenceCategory android:title="@string/settings_category_timeline">
|
<im.vector.app.core.preference.VectorPreferenceCategory android:title="@string/settings_category_timeline">
|
||||||
|
|
Loading…
Reference in New Issue