Initial sync, start the sync thread or the sync service

This commit is contained in:
ganfra 2019-12-17 18:46:19 +01:00
parent 2316c98a65
commit 4c88c12cfe
8 changed files with 48 additions and 30 deletions

View File

@ -53,7 +53,7 @@ internal class NetworkConnectivityChecker @Inject constructor(private val contex
@WorkerThread
fun hasInternetAccess(): Boolean {
// If we are in background we have unbound merlin, so we have to check
return if (backgroundDetectionObserver.isIsBackground) {
return if (backgroundDetectionObserver.isInBackground) {
merlinsBeard.hasInternetAccess()
} else {
hasInternetAccess

View File

@ -38,7 +38,6 @@ internal class DefaultSyncTask @Inject constructor(private val syncAPI: SyncAPI,
@UserId private val userId: String,
private val filterRepository: FilterRepository,
private val syncResponseHandler: SyncResponseHandler,
private val sessionParamsStore: SessionParamsStore,
private val initialSyncProgressService: DefaultInitialSyncProgressService,
private val syncTokenStore: SyncTokenStore,
private val getHomeServerCapabilitiesTask: GetHomeServerCapabilitiesTask,

View File

@ -19,11 +19,13 @@ import android.app.Service
import android.content.Intent
import android.os.IBinder
import im.vector.matrix.android.api.Matrix
import im.vector.matrix.android.api.failure.MatrixError
import im.vector.matrix.android.api.failure.isTokenError
import im.vector.matrix.android.api.session.Session
import im.vector.matrix.android.api.session.sync.SyncState
import im.vector.matrix.android.internal.network.NetworkConnectivityChecker
import im.vector.matrix.android.internal.session.sync.SyncTask
import im.vector.matrix.android.internal.task.TaskExecutor
import im.vector.matrix.android.internal.util.BackgroundDetectionObserver
import im.vector.matrix.android.internal.util.MatrixCoroutineDispatchers
import kotlinx.coroutines.*
import timber.log.Timber
@ -40,10 +42,13 @@ abstract class SyncService : Service() {
private var userId: String? = null
private var mIsSelfDestroyed: Boolean = false
private var isInitialSync: Boolean = false
private lateinit var session: Session
private lateinit var syncTask: SyncTask
private lateinit var networkConnectivityChecker: NetworkConnectivityChecker
private lateinit var taskExecutor: TaskExecutor
private lateinit var coroutineDispatchers: MatrixCoroutineDispatchers
private lateinit var backgroundDetectionObserver: BackgroundDetectionObserver
private val isRunning = AtomicBoolean(false)
@ -52,14 +57,19 @@ abstract class SyncService : Service() {
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
Timber.i("onStartCommand $intent")
intent?.let {
val matrix = Matrix.getInstance(applicationContext)
val safeUserId = it.getStringExtra(EXTRA_USER_ID) ?: return@let
val sessionComponent = Matrix.getInstance(applicationContext).sessionManager.getSessionComponent(safeUserId)
val sessionComponent = matrix.sessionManager.getSessionComponent(safeUserId)
?: return@let
session = sessionComponent.session()
userId = safeUserId
syncTask = sessionComponent.syncTask()
isInitialSync = !session.hasAlreadySynced()
networkConnectivityChecker = sessionComponent.networkConnectivityChecker()
taskExecutor = sessionComponent.taskExecutor()
coroutineDispatchers = sessionComponent.coroutineDispatchers()
backgroundDetectionObserver = matrix.backgroundDetectionObserver
onStart(isInitialSync)
if (isRunning.get()) {
Timber.i("Received a start while was already syncing... ignore")
} else {
@ -92,7 +102,7 @@ abstract class SyncService : Service() {
if (!networkConnectivityChecker.hasInternetAccess()) {
Timber.v("No network reschedule to avoid wasting resources")
userId?.also {
onRescheduleAsked(it, delay = 10_000L)
onRescheduleAsked(it, isInitialSync, delay = 10_000L)
}
stopMe()
return
@ -101,6 +111,11 @@ abstract class SyncService : Service() {
val params = SyncTask.Params(TIME_OUT)
try {
syncTask.execute(params)
// Start sync if we were doing an initial sync and the syncThread is not launched yet
if (isInitialSync && session.syncState().value == SyncState.Idle) {
val isForeground = !backgroundDetectionObserver.isInBackground
session.startSync(isForeground)
}
stopMe()
} catch (throwable: Throwable) {
Timber.e(throwable)
@ -114,7 +129,9 @@ abstract class SyncService : Service() {
}
}
abstract fun onRescheduleAsked(userId: String, delay: Long)
abstract fun onStart(isInitialSync: Boolean)
abstract fun onRescheduleAsked(userId: String, isInitialSync: Boolean, delay: Long)
override fun onBind(intent: Intent?): IBinder? {
return null

View File

@ -29,7 +29,7 @@ import javax.inject.Inject
@MatrixScope
internal class BackgroundDetectionObserver @Inject constructor() : LifecycleObserver {
var isIsBackground: Boolean = false
var isInBackground: Boolean = false
private set
private
@ -46,14 +46,14 @@ internal class BackgroundDetectionObserver @Inject constructor() : LifecycleObse
@OnLifecycleEvent(Lifecycle.Event.ON_START)
fun onMoveToForeground() {
Timber.v("App returning to foreground…")
isIsBackground = false
isInBackground = false
listeners.forEach { it.onMoveToForeground() }
}
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
fun onMoveToBackground() {
Timber.v("App going to background…")
isIsBackground = true
isInBackground = true
listeners.forEach { it.onMoveToBackground() }
}

View File

@ -55,10 +55,11 @@ fun Session.startSyncing(context: Context) {
Timber.e(ex)
}
}
} else {
val isAtLeastStarted = ProcessLifecycleOwner.get().lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED)
Timber.v("--> is at least started? $isAtLeastStarted")
startSync(isAtLeastStarted)
}
val isAtLeastStarted = ProcessLifecycleOwner.get().lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED)
Timber.v("--> is at least started? $isAtLeastStarted")
startSync(isAtLeastStarted)
}
/**

View File

@ -25,7 +25,6 @@ import im.vector.matrix.android.internal.session.sync.job.SyncService
import im.vector.riotx.R
import im.vector.riotx.core.extensions.vectorComponent
import im.vector.riotx.features.notifications.NotificationUtils
import timber.log.Timber
class VectorSyncService : SyncService() {
@ -45,16 +44,20 @@ class VectorSyncService : SyncService() {
notificationUtils = vectorComponent().notificationUtils()
}
/**
* Service is started in fdroid mode when no FCM is available or is used for initialSync
*/
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
Timber.v("VectorSyncService - onStartCommand ")
override fun onStart(isInitialSync: Boolean) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val notification = notificationUtils.buildForegroundServiceNotification(R.string.notification_listening_for_events, false)
val notificationSubtitleRes = if (isInitialSync) {
R.string.notification_initial_sync
} else {
R.string.notification_listening_for_events
}
val notification = notificationUtils.buildForegroundServiceNotification(notificationSubtitleRes, false)
startForeground(NotificationUtils.NOTIFICATION_ID_FOREGROUND_SERVICE, notification)
}
return super.onStartCommand(intent, flags, startId)
}
override fun onRescheduleAsked(userId: String, isInitialSync: Boolean, delay: Long) {
reschedule(userId, delay)
}
override fun onDestroy() {
@ -62,10 +65,6 @@ class VectorSyncService : SyncService() {
super.onDestroy()
}
override fun onRescheduleAsked(userId: String, delay: Long) {
reschedule(userId, delay)
}
private fun removeForegroundNotif() {
val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
notificationManager.cancel(NotificationUtils.NOTIFICATION_ID_FOREGROUND_SERVICE)

View File

@ -127,7 +127,8 @@ class MainActivity : VectorBaseActivity() {
override fun onSuccess(data: Unit) {
Timber.w("SIGN_OUT: success, start app")
sessionHolder.clearActiveSession()
doLocalCleanupAndStart()
doLocalCleanup()
startNextActivityAndFinish()
}
override fun onFailure(failure: Throwable) {
@ -137,8 +138,9 @@ class MainActivity : VectorBaseActivity() {
args.clearCache -> session.clearCache(
object : MatrixCallback<Unit> {
override fun onSuccess(data: Unit) {
doLocalCleanup()
session.startSyncing(applicationContext)
doLocalCleanupAndStart()
startNextActivityAndFinish()
}
override fun onFailure(failure: Throwable) {
@ -153,7 +155,7 @@ class MainActivity : VectorBaseActivity() {
Timber.w("Ignoring invalid token global error")
}
private fun doLocalCleanupAndStart() {
private fun doLocalCleanup() {
GlobalScope.launch(Dispatchers.Main) {
// On UI Thread
Glide.get(this@MainActivity).clearMemory()
@ -165,8 +167,6 @@ class MainActivity : VectorBaseActivity() {
deleteAllFiles(this@MainActivity.cacheDir)
}
}
startNextActivityAndFinish()
}
private fun displayError(failure: Throwable) {
@ -182,7 +182,7 @@ class MainActivity : VectorBaseActivity() {
private fun startNextActivityAndFinish() {
val intent = when {
args.clearCredentials
&& !args.isUserLoggedOut ->
&& !args.isUserLoggedOut ->
// User has explicitly asked to log out
LoginActivity.newIntent(this, null)
args.isSoftLogout ->

View File

@ -162,4 +162,6 @@
<string name="soft_logout_sso_not_same_user_error">The current session is for user %1$s and you provide credentials for user %2$s. This is not supported by RiotX.\nPlease first clear data, then sign in again on another account.</string>
<string name="permalink_malformed">Your matrix.to link was malformed</string>
<string name="notification_initial_sync">Initial Sync…</string>
</resources>