Skip to content

Commit a955f5b

Browse files
committed
NAVAND-1158: ignore old alternatives
1 parent c3b1612 commit a955f5b

3 files changed

Lines changed: 112 additions & 24 deletions

File tree

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
- Fixed a rare race condition where the alternative routes might have not been in sync with the current primary route.

libnavigation-core/src/main/java/com/mapbox/navigation/core/MapboxNavigation.kt

Lines changed: 39 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1044,33 +1044,48 @@ class MapboxNavigation @VisibleForTesting internal constructor(
10441044
restartRouteRefreshScope()
10451045
threadController.getMainScopeAndRootJob().scope.launch(Dispatchers.Main.immediate) {
10461046
routeUpdateMutex.withLock {
1047-
historyRecordingStateHandler.setRoutes(routes)
10481047
val routesSetResult: Expected<RoutesSetError, RoutesSetSuccess>
1049-
when (val processedRoutes = setRoutesToTripSession(routes, setRoutesInfo)) {
1050-
is NativeSetRouteValue -> {
1051-
val directionsSessionRoutes = Utils.createDirectionsSessionRoutes(
1052-
routes,
1053-
processedRoutes,
1054-
setRoutesInfo
1048+
if (
1049+
setRoutesInfo is SetRoutes.Alternatives &&
1050+
routes.first().id != directionsSession.routes.firstOrNull()?.id
1051+
) {
1052+
routesSetResult = ExpectedFactory.createError(
1053+
RoutesSetError(
1054+
"Alternatives ${routes.drop(1).map { it.id }} " +
1055+
"are outdated. Primary route has changed " +
1056+
"from ${routes.first().id} " +
1057+
"to ${directionsSession.routes.firstOrNull()?.id}"
10551058
)
1056-
directionsSession.setRoutes(directionsSessionRoutes)
1057-
routesSetResult = ExpectedFactory.createValue(
1058-
RoutesSetSuccess(
1059-
directionsSessionRoutes.ignoredRoutes.associate {
1060-
it.navigationRoute.id to RoutesSetError("invalid alternative")
1061-
}
1059+
)
1060+
} else {
1061+
historyRecordingStateHandler.setRoutes(routes)
1062+
when (val processedRoutes = setRoutesToTripSession(routes, setRoutesInfo)) {
1063+
is NativeSetRouteValue -> {
1064+
val directionsSessionRoutes = Utils.createDirectionsSessionRoutes(
1065+
routes,
1066+
processedRoutes,
1067+
setRoutesInfo
10621068
)
1063-
)
1064-
}
1065-
is NativeSetRouteError -> {
1066-
logE(
1067-
"Routes with IDs ${routes.map { it.id }} " +
1068-
"will be ignored as they are not valid"
1069-
)
1070-
routesSetResult = ExpectedFactory.createError(
1071-
RoutesSetError(processedRoutes.error)
1072-
)
1073-
historyRecordingStateHandler.lastSetRoutesFailed()
1069+
directionsSession.setRoutes(directionsSessionRoutes)
1070+
routesSetResult = ExpectedFactory.createValue(
1071+
RoutesSetSuccess(
1072+
directionsSessionRoutes.ignoredRoutes.associate {
1073+
it.navigationRoute.id to
1074+
RoutesSetError("invalid alternative")
1075+
}
1076+
)
1077+
)
1078+
}
1079+
is NativeSetRouteError -> {
1080+
logE(
1081+
"Routes with IDs ${routes.map { it.id }} " +
1082+
"will be ignored as they are not valid"
1083+
)
1084+
routesSetResult = ExpectedFactory.createError(
1085+
RoutesSetError(processedRoutes.error)
1086+
)
1087+
historyRecordingStateHandler.lastSetRoutesFailed()
1088+
}
10741089
}
10751090
}
10761091
callback?.onRoutesSet(routesSetResult)

libnavigation-core/src/test/java/com/mapbox/navigation/core/MapboxNavigationTest.kt

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1746,6 +1746,78 @@ internal class MapboxNavigationTest : MapboxNavigationBaseTest() {
17461746
}
17471747
}
17481748

1749+
@Test
1750+
fun `setNavigationRoutes alternative for current primary route`() = coroutineRule.runBlockingTest {
1751+
createMapboxNavigation()
1752+
val route1 = mockk<NavigationRoute>(relaxed = true) {
1753+
every { id } returns "id1"
1754+
}
1755+
val route2 = mockk<NavigationRoute>(relaxed = true) {
1756+
every { id } returns "id2"
1757+
}
1758+
val route3 = mockk<NavigationRoute>(relaxed = true) {
1759+
every { id } returns "id3"
1760+
}
1761+
every { directionsSession.routes } returns listOf(route1, route2)
1762+
1763+
mapboxNavigation.setNavigationRoutes(listOf(route1, route3))
1764+
1765+
coVerify(exactly = 1) {
1766+
tripSession.setRoutes(any(), ofType(SetRoutes.Alternatives::class))
1767+
}
1768+
verify(exactly = 1) {
1769+
directionsSession.setRoutes(any())
1770+
}
1771+
}
1772+
1773+
@Test
1774+
fun `setNavigationRoutes new routes`() = coroutineRule.runBlockingTest {
1775+
createMapboxNavigation()
1776+
val route1 = mockk<NavigationRoute>(relaxed = true) {
1777+
every { id } returns "id1"
1778+
}
1779+
val route2 = mockk<NavigationRoute>(relaxed = true) {
1780+
every { id } returns "id2"
1781+
}
1782+
val route3 = mockk<NavigationRoute>(relaxed = true) {
1783+
every { id } returns "id3"
1784+
}
1785+
every { directionsSession.routes } returns listOf(route1, route2)
1786+
1787+
mapboxNavigation.setNavigationRoutes(listOf(route3, route2))
1788+
1789+
coVerify(exactly = 1) {
1790+
tripSession.setRoutes(any(), ofType(SetRoutes.NewRoutes::class))
1791+
}
1792+
verify(exactly = 1) {
1793+
directionsSession.setRoutes(any())
1794+
}
1795+
}
1796+
1797+
@Test
1798+
fun `setNavigationRoutes alternative for outdated primary route`() = coroutineRule.runBlockingTest {
1799+
createMapboxNavigation()
1800+
val route1 = mockk<NavigationRoute>(relaxed = true) {
1801+
every { id } returns "id1"
1802+
}
1803+
val route2 = mockk<NavigationRoute>(relaxed = true) {
1804+
every { id } returns "id2"
1805+
}
1806+
val route3 = mockk<NavigationRoute>(relaxed = true) {
1807+
every { id } returns "id3"
1808+
}
1809+
every { directionsSession.routes } returnsMany listOf(listOf(route1), listOf(route2))
1810+
1811+
mapboxNavigation.setNavigationRoutes(listOf(route1, route3))
1812+
1813+
coVerify(exactly = 0) {
1814+
tripSession.setRoutes(any(), any())
1815+
}
1816+
verify(exactly = 0) {
1817+
directionsSession.setRoutes(any())
1818+
}
1819+
}
1820+
17491821
@Test
17501822
fun `refreshed route is set to trip session and directions session`() =
17511823
coroutineRule.runBlockingTest {

0 commit comments

Comments
 (0)