From 95d83db90c900b676e4f4a5ea1497d55382e9fbf Mon Sep 17 00:00:00 2001 From: Valere Date: Thu, 4 Jul 2019 10:53:46 +0200 Subject: [PATCH] WIP --- .../api/session/InitialSyncProgressService.kt | 13 +++ .../matrix/android/api/session/Session.kt | 5 +- .../DefaultInitialSyncProgressService.kt | 97 +++++++++++++++++++ .../internal/session/DefaultSession.kt | 9 +- .../internal/session/SessionComponent.kt | 1 + .../android/internal/session/SessionModule.kt | 4 + .../session/sync/CryptoSyncHandler.kt | 8 +- .../internal/session/sync/GroupSyncHandler.kt | 46 +++++++-- .../internal/session/sync/RoomSyncHandler.kt | 44 +++++++-- .../session/sync/SyncResponseHandler.kt | 43 +++++--- .../android/internal/session/sync/SyncTask.kt | 20 +++- .../src/main/res/values/strings.xml | 9 ++ .../riotx/features/home/HomeActivity.kt | 23 +++++ .../features/rageshake/BugReportActivity.kt | 6 +- .../riotx/features/rageshake/BugReporter.kt | 22 ++--- vector/src/main/res/layout/activity.xml | 62 +----------- vector/src/main/res/layout/activity_home.xml | 3 + .../res/layout/merge_overlay_waiting_view.xml | 71 ++++++++++++++ 18 files changed, 373 insertions(+), 113 deletions(-) create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/InitialSyncProgressService.kt create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/DefaultInitialSyncProgressService.kt create mode 100644 vector/src/main/res/layout/merge_overlay_waiting_view.xml diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/InitialSyncProgressService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/InitialSyncProgressService.kt new file mode 100644 index 0000000000..619d9356a5 --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/InitialSyncProgressService.kt @@ -0,0 +1,13 @@ +package im.vector.matrix.android.api.session + +import androidx.lifecycle.LiveData + +interface InitialSyncProgressService { + + fun getLiveStatus() : LiveData + + data class Status( + val statusText: Int?, + val percentProgress: Int = 0 + ) +} \ No newline at end of file diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/Session.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/Session.kt index 3621c6ad21..08e706c3e4 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/Session.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/Session.kt @@ -49,14 +49,15 @@ interface Session : FilterService, FileService, PushRuleService, - PushersService { + PushersService, + InitialSyncProgressService { /** * The params associated to the session */ val sessionParams: SessionParams - val myUserId : String + val myUserId: String get() = sessionParams.credentials.userId diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/DefaultInitialSyncProgressService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/DefaultInitialSyncProgressService.kt new file mode 100644 index 0000000000..3bf5f7ae3a --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/DefaultInitialSyncProgressService.kt @@ -0,0 +1,97 @@ +package im.vector.matrix.android.internal.session + +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import im.vector.matrix.android.api.session.InitialSyncProgressService +import timber.log.Timber +import javax.inject.Inject + + +@SessionScope +class DefaultInitialSyncProgressService @Inject constructor() : InitialSyncProgressService { + + var status = MutableLiveData() + + var rootTask: TaskInfo? = null + + override fun getLiveStatus(): LiveData { + return status + } + + + fun startTask(nameRes: Int, totalProgress: Int, parentWeight: Float = 1f) { + if (rootTask == null) { + rootTask = TaskInfo(nameRes, totalProgress) + } else { + val currentLeaf = rootTask!!.leaf() + val newTask = TaskInfo(nameRes, totalProgress) + newTask.parent = currentLeaf + newTask.offset = currentLeaf.currentProgress + currentLeaf.child = newTask + newTask.parentWeight = parentWeight + } + reportProgress(0) + } + + fun reportProgress(progress: Int) { + rootTask?.leaf()?.incrementProgress(progress) + } + + fun endTask(nameRes: Int) { + val endedTask = rootTask?.leaf() + if (endedTask?.nameRes == nameRes) { + //close it + val parent = endedTask.parent + parent?.child = null + parent?.incrementProgress(endedTask.offset + (endedTask.totalProgress * endedTask.parentWeight).toInt()) + } + if (endedTask?.parent == null) { + this@DefaultInitialSyncProgressService.status.postValue(null) + } + } + + fun endAll() { + this@DefaultInitialSyncProgressService.status.postValue(null) + } + + + inner class TaskInfo(var nameRes: Int, + var totalProgress: Int) { + var parent: TaskInfo? = null + var child: TaskInfo? = null + var parentWeight: Float = 1f + var currentProgress: Int = 0 + var offset: Int = 0 + + fun leaf(): TaskInfo { + var last = this + while (last.child != null) { + last = last.child!! + } + return last + } + + fun incrementProgress(progress: Int) { + currentProgress = progress +// val newProgress = Math.min(currentProgress + progress, totalProgress) + parent?.let { + val parentProgress = (currentProgress * parentWeight).toInt() + it.incrementProgress(offset + parentProgress) + } + if (parent == null) { + Timber.e("--- ${leaf().nameRes}: ${currentProgress}") + this@DefaultInitialSyncProgressService.status.postValue( + InitialSyncProgressService.Status(leaf().nameRes, currentProgress) + ) + } + } + } + +} + +public inline fun reportSubtask(reporter: DefaultInitialSyncProgressService?, nameRes: Int, totalProgress: Int, parentWeight: Float = 1f, block: () -> T): T { + reporter?.startTask(nameRes, totalProgress, parentWeight) + return block().also { + reporter?.endTask(nameRes) + } +} \ No newline at end of file diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/DefaultSession.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/DefaultSession.kt index 72fdadfc1e..1e2aec849b 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/DefaultSession.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/DefaultSession.kt @@ -24,6 +24,7 @@ import androidx.work.WorkManager import im.vector.matrix.android.api.MatrixCallback import im.vector.matrix.android.api.auth.data.SessionParams import im.vector.matrix.android.api.pushrules.PushRuleService +import im.vector.matrix.android.api.session.InitialSyncProgressService import im.vector.matrix.android.api.session.Session import im.vector.matrix.android.api.session.cache.CacheService import im.vector.matrix.android.api.session.content.ContentUploadStateTracker @@ -64,7 +65,8 @@ internal class DefaultSession @Inject constructor(override val sessionParams: Se private val fileService: FileService, private val syncThread: SyncThread, private val contentUrlResolver: ContentUrlResolver, - private val contentUploadProgressTracker: ContentUploadStateTracker) + private val contentUploadProgressTracker: ContentUploadStateTracker, + private val initialSyncProgressService: InitialSyncProgressService) : Session, RoomService by roomService, RoomDirectoryService by roomDirectoryService, @@ -74,9 +76,10 @@ internal class DefaultSession @Inject constructor(override val sessionParams: Se CacheService by cacheService, SignOutService by signOutService, FilterService by filterService, - FileService by fileService, PushRuleService by pushRuleService, - PushersService by pushersService { + PushersService by pushersService, + FileService by fileService, + InitialSyncProgressService by initialSyncProgressService { private var isOpen = false diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/SessionComponent.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/SessionComponent.kt index fc23b78037..1738ceddcd 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/SessionComponent.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/SessionComponent.kt @@ -19,6 +19,7 @@ package im.vector.matrix.android.internal.session import dagger.BindsInstance import dagger.Component import im.vector.matrix.android.api.auth.data.SessionParams +import im.vector.matrix.android.api.session.InitialSyncProgressService import im.vector.matrix.android.api.session.Session import im.vector.matrix.android.internal.crypto.CryptoModule import im.vector.matrix.android.internal.di.MatrixComponent diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/SessionModule.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/SessionModule.kt index 8f580da11e..d1673bfef3 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/SessionModule.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/SessionModule.kt @@ -25,6 +25,7 @@ import dagger.multibindings.IntoSet import im.vector.matrix.android.api.auth.data.Credentials import im.vector.matrix.android.api.auth.data.HomeServerConnectionConfig import im.vector.matrix.android.api.auth.data.SessionParams +import im.vector.matrix.android.api.session.InitialSyncProgressService import im.vector.matrix.android.api.session.Session import im.vector.matrix.android.internal.database.LiveEntityObserver import im.vector.matrix.android.internal.database.configureEncryption @@ -132,4 +133,7 @@ internal abstract class SessionModule { @IntoSet abstract fun bindUserEntityUpdater(groupSummaryUpdater: UserEntityUpdater): LiveEntityObserver + @Binds + abstract fun bindInitialSyncProgressService(initialSyncProgressService: DefaultInitialSyncProgressService): InitialSyncProgressService + } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/CryptoSyncHandler.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/CryptoSyncHandler.kt index a9416a703a..cb102d5d41 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/CryptoSyncHandler.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/CryptoSyncHandler.kt @@ -26,6 +26,8 @@ import im.vector.matrix.android.internal.crypto.CryptoManager import im.vector.matrix.android.internal.crypto.MXEventDecryptionResult import im.vector.matrix.android.internal.crypto.algorithms.olm.OlmDecryptionResult import im.vector.matrix.android.internal.crypto.verification.DefaultSasVerificationService +import im.vector.matrix.android.internal.session.DefaultInitialSyncProgressService +import im.vector.matrix.android.internal.session.SessionScope import im.vector.matrix.android.internal.session.sync.model.SyncResponse import im.vector.matrix.android.internal.session.sync.model.ToDeviceSyncResponse import timber.log.Timber @@ -35,8 +37,10 @@ import javax.inject.Inject internal class CryptoSyncHandler @Inject constructor(private val cryptoManager: CryptoManager, private val sasVerificationService: DefaultSasVerificationService) { - fun handleToDevice(toDevice: ToDeviceSyncResponse) { - toDevice.events?.forEach { event -> + fun handleToDevice(toDevice: ToDeviceSyncResponse, initialSyncProgressService: DefaultInitialSyncProgressService? = null) { + val total = toDevice.events?.size ?: 0 + toDevice.events?.forEachIndexed { index, event -> + initialSyncProgressService?.reportProgress(((index / total.toFloat()) * 100).toInt()) // Decrypt event if necessary decryptEvent(event, null) if (TextUtils.equals(event.getClearType(), EventType.MESSAGE) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/GroupSyncHandler.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/GroupSyncHandler.kt index d7b8328c7d..4d19bcf57c 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/GroupSyncHandler.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/GroupSyncHandler.kt @@ -17,10 +17,11 @@ package im.vector.matrix.android.internal.session.sync import com.zhuinden.monarchy.Monarchy +import im.vector.matrix.android.R import im.vector.matrix.android.api.session.room.model.Membership import im.vector.matrix.android.internal.database.model.GroupEntity import im.vector.matrix.android.internal.database.query.where -import im.vector.matrix.android.internal.session.SessionScope +import im.vector.matrix.android.internal.session.DefaultInitialSyncProgressService import im.vector.matrix.android.internal.session.sync.model.GroupsSyncResponse import im.vector.matrix.android.internal.session.sync.model.InvitedGroupSync import io.realm.Realm @@ -34,21 +35,48 @@ internal class GroupSyncHandler @Inject constructor(private val monarchy: Monarc data class LEFT(val data: Map) : HandlingStrategy() } - fun handle(roomsSyncResponse: GroupsSyncResponse) { + fun handle(roomsSyncResponse: GroupsSyncResponse, reporter: DefaultInitialSyncProgressService? = null) { monarchy.runTransactionSync { realm -> - handleGroupSync(realm, GroupSyncHandler.HandlingStrategy.JOINED(roomsSyncResponse.join)) - handleGroupSync(realm, GroupSyncHandler.HandlingStrategy.INVITED(roomsSyncResponse.invite)) - handleGroupSync(realm, GroupSyncHandler.HandlingStrategy.LEFT(roomsSyncResponse.leave)) + handleGroupSync(realm, HandlingStrategy.JOINED(roomsSyncResponse.join), reporter) + handleGroupSync(realm, HandlingStrategy.INVITED(roomsSyncResponse.invite), reporter) + handleGroupSync(realm, HandlingStrategy.LEFT(roomsSyncResponse.leave), reporter) } } // PRIVATE METHODS ***************************************************************************** - private fun handleGroupSync(realm: Realm, handlingStrategy: HandlingStrategy) { + private fun handleGroupSync(realm: Realm, handlingStrategy: HandlingStrategy, reporter: DefaultInitialSyncProgressService?) { val groups = when (handlingStrategy) { - is HandlingStrategy.JOINED -> handlingStrategy.data.map { handleJoinedGroup(realm, it.key) } - is HandlingStrategy.INVITED -> handlingStrategy.data.map { handleInvitedGroup(realm, it.key) } - is HandlingStrategy.LEFT -> handlingStrategy.data.map { handleLeftGroup(realm, it.key) } + is HandlingStrategy.JOINED -> { + val total = handlingStrategy.data.size + reporter?.startTask(R.string.initial_sync_start_importing_account_groups, total, 0.6f) + var current = 0 + handlingStrategy.data.map { + reporter?.reportProgress((current / total.toFloat() * 100).toInt()) + current++ + handleJoinedGroup(realm, it.key) + } + } + is HandlingStrategy.INVITED -> { + val total = handlingStrategy.data.size + reporter?.startTask(R.string.initial_sync_start_importing_account_groups, total, 0.3f) + var current = 0 + handlingStrategy.data.map { + reporter?.reportProgress((current / total.toFloat() * 100).toInt()) + current++ + handleInvitedGroup(realm, it.key) + } + } + is HandlingStrategy.LEFT -> { + val total = handlingStrategy.data.size + reporter?.startTask(R.string.initial_sync_start_importing_account_groups, total, 0.1f) + var current = 0 + handlingStrategy.data.map { + reporter?.reportProgress((current / total.toFloat() * 100).toInt()) + current++ + handleLeftGroup(realm, it.key) + } + } } realm.insertOrUpdate(groups) } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/RoomSyncHandler.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/RoomSyncHandler.kt index 3afc57f943..ae59bad852 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/RoomSyncHandler.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/RoomSyncHandler.kt @@ -17,6 +17,7 @@ package im.vector.matrix.android.internal.session.sync import com.zhuinden.monarchy.Monarchy +import im.vector.matrix.android.R import im.vector.matrix.android.api.session.events.model.Event import im.vector.matrix.android.api.session.events.model.EventType import im.vector.matrix.android.api.session.events.model.toModel @@ -32,6 +33,7 @@ import im.vector.matrix.android.internal.database.model.RoomEntity import im.vector.matrix.android.internal.database.query.find import im.vector.matrix.android.internal.database.query.findLastLiveChunkFromRoom import im.vector.matrix.android.internal.database.query.where +import im.vector.matrix.android.internal.session.DefaultInitialSyncProgressService import im.vector.matrix.android.internal.session.notification.DefaultPushRuleService import im.vector.matrix.android.internal.session.notification.ProcessEventForPushTask import im.vector.matrix.android.internal.session.room.RoomSummaryUpdater @@ -60,11 +62,11 @@ internal class RoomSyncHandler @Inject constructor(private val monarchy: Monarch data class LEFT(val data: Map) : HandlingStrategy() } - fun handle(roomsSyncResponse: RoomsSyncResponse) { + fun handle(roomsSyncResponse: RoomsSyncResponse, reporter: DefaultInitialSyncProgressService? = null) { monarchy.runTransactionSync { realm -> - handleRoomSync(realm, HandlingStrategy.JOINED(roomsSyncResponse.join)) - handleRoomSync(realm, HandlingStrategy.INVITED(roomsSyncResponse.invite)) - handleRoomSync(realm, HandlingStrategy.LEFT(roomsSyncResponse.leave)) + handleRoomSync(realm, HandlingStrategy.JOINED(roomsSyncResponse.join), reporter) + handleRoomSync(realm, HandlingStrategy.INVITED(roomsSyncResponse.invite), reporter) + handleRoomSync(realm, HandlingStrategy.LEFT(roomsSyncResponse.leave), reporter) } //handle event for bing rule checks @@ -87,11 +89,37 @@ internal class RoomSyncHandler @Inject constructor(private val monarchy: Monarch // PRIVATE METHODS ***************************************************************************** - private fun handleRoomSync(realm: Realm, handlingStrategy: HandlingStrategy) { + private fun handleRoomSync(realm: Realm, handlingStrategy: HandlingStrategy, reporter: DefaultInitialSyncProgressService?) { + val rooms = when (handlingStrategy) { - is HandlingStrategy.JOINED -> handlingStrategy.data.map { handleJoinedRoom(realm, it.key, it.value) } - is HandlingStrategy.INVITED -> handlingStrategy.data.map { handleInvitedRoom(realm, it.key, it.value) } - is HandlingStrategy.LEFT -> handlingStrategy.data.map { handleLeftRoom(realm, it.key, it.value) } + is HandlingStrategy.JOINED -> { + val total = handlingStrategy.data.size + reporter?.startTask(R.string.initial_sync_start_importing_account_joined_rooms, total, 0.6f) + var current = 0 + handlingStrategy.data.map { + reporter?.reportProgress((current / total.toFloat() * 100).toInt()) + current++ + handleJoinedRoom(realm, it.key, it.value).also { + reporter?.endTask(R.string.initial_sync_start_importing_account_joined_rooms) + } + } + + } + is HandlingStrategy.INVITED -> { + val total = handlingStrategy.data.size + reporter?.startTask(R.string.initial_sync_start_importing_account_invited_rooms, total, 0.4f) + var current = 0 + handlingStrategy.data.map { + reporter?.reportProgress((current / total.toFloat() * 100).toInt()) + current++ + handleInvitedRoom(realm, it.key, it.value) + }.also { + reporter?.endTask(R.string.initial_sync_start_importing_account_invited_rooms) + } + } + is HandlingStrategy.LEFT -> { + handlingStrategy.data.map { handleLeftRoom(realm, it.key, it.value) } + } } realm.insertOrUpdate(rooms) } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/SyncResponseHandler.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/SyncResponseHandler.kt index d21b1de3b0..8d018d6175 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/SyncResponseHandler.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/SyncResponseHandler.kt @@ -17,7 +17,10 @@ package im.vector.matrix.android.internal.session.sync import arrow.core.Try +import im.vector.matrix.android.R import im.vector.matrix.android.internal.crypto.CryptoManager +import im.vector.matrix.android.internal.session.DefaultInitialSyncProgressService +import im.vector.matrix.android.internal.session.reportSubtask import im.vector.matrix.android.internal.session.sync.model.SyncResponse import timber.log.Timber import javax.inject.Inject @@ -27,12 +30,15 @@ internal class SyncResponseHandler @Inject constructor(private val roomSyncHandl private val userAccountDataSyncHandler: UserAccountDataSyncHandler, private val groupSyncHandler: GroupSyncHandler, private val cryptoSyncHandler: CryptoSyncHandler, - private val cryptoManager: CryptoManager) { + private val cryptoManager: CryptoManager, + private val initialSyncProgressService: DefaultInitialSyncProgressService) { fun handleResponse(syncResponse: SyncResponse, fromToken: String?, isCatchingUp: Boolean): Try { return Try { - Timber.v("Start handling sync") val isInitialSync = fromToken == null + Timber.v("Start handling sync, is InitialSync: ${isInitialSync}") + val reporter = initialSyncProgressService.takeIf { isInitialSync } + if (!cryptoManager.isStarted()) { Timber.v("Should start cryptoManager") cryptoManager.start(isInitialSync) @@ -41,23 +47,36 @@ internal class SyncResponseHandler @Inject constructor(private val roomSyncHandl // Handle the to device events before the room ones // to ensure to decrypt them properly Timber.v("Handle toDevice") - if (syncResponse.toDevice != null) { - cryptoSyncHandler.handleToDevice(syncResponse.toDevice) + reportSubtask(reporter, R.string.initial_sync_start_importing_account_crypto, 100, 0.2f) { + if (syncResponse.toDevice != null) { + cryptoSyncHandler.handleToDevice(syncResponse.toDevice, reporter) + } } Timber.v("Handle rooms") - if (syncResponse.rooms != null) { - roomSyncHandler.handle(syncResponse.rooms) + + reportSubtask(reporter, R.string.initial_sync_start_importing_account_rooms, 100, 0.5f) { + if (syncResponse.rooms != null) { + roomSyncHandler.handle(syncResponse.rooms, reporter) + } } - Timber.v("Handle groups") - if (syncResponse.groups != null) { - groupSyncHandler.handle(syncResponse.groups) + + reportSubtask(reporter, R.string.initial_sync_start_importing_account_groups, 100, 0.2f) { + Timber.v("Handle groups") + if (syncResponse.groups != null) { + groupSyncHandler.handle(syncResponse.groups, reporter) + } } - Timber.v("Handle accoundData") - if (syncResponse.accountData != null) { - userAccountDataSyncHandler.handle(syncResponse.accountData) + + reportSubtask(reporter, R.string.initial_sync_start_importing_account_data, 100, 0.1f) { + Timber.v("Handle accoundData") + if (syncResponse.accountData != null) { + userAccountDataSyncHandler.handle(syncResponse.accountData) + } } + Timber.v("On sync completed") cryptoSyncHandler.onSyncCompleted(syncResponse) + } Timber.v("Finish handling sync in $measure ms") syncResponse diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/SyncTask.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/SyncTask.kt index e29f2eeac5..45e10fb97d 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/SyncTask.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/SyncTask.kt @@ -19,14 +19,18 @@ package im.vector.matrix.android.internal.session.sync import arrow.core.Try import arrow.core.failure import arrow.core.recoverWith +import com.zhuinden.monarchy.Monarchy +import im.vector.matrix.android.R import im.vector.matrix.android.api.auth.data.Credentials import im.vector.matrix.android.api.failure.Failure import im.vector.matrix.android.api.failure.MatrixError import im.vector.matrix.android.internal.auth.SessionParamsStore import im.vector.matrix.android.internal.network.executeRequest +import im.vector.matrix.android.internal.session.DefaultInitialSyncProgressService import im.vector.matrix.android.internal.session.filter.FilterRepository import im.vector.matrix.android.internal.session.sync.model.SyncResponse import im.vector.matrix.android.internal.task.Task +import im.vector.matrix.android.internal.util.tryTransactionAsync import javax.inject.Inject internal interface SyncTask : Task { @@ -40,7 +44,9 @@ internal class DefaultSyncTask @Inject constructor(private val syncAPI: SyncAPI, private val filterRepository: FilterRepository, private val syncResponseHandler: SyncResponseHandler, private val sessionParamsStore: SessionParamsStore, - private val syncTokenStore: SyncTokenStore + private val initialSyncProgressService: DefaultInitialSyncProgressService, + private val syncTokenStore: SyncTokenStore, + private val monarchy: Monarchy ) : SyncTask { @@ -55,6 +61,10 @@ internal class DefaultSyncTask @Inject constructor(private val syncAPI: SyncAPI, requestParams["timeout"] = timeout.toString() requestParams["filter"] = filterRepository.getFilter() + val isInitialSync = token == null + if (isInitialSync) { + initialSyncProgressService.startTask(R.string.initial_sync_start_importing_account, 100) + } return executeRequest { apiCall = syncAPI.sync(requestParams) }.recoverWith { throwable -> @@ -67,7 +77,13 @@ internal class DefaultSyncTask @Inject constructor(private val syncAPI: SyncAPI, // Transmit the throwable throwable.failure() }.flatMap { syncResponse -> - syncResponseHandler.handleResponse(syncResponse, token, false) + syncResponseHandler.handleResponse(syncResponse, token, false).also { + if (isInitialSync) { + monarchy.tryTransactionAsync { + initialSyncProgressService.endAll() + } + } + } }.map { syncTokenStore.saveToken(it.nextBatch) } diff --git a/matrix-sdk-android/src/main/res/values/strings.xml b/matrix-sdk-android/src/main/res/values/strings.xml index be64a65974..eb39b689dc 100644 --- a/matrix-sdk-android/src/main/res/values/strings.xml +++ b/matrix-sdk-android/src/main/res/values/strings.xml @@ -228,4 +228,13 @@ Pin + + Initial Sync:\nImporting account… + Initial Sync:\nImporting crypto + Initial Sync:\nImporting Rooms + Initial Sync:\nImporting Joined Rooms + Initial Sync:\nImporting Invited Rooms + Initial Sync:\nImporting Left Rooms + Initial Sync:\nImporting Communities + Initial Sync:\nImporting Account Data diff --git a/vector/src/main/java/im/vector/riotx/features/home/HomeActivity.kt b/vector/src/main/java/im/vector/riotx/features/home/HomeActivity.kt index 21ca495ab9..398c3c46ce 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/HomeActivity.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/HomeActivity.kt @@ -17,6 +17,7 @@ package im.vector.riotx.features.home import android.app.ProgressDialog +import android.app.TimePickerDialog import android.content.Context import android.content.Intent import android.os.Bundle @@ -24,6 +25,7 @@ import android.view.MenuItem import androidx.appcompat.app.AlertDialog import androidx.appcompat.widget.Toolbar import androidx.core.view.GravityCompat +import androidx.core.view.isVisible import androidx.drawerlayout.widget.DrawerLayout import androidx.fragment.app.FragmentManager import androidx.lifecycle.Observer @@ -45,6 +47,8 @@ import im.vector.riotx.features.rageshake.VectorUncaughtExceptionHandler import im.vector.riotx.features.workers.signout.SignOutViewModel import im.vector.riotx.push.fcm.FcmHelper import kotlinx.android.synthetic.main.activity_home.* +import kotlinx.android.synthetic.main.merge_overlay_waiting_view.* +import timber.log.Timber import javax.inject.Inject @@ -114,6 +118,25 @@ class HomeActivity : VectorBaseActivity(), ToolbarConfigurable { notificationDrawerManager.clearAllEvents() intent.removeExtra(EXTRA_CLEAR_EXISTING_NOTIFICATION) } + + activeSessionHolder.getSafeActiveSession()?.getLiveStatus()?.observe(this, Observer { + Timber.e("${it?.statusText?.let { getString(it) }} ${it?.percentProgress}") + if (it == null) { + waiting_view.isVisible = false + } else { + waiting_view_status_horizontal_progress.apply { + isIndeterminate = false + max = 100 + progress = it.percentProgress + isVisible = true + } + waiting_view_status_text.apply { + text = it.statusText?.let { res -> getString(res) } + isVisible = true + } + waiting_view.isVisible = true + } + }) } override fun onNewIntent(intent: Intent?) { diff --git a/vector/src/main/java/im/vector/riotx/features/rageshake/BugReportActivity.kt b/vector/src/main/java/im/vector/riotx/features/rageshake/BugReportActivity.kt index d0e229ff7b..7f56bdc08c 100755 --- a/vector/src/main/java/im/vector/riotx/features/rageshake/BugReportActivity.kt +++ b/vector/src/main/java/im/vector/riotx/features/rageshake/BugReportActivity.kt @@ -30,7 +30,7 @@ import kotlinx.android.synthetic.main.activity_bug_report.* import timber.log.Timber /** - * Form to send a bug report + * Form to send a bug reportSubtask */ class BugReportActivity : VectorBaseActivity() { @@ -56,7 +56,7 @@ class BugReportActivity : VectorBaseActivity() { forSuggestion = intent.getBooleanExtra("FOR_SUGGESTION", false) - // Default screen is for bug report, so modify it for suggestion + // Default screen is for bug reportSubtask, so modify it for suggestion if (forSuggestion) { supportActionBar?.setTitle(R.string.send_suggestion) @@ -101,7 +101,7 @@ class BugReportActivity : VectorBaseActivity() { /** - * Send the bug report + * Send the bug reportSubtask */ private fun sendBugReport() { bug_report_scrollview.alpha = 0.3f diff --git a/vector/src/main/java/im/vector/riotx/features/rageshake/BugReporter.kt b/vector/src/main/java/im/vector/riotx/features/rageshake/BugReporter.kt index 7bb75c4ed9..123d0a5ac7 100755 --- a/vector/src/main/java/im/vector/riotx/features/rageshake/BugReporter.kt +++ b/vector/src/main/java/im/vector/riotx/features/rageshake/BugReporter.kt @@ -68,11 +68,11 @@ class BugReporter @Inject constructor(private val activeSessionHolder: ActiveSes // the http client private val mOkHttpClient = OkHttpClient() - // the pending bug report call + // the pending bug reportSubtask call private var mBugReportCall: Call? = null - // boolean to cancel the bug report + // boolean to cancel the bug reportSubtask private val mIsCancelled = false /** @@ -96,16 +96,16 @@ class BugReporter @Inject constructor(private val activeSessionHolder: ActiveSes private val LOGCAT_CMD_DEBUG = arrayOf("logcat", "-d", "-v", "threadtime", "*:*") /** - * Bug report upload listener + * Bug reportSubtask upload listener */ interface IMXBugReportListener { /** - * The bug report has been cancelled + * The bug reportSubtask has been cancelled */ fun onUploadCancelled() /** - * The bug report upload failed. + * The bug reportSubtask upload failed. * * @param reason the failure reason */ @@ -119,13 +119,13 @@ class BugReporter @Inject constructor(private val activeSessionHolder: ActiveSes fun onProgress(progress: Int) /** - * The bug report upload succeeded. + * The bug reportSubtask upload succeeded. */ fun onUploadSucceed() } /** - * Send a bug report. + * Send a bug reportSubtask. * * @param context the application context * @param forSuggestion true to send a suggestion @@ -407,7 +407,7 @@ class BugReporter @Inject constructor(private val activeSessionHolder: ActiveSes override fun onPostExecute(reason: String?) { mBugReportCall = null - // delete when the bug report has been successfully sent + // delete when the bug reportSubtask has been successfully sent for (file in mBugReportFiles) { file.delete() } @@ -431,7 +431,7 @@ class BugReporter @Inject constructor(private val activeSessionHolder: ActiveSes } /** - * Send a bug report either with email or with Vector. + * Send a bug reportSubtask either with email or with Vector. */ fun openBugReportScreen(activity: Activity, forSuggestion: Boolean = false) { screenshot = takeScreenshot(activity) @@ -442,7 +442,7 @@ class BugReporter @Inject constructor(private val activeSessionHolder: ActiveSes } //============================================================================================================== - // crash report management + // crash reportSubtask management //============================================================================================================== /** @@ -472,7 +472,7 @@ class BugReporter @Inject constructor(private val activeSessionHolder: ActiveSes } /** - * Save the crash report + * Save the crash reportSubtask * * @param context the context * @param crashDescription teh crash description diff --git a/vector/src/main/res/layout/activity.xml b/vector/src/main/res/layout/activity.xml index 9a5c32e4f2..df0cd3fbea 100644 --- a/vector/src/main/res/layout/activity.xml +++ b/vector/src/main/res/layout/activity.xml @@ -22,66 +22,6 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/toolbar" /> - - - - - - - - - - - - - - - - - + diff --git a/vector/src/main/res/layout/activity_home.xml b/vector/src/main/res/layout/activity_home.xml index 599b7d4cfb..c6f74147d5 100644 --- a/vector/src/main/res/layout/activity_home.xml +++ b/vector/src/main/res/layout/activity_home.xml @@ -15,6 +15,8 @@ android:id="@+id/homeDetailFragmentContainer" android:layout_width="match_parent" android:layout_height="match_parent" /> + + @@ -24,4 +26,5 @@ android:layout_height="match_parent" android:layout_gravity="start" /> + \ No newline at end of file diff --git a/vector/src/main/res/layout/merge_overlay_waiting_view.xml b/vector/src/main/res/layout/merge_overlay_waiting_view.xml new file mode 100644 index 0000000000..8f09ed0988 --- /dev/null +++ b/vector/src/main/res/layout/merge_overlay_waiting_view.xml @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file