From e7f9bf86c6773a9050e84ddea7a737e09522477b Mon Sep 17 00:00:00 2001 From: ganfra Date: Wed, 17 Oct 2018 15:20:26 +0200 Subject: [PATCH] Pause/Resume sync thread when app goes background/foreground --- .idea/caches/build_file_checksums.ser | Bin 651 -> 651 bytes matrix-sdk-android/build.gradle | 7 +-- .../im/vector/matrix/android/api/Matrix.kt | 6 ++- .../android/internal/di/MatrixModule.kt | 6 +++ .../internal/events/sync/SyncModule.kt | 2 +- .../internal/events/sync/job/SyncThread.kt | 19 ++++++-- .../util/BackgroundDetectionObserver.kt | 46 ++++++++++++++++++ 7 files changed, 74 insertions(+), 12 deletions(-) create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/util/BackgroundDetectionObserver.kt diff --git a/.idea/caches/build_file_checksums.ser b/.idea/caches/build_file_checksums.ser index f1d03afc68338383cfc12e31de7f1918461bef67..acb3a3d585df817f46861c946b2e8c6b7da4d1fe 100644 GIT binary patch delta 36 ucmV+<0NekI1&alcm;{0qHPW%1EddaX{8=&8+w|~u_d%5KH1zb7*#WXCauSLF delta 36 ucmV+<0NekI1&alcm;`}Qt_iW6Edda3$riX)ldWJg4nkNN*^r)-*#WZofev>7 diff --git a/matrix-sdk-android/build.gradle b/matrix-sdk-android/build.gradle index 7e1402bad1..8fb1dadd1a 100644 --- a/matrix-sdk-android/build.gradle +++ b/matrix-sdk-android/build.gradle @@ -45,7 +45,6 @@ dependencies { def support_version = '28.0.0' def moshi_version = '1.7.0' def lifecycle_version = "1.1.1" - def work_version = "1.0.0-alpha10" implementation fileTree(dir: 'libs', include: ['*.aar']) implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" @@ -65,7 +64,6 @@ dependencies { implementation 'com.squareup.okhttp3:logging-interceptor:3.10.0' implementation 'com.squareup.okio:okio:1.15.0' implementation 'com.novoda:merlin:1.1.6' - implementation 'com.google.code.gson:gson:2.8.5' implementation "com.squareup.moshi:moshi-adapters:$moshi_version" kapt "com.squareup.moshi:moshi-kotlin-codegen:$moshi_version" @@ -73,10 +71,7 @@ dependencies { // Paging implementation "android.arch.paging:runtime:1.0.1" - // Worker - implementation "android.arch.work:work-runtime-ktx:$work_version" - implementation 'com.evernote:android-job:1.2.6' - + // FP implementation "io.arrow-kt:arrow-core:$arrow_version" // DI diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/Matrix.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/Matrix.kt index 83852976ef..6ff5a5ba5f 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/Matrix.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/Matrix.kt @@ -1,12 +1,13 @@ package im.vector.matrix.android.api +import android.arch.lifecycle.ProcessLifecycleOwner import android.content.Context -import com.evernote.android.job.JobManager import im.vector.matrix.android.api.auth.Authenticator import im.vector.matrix.android.api.session.Session import im.vector.matrix.android.internal.auth.AuthModule import im.vector.matrix.android.internal.di.MatrixModule import im.vector.matrix.android.internal.di.NetworkModule +import im.vector.matrix.android.internal.util.BackgroundDetectionObserver import io.realm.Realm import org.koin.standalone.KoinComponent import org.koin.standalone.StandAloneContext.loadKoinModules @@ -16,16 +17,17 @@ import org.koin.standalone.inject class Matrix(matrixOptions: MatrixOptions) : KoinComponent { private val authenticator by inject() + private val backgroundDetectionObserver by inject() var currentSession: Session? = null init { Realm.init(matrixOptions.context) - JobManager.create(matrixOptions.context) val matrixModule = MatrixModule(matrixOptions) val networkModule = NetworkModule() val authModule = AuthModule() loadKoinModules(listOf(matrixModule, networkModule, authModule)) + ProcessLifecycleOwner.get().lifecycle.addObserver(backgroundDetectionObserver) } fun authenticator(): Authenticator { diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/MatrixModule.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/MatrixModule.kt index 7d4cfbf728..cee73a5ea0 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/MatrixModule.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/MatrixModule.kt @@ -2,6 +2,7 @@ package im.vector.matrix.android.internal.di import im.vector.matrix.android.api.MatrixOptions import im.vector.matrix.android.api.thread.MainThreadExecutor +import im.vector.matrix.android.internal.util.BackgroundDetectionObserver import im.vector.matrix.android.internal.util.MatrixCoroutineDispatchers import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.IO @@ -22,5 +23,10 @@ class MatrixModule(private val options: MatrixOptions) : Module { single { MatrixCoroutineDispatchers(io = Dispatchers.IO, computation = Dispatchers.IO, main = MainThreadExecutor().asCoroutineDispatcher()) } + + single { + BackgroundDetectionObserver() + } + }.invoke() } \ No newline at end of file diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/events/sync/SyncModule.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/events/sync/SyncModule.kt index 03bcea5462..10d7602b9f 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/events/sync/SyncModule.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/events/sync/SyncModule.kt @@ -34,7 +34,7 @@ class SyncModule : Module { } scope(DefaultSession.SCOPE) { - SyncThread(get(), get(), get()) + SyncThread(get(), get(), get(), get()) } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/events/sync/job/SyncThread.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/events/sync/job/SyncThread.kt index b865e711e1..a35fcffa6b 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/events/sync/job/SyncThread.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/events/sync/job/SyncThread.kt @@ -7,6 +7,7 @@ import im.vector.matrix.android.internal.events.sync.SyncRequest import im.vector.matrix.android.internal.events.sync.SyncTokenStore import im.vector.matrix.android.internal.events.sync.data.SyncResponse import im.vector.matrix.android.internal.network.NetworkConnectivityChecker +import im.vector.matrix.android.internal.util.BackgroundDetectionObserver import timber.log.Timber import java.util.concurrent.CountDownLatch @@ -14,8 +15,9 @@ private const val RETRY_WAIT_TIME_MS = 10_000L class SyncThread(private val syncRequest: SyncRequest, private val networkConnectivityChecker: NetworkConnectivityChecker, - private val syncTokenStore: SyncTokenStore -) : Thread(), NetworkConnectivityChecker.Listener { + private val syncTokenStore: SyncTokenStore, + private val backgroundDetectionObserver: BackgroundDetectionObserver +) : Thread(), NetworkConnectivityChecker.Listener, BackgroundDetectionObserver.Listener { enum class State { IDLE, @@ -63,8 +65,9 @@ class SyncThread(private val syncRequest: SyncRequest, override fun run() { Timber.v("Start syncing...") - state = State.RUNNING networkConnectivityChecker.register(this) + backgroundDetectionObserver.register(this) + state = State.RUNNING while (state != State.KILLING) { if (!networkConnectivityChecker.isConnected() || state == State.PAUSED) { Timber.v("Waiting...") @@ -94,6 +97,7 @@ class SyncThread(private val syncRequest: SyncRequest, } Timber.v("Sync killed") state = State.KILLED + backgroundDetectionObserver.unregister(this) networkConnectivityChecker.unregister(this) } @@ -103,6 +107,15 @@ class SyncThread(private val syncRequest: SyncRequest, } } + override fun onMoveToForeground() { + restart() + } + + override fun onMoveToBackground() { + pause() + } + + } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/util/BackgroundDetectionObserver.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/util/BackgroundDetectionObserver.kt new file mode 100644 index 0000000000..9fb35421bc --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/util/BackgroundDetectionObserver.kt @@ -0,0 +1,46 @@ +package im.vector.matrix.android.internal.util + +import android.arch.lifecycle.Lifecycle +import android.arch.lifecycle.LifecycleObserver +import android.arch.lifecycle.OnLifecycleEvent +import timber.log.Timber + +/** + * To be attached to ProcessLifecycleOwner lifecycle + */ +class BackgroundDetectionObserver : LifecycleObserver { + + var isIsBackground: Boolean = false + private set + + private + val listeners = ArrayList() + + fun register(listener: Listener) { + listeners.add(listener) + } + + fun unregister(listener: Listener) { + listeners.remove(listener) + } + + @OnLifecycleEvent(Lifecycle.Event.ON_START) + fun onMoveToForeground() { + Timber.d("App returning to foreground…") + isIsBackground = false + listeners.forEach { it.onMoveToForeground() } + } + + @OnLifecycleEvent(Lifecycle.Event.ON_STOP) + fun onMoveToBackground() { + Timber.d("App going to background…") + isIsBackground = true + listeners.forEach { it.onMoveToBackground() } + } + + interface Listener { + fun onMoveToForeground() + fun onMoveToBackground() + } + +} \ No newline at end of file