summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/compose/NavControllerWrapper.kt20
-rw-r--r--packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/framework/compose/NavControllerWrapperTest.kt105
-rw-r--r--packages/SettingsLib/Spa/testutils/src/com/android/settingslib/spa/testutils/FakeNavControllerWrapper.kt2
3 files changed, 120 insertions, 7 deletions
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/compose/NavControllerWrapper.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/compose/NavControllerWrapper.kt
index eb2bffe0e4fd..1aa207900dd2 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/compose/NavControllerWrapper.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/compose/NavControllerWrapper.kt
@@ -25,7 +25,7 @@ import androidx.compose.runtime.remember
import androidx.navigation.NavHostController
interface NavControllerWrapper {
- fun navigate(route: String)
+ fun navigate(route: String, popUpCurrent: Boolean = false)
fun navigateBack()
val highlightEntryId: String?
@@ -48,17 +48,17 @@ fun NavHostController.localNavController(): ProvidedValue<NavControllerWrapper>
val LocalNavController = compositionLocalOf<NavControllerWrapper> {
object : NavControllerWrapper {
- override fun navigate(route: String) {}
+ override fun navigate(route: String, popUpCurrent: Boolean) {}
override fun navigateBack() {}
}
}
@Composable
-fun navigator(route: String?): () -> Unit {
+fun navigator(route: String?, popUpCurrent: Boolean = false): () -> Unit {
if (route == null) return {}
val navController = LocalNavController.current
- return { navController.navigate(route) }
+ return { navController.navigate(route, popUpCurrent) }
}
internal class NavControllerWrapperImpl(
@@ -68,8 +68,16 @@ internal class NavControllerWrapperImpl(
var highlightId: String? = null
var sessionName: String? = null
- override fun navigate(route: String) {
- navController.navigate(route)
+ override fun navigate(route: String, popUpCurrent: Boolean) {
+ navController.navigate(route) {
+ if (popUpCurrent) {
+ navController.currentDestination?.let { currentDestination ->
+ popUpTo(currentDestination.id) {
+ inclusive = true
+ }
+ }
+ }
+ }
}
override fun navigateBack() {
diff --git a/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/framework/compose/NavControllerWrapperTest.kt b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/framework/compose/NavControllerWrapperTest.kt
new file mode 100644
index 000000000000..118585efeb3f
--- /dev/null
+++ b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/framework/compose/NavControllerWrapperTest.kt
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.spa.framework.compose
+
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.CompositionLocalProvider
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.ui.test.assertIsDisplayed
+import androidx.compose.ui.test.hasText
+import androidx.compose.ui.test.junit4.createComposeRule
+import androidx.compose.ui.test.onNodeWithText
+import androidx.navigation.compose.NavHost
+import androidx.navigation.compose.composable
+import androidx.navigation.compose.rememberNavController
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.android.settingslib.spa.testutils.waitUntilExists
+import kotlinx.coroutines.delay
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+class NavControllerWrapperTest {
+ @get:Rule
+ val composeTestRule = createComposeRule()
+
+ @Test
+ fun navigate_canNavigate() {
+ composeTestRule.setContent {
+ TestNavHost {
+ LocalNavController.current.navigate(ROUTE_B)
+ }
+ }
+
+ composeTestRule.onNodeWithText(ROUTE_B).assertIsDisplayed()
+ }
+
+ @Test
+ fun navigate_canNavigateBack() {
+ composeTestRule.setContent {
+ TestNavHost {
+ val navController = LocalNavController.current
+ LaunchedEffect(Unit) {
+ navController.navigate(ROUTE_B)
+ delay(100)
+ navController.navigateBack()
+ }
+ }
+ }
+
+ composeTestRule.waitUntilExists(hasText(ROUTE_A))
+ }
+
+ @Test
+ fun navigate_canNavigateAndPopUpCurrent() {
+ composeTestRule.setContent {
+ TestNavHost {
+ val navController = LocalNavController.current
+ LaunchedEffect(Unit) {
+ navController.navigate(ROUTE_B)
+ delay(100)
+ navController.navigate(ROUTE_C, popUpCurrent = true)
+ delay(100)
+ navController.navigateBack()
+ }
+ }
+ }
+
+ composeTestRule.waitUntilExists(hasText(ROUTE_A))
+ }
+
+ private companion object {
+ @Composable
+ fun TestNavHost(content: @Composable () -> Unit) {
+ val navController = rememberNavController()
+ CompositionLocalProvider(navController.localNavController()) {
+ NavHost(navController, ROUTE_A) {
+ composable(route = ROUTE_A) { Text(ROUTE_A) }
+ composable(route = ROUTE_B) { Text(ROUTE_B) }
+ composable(route = ROUTE_C) { Text(ROUTE_C) }
+ }
+ content()
+ }
+ }
+
+ const val ROUTE_A = "RouteA"
+ const val ROUTE_B = "RouteB"
+ const val ROUTE_C = "RouteC"
+ }
+}
diff --git a/packages/SettingsLib/Spa/testutils/src/com/android/settingslib/spa/testutils/FakeNavControllerWrapper.kt b/packages/SettingsLib/Spa/testutils/src/com/android/settingslib/spa/testutils/FakeNavControllerWrapper.kt
index 5a3044d5ef84..f289d0d8d465 100644
--- a/packages/SettingsLib/Spa/testutils/src/com/android/settingslib/spa/testutils/FakeNavControllerWrapper.kt
+++ b/packages/SettingsLib/Spa/testutils/src/com/android/settingslib/spa/testutils/FakeNavControllerWrapper.kt
@@ -25,7 +25,7 @@ class FakeNavControllerWrapper : NavControllerWrapper {
var navigateCalledWith: String? = null
var navigateBackIsCalled = false
- override fun navigate(route: String) {
+ override fun navigate(route: String, popUpCurrent: Boolean) {
navigateCalledWith = route
}