From 2ef7b0e9996eab72b1007df3f8e84f950537dec1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niccol=C3=B2=20Forlini?= Date: Fri, 29 Aug 2025 11:59:17 +0200 Subject: [PATCH] Wire Rust resume/pause work on app lifecycle changes ET-4565 --- .../BackgroundExecutionInitializer.kt | 2 +- ...server.kt => RustWorkLifecycleObserver.kt} | 14 ++++++++++++- ...st.kt => RustWorkLifecycleObserverTest.kt} | 20 +++++++++++++------ .../data/wrapper/MailSessionWrapper.kt | 10 ++++++++++ 4 files changed, 38 insertions(+), 8 deletions(-) rename app/src/main/kotlin/ch/protonmail/android/initializer/background/{BackgroundExecutionLifecycleObserver.kt => RustWorkLifecycleObserver.kt} (76%) rename app/src/test/kotlin/ch/protonmail/android/initializer/background/{BackgroundExecutionLifecycleObserverTest.kt => RustWorkLifecycleObserverTest.kt} (65%) diff --git a/app/src/main/kotlin/ch/protonmail/android/initializer/background/BackgroundExecutionInitializer.kt b/app/src/main/kotlin/ch/protonmail/android/initializer/background/BackgroundExecutionInitializer.kt index 86aa25e724..3785b25c54 100644 --- a/app/src/main/kotlin/ch/protonmail/android/initializer/background/BackgroundExecutionInitializer.kt +++ b/app/src/main/kotlin/ch/protonmail/android/initializer/background/BackgroundExecutionInitializer.kt @@ -46,6 +46,6 @@ internal class BackgroundExecutionInitializer : Initializer { @InstallIn(SingletonComponent::class) interface BackgroundExecutionEntryPoint { - fun lifecycleObserver(): BackgroundExecutionLifecycleObserver + fun lifecycleObserver(): RustWorkLifecycleObserver } } diff --git a/app/src/main/kotlin/ch/protonmail/android/initializer/background/BackgroundExecutionLifecycleObserver.kt b/app/src/main/kotlin/ch/protonmail/android/initializer/background/RustWorkLifecycleObserver.kt similarity index 76% rename from app/src/main/kotlin/ch/protonmail/android/initializer/background/BackgroundExecutionLifecycleObserver.kt rename to app/src/main/kotlin/ch/protonmail/android/initializer/background/RustWorkLifecycleObserver.kt index ed3fcc9c9f..ed340fcfb9 100644 --- a/app/src/main/kotlin/ch/protonmail/android/initializer/background/BackgroundExecutionLifecycleObserver.kt +++ b/app/src/main/kotlin/ch/protonmail/android/initializer/background/RustWorkLifecycleObserver.kt @@ -21,17 +21,29 @@ package ch.protonmail.android.initializer.background import androidx.lifecycle.DefaultLifecycleObserver import androidx.lifecycle.LifecycleOwner import ch.protonmail.android.mailsession.data.background.BackgroundExecutionWorkScheduler +import ch.protonmail.android.mailsession.data.repository.MailSessionRepository import javax.inject.Inject -class BackgroundExecutionLifecycleObserver @Inject constructor( +class RustWorkLifecycleObserver @Inject constructor( + private val mailSessionRepository: MailSessionRepository, private val backgroundExecutionWorkScheduler: BackgroundExecutionWorkScheduler ) : DefaultLifecycleObserver { override fun onResume(owner: LifecycleOwner) { backgroundExecutionWorkScheduler.cancelPendingWork() + resumeWork() } override fun onStop(owner: LifecycleOwner) { + pauseWork() backgroundExecutionWorkScheduler.scheduleWork() } + + private fun pauseWork() { + mailSessionRepository.getMailSession().pauseWork() + } + + private fun resumeWork() { + mailSessionRepository.getMailSession().resumeWork() + } } diff --git a/app/src/test/kotlin/ch/protonmail/android/initializer/background/BackgroundExecutionLifecycleObserverTest.kt b/app/src/test/kotlin/ch/protonmail/android/initializer/background/RustWorkLifecycleObserverTest.kt similarity index 65% rename from app/src/test/kotlin/ch/protonmail/android/initializer/background/BackgroundExecutionLifecycleObserverTest.kt rename to app/src/test/kotlin/ch/protonmail/android/initializer/background/RustWorkLifecycleObserverTest.kt index 80cad01272..eb276689f5 100644 --- a/app/src/test/kotlin/ch/protonmail/android/initializer/background/BackgroundExecutionLifecycleObserverTest.kt +++ b/app/src/test/kotlin/ch/protonmail/android/initializer/background/RustWorkLifecycleObserverTest.kt @@ -20,6 +20,7 @@ package ch.protonmail.android.initializer.background import androidx.lifecycle.LifecycleOwner import ch.protonmail.android.mailsession.data.background.BackgroundExecutionWorkScheduler +import ch.protonmail.android.mailsession.data.repository.MailSessionRepository import io.mockk.coEvery import io.mockk.coVerify import io.mockk.confirmVerified @@ -30,34 +31,41 @@ import io.mockk.runs import io.mockk.verify import kotlin.test.Test -internal class BackgroundExecutionLifecycleObserverTest { +internal class RustWorkLifecycleObserverTest { private val scheduler = mockk() - private val observer = BackgroundExecutionLifecycleObserver(scheduler) + private val mailSessionRepository = mockk() + private val observer = RustWorkLifecycleObserver(mailSessionRepository, scheduler) private val lifecycleOwner = mockk() @Test - fun `should cancel background work when onResume is triggered`() { + fun `should cancel background execution and resume work when onResume is triggered`() { // Given every { scheduler.cancelPendingWork() } just runs + every { mailSessionRepository.getMailSession().resumeWork() } just runs + // When observer.onResume(lifecycleOwner) // Then verify(exactly = 1) { scheduler.cancelPendingWork() } - confirmVerified(scheduler) + coVerify(exactly = 1) { mailSessionRepository.getMailSession().resumeWork() } + confirmVerified(mailSessionRepository, scheduler) } @Test - fun `should schedule background work when onStop is triggered`() { + fun `should schedule background execution and pause work when onStop is triggered`() { // Given coEvery { scheduler.scheduleWork() } just runs + every { mailSessionRepository.getMailSession().pauseWork() } just runs + // When observer.onStop(lifecycleOwner) // Then coVerify(exactly = 1) { scheduler.scheduleWork() } - confirmVerified(scheduler) + coVerify(exactly = 1) { mailSessionRepository.getMailSession().pauseWork() } + confirmVerified(mailSessionRepository, scheduler) } } diff --git a/mail-session/data/src/main/kotlin/ch/protonmail/android/mailsession/data/wrapper/MailSessionWrapper.kt b/mail-session/data/src/main/kotlin/ch/protonmail/android/mailsession/data/wrapper/MailSessionWrapper.kt index 3fccca3d2f..36e38d806e 100644 --- a/mail-session/data/src/main/kotlin/ch/protonmail/android/mailsession/data/wrapper/MailSessionWrapper.kt +++ b/mail-session/data/src/main/kotlin/ch/protonmail/android/mailsession/data/wrapper/MailSessionWrapper.kt @@ -149,6 +149,16 @@ class MailSessionWrapper(private val mailSession: MailSession) { fun startBackgroundTask(callback: BackgroundExecutionCallback) = mailSession.startBackgroundExecution(callback) + /** + * Used to pause work when the app is sent to the background. + */ + fun pauseWork() = mailSession.pauseWork() + + /** + * Used to resume work when the app is brought back to the foreground. + */ + fun resumeWork() = mailSession.resumeWork() + suspend fun newLoginFlow(): Either { return when (val result = mailSession.newLoginFlow()) { is MailSessionNewLoginFlowResult.Ok -> LoginFlowWrapper(result.v1).right()