diff --git a/app/src/main/java/org/mozilla/fenix/HomeActivity.kt b/app/src/main/java/org/mozilla/fenix/HomeActivity.kt index 13e8b7cac..e7d548ae2 100644 --- a/app/src/main/java/org/mozilla/fenix/HomeActivity.kt +++ b/app/src/main/java/org/mozilla/fenix/HomeActivity.kt @@ -107,6 +107,7 @@ open class HomeActivity : LocaleAwareAppCompatActivity() { private var isVisuallyComplete = false private var visualCompletenessQueue: RunWhenReadyQueue? = null + private var privateNotificationObserver: NotificationSessionObserver? = null private var isToolbarInflated = false @@ -156,8 +157,9 @@ open class HomeActivity : LocaleAwareAppCompatActivity() { sessionObserver = UriOpenedObserver(this) checkPrivateShortcutEntryPoint(intent) - val privateNotificationObserver = NotificationSessionObserver(this) - privateNotificationObserver.start() + privateNotificationObserver = NotificationSessionObserver(applicationContext).also { + it.start() + } if (isActivityColdStarted(intent, savedInstanceState)) { externalSourceIntentProcessors.any { it.process(intent, navHost.navController, this.intent) } @@ -218,6 +220,11 @@ open class HomeActivity : LocaleAwareAppCompatActivity() { BrowsersCache.resetAll() } + override fun onDestroy() { + super.onDestroy() + privateNotificationObserver?.stop() + } + /** * Handles intents received when the activity is open. */ diff --git a/app/src/main/java/org/mozilla/fenix/session/NotificationSessionObserver.kt b/app/src/main/java/org/mozilla/fenix/session/NotificationSessionObserver.kt index 456789cb6..7b6f49410 100644 --- a/app/src/main/java/org/mozilla/fenix/session/NotificationSessionObserver.kt +++ b/app/src/main/java/org/mozilla/fenix/session/NotificationSessionObserver.kt @@ -20,25 +20,22 @@ import org.mozilla.fenix.ext.components * indicating that a private tab is open. */ class NotificationSessionObserver( - private val context: Context, + private val applicationContext: Context, private val notificationService: SessionNotificationService.Companion = SessionNotificationService ) { private var scope: CoroutineScope? = null - private var started = false @ExperimentalCoroutinesApi fun start() { - scope = context.components.core.store.flowScoped { flow -> + scope = applicationContext.components.core.store.flowScoped { flow -> flow.map { state -> state.privateTabs.isNotEmpty() } .ifChanged() .collect { hasPrivateTabs -> if (hasPrivateTabs) { - notificationService.start(context, isStartedFromPrivateShortcut) - started = true - } else if (started) { - notificationService.stop(context) - started = false + notificationService.start(applicationContext, isStartedFromPrivateShortcut) + } else if (SessionNotificationService.started) { + notificationService.stop(applicationContext) } } } diff --git a/app/src/main/java/org/mozilla/fenix/session/SessionNotificationService.kt b/app/src/main/java/org/mozilla/fenix/session/SessionNotificationService.kt index ea9049c93..e85411b20 100644 --- a/app/src/main/java/org/mozilla/fenix/session/SessionNotificationService.kt +++ b/app/src/main/java/org/mozilla/fenix/session/SessionNotificationService.kt @@ -138,6 +138,7 @@ class SessionNotificationService : Service() { private const val ACTION_START = "start" private const val ACTION_ERASE = "erase" + internal var started = false internal fun start( context: Context, @@ -154,6 +155,8 @@ class SessionNotificationService : Service() { ThreadUtils.postToMainThread(Runnable { context.startService(intent) }) + + started = true } internal fun stop(context: Context) { @@ -164,6 +167,8 @@ class SessionNotificationService : Service() { ThreadUtils.postToMainThread(Runnable { context.stopService(intent) }) + + started = false } } } diff --git a/app/src/test/java/org/mozilla/fenix/session/NotificationSessionObserverTest.kt b/app/src/test/java/org/mozilla/fenix/session/NotificationSessionObserverTest.kt index aa313ec15..87d462ecf 100644 --- a/app/src/test/java/org/mozilla/fenix/session/NotificationSessionObserverTest.kt +++ b/app/src/test/java/org/mozilla/fenix/session/NotificationSessionObserverTest.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.session import android.content.Context diff --git a/app/src/test/java/org/mozilla/fenix/session/SessionNotificationServiceTest.kt b/app/src/test/java/org/mozilla/fenix/session/SessionNotificationServiceTest.kt new file mode 100644 index 000000000..2a9e5bccd --- /dev/null +++ b/app/src/test/java/org/mozilla/fenix/session/SessionNotificationServiceTest.kt @@ -0,0 +1,27 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package org.mozilla.fenix.session + +import mozilla.components.support.test.robolectric.testContext +import org.junit.Assert.assertFalse +import org.junit.Assert.assertTrue +import org.junit.Test +import org.junit.runner.RunWith +import org.mozilla.fenix.helpers.FenixRobolectricTestRunner + +@RunWith(FenixRobolectricTestRunner::class) +class SessionNotificationServiceTest { + + @Test + fun `Service keeps tracked of started state`() { + assertFalse(SessionNotificationService.started) + + SessionNotificationService.start(testContext, false) + assertTrue(SessionNotificationService.started) + + SessionNotificationService.stop(testContext) + assertFalse(SessionNotificationService.started) + } +}