Skip to content

Commit 797c007

Browse files
committed
Remove stopTripSession from ReplayRouteSession
1 parent 61415ea commit 797c007

File tree

9 files changed

+200
-112
lines changed

9 files changed

+200
-112
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
- Improved `startReplayTripSession` and `ReplayRouteSession` so that the previous trip session does not need to be stopped.

libnavigation-core/src/main/java/com/mapbox/navigation/core/replay/route/ReplayRouteSession.kt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,6 @@ class ReplayRouteSession : MapboxNavigationObserver {
106106
override fun onAttached(mapboxNavigation: MapboxNavigation) {
107107
this.replayRouteMapper = ReplayRouteMapper(options.replayRouteOptions)
108108
this.mapboxNavigation = mapboxNavigation
109-
mapboxNavigation.stopTripSession()
110109
mapboxNavigation.startReplayTripSession()
111110
mapboxNavigation.registerRouteProgressObserver(routeProgressObserver)
112111
mapboxNavigation.registerRoutesObserver(routesObserver)
@@ -139,7 +138,6 @@ class ReplayRouteSession : MapboxNavigationObserver {
139138
mapboxNavigation.mapboxReplayer.unregisterObserver(replayEventsObserver)
140139
mapboxNavigation.mapboxReplayer.stop()
141140
mapboxNavigation.mapboxReplayer.clearEvents()
142-
mapboxNavigation.stopTripSession()
143141
this.mapboxNavigation = null
144142
this.currentRoute = null
145143
}

libnavigation-core/src/main/java/com/mapbox/navigation/core/trip/session/MapboxTripSession.kt

Lines changed: 29 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,28 @@ internal class MapboxTripSession(
267267
}
268268
}
269269

270+
private val onRawLocationUpdate: (Location) -> Unit = { rawLocation ->
271+
val locationHash = rawLocation.hashCode()
272+
logD(
273+
"updateRawLocation; system elapsed time: ${System.nanoTime()}; " +
274+
"location ($locationHash) elapsed time: ${rawLocation.elapsedRealtimeNanos}",
275+
LOG_CATEGORY
276+
)
277+
this.rawLocation = rawLocation
278+
locationObservers.forEach { it.onNewRawLocation(rawLocation) }
279+
mainJobController.scope.launch(start = CoroutineStart.UNDISPATCHED) {
280+
logD(
281+
"updateRawLocation; notify navigator for ($locationHash) - start",
282+
LOG_CATEGORY
283+
)
284+
navigator.updateLocation(rawLocation.toFixLocation())
285+
logD(
286+
"updateRawLocation; notify navigator for ($locationHash) - end",
287+
LOG_CATEGORY
288+
)
289+
}
290+
}
291+
270292
init {
271293
navigator.setNativeNavigatorRecreationObserver {
272294
if (fallbackVersionsObservers.isNotEmpty()) {
@@ -297,39 +319,14 @@ internal class MapboxTripSession(
297319
* Start MapboxTripSession
298320
*/
299321
override fun start(withTripService: Boolean, withReplayEnabled: Boolean) {
300-
if (state == TripSessionState.STARTED) {
301-
return
302-
}
303-
navigator.addNavigatorObserver(navigatorObserver)
304-
if (withTripService) {
305-
tripService.startService()
306-
}
307-
tripSessionLocationEngine.startLocationUpdates(withReplayEnabled) {
308-
updateRawLocation(it)
309-
}
310-
state = TripSessionState.STARTED
311-
}
312-
313-
private fun updateRawLocation(rawLocation: Location) {
314-
val locationHash = rawLocation.hashCode()
315-
logD(
316-
"updateRawLocation; system elapsed time: ${System.nanoTime()}; " +
317-
"location ($locationHash) elapsed time: ${rawLocation.elapsedRealtimeNanos}",
318-
LOG_CATEGORY
319-
)
320-
this.rawLocation = rawLocation
321-
locationObservers.forEach { it.onNewRawLocation(rawLocation) }
322-
mainJobController.scope.launch(start = CoroutineStart.UNDISPATCHED) {
323-
logD(
324-
"updateRawLocation; notify navigator for ($locationHash) - start",
325-
LOG_CATEGORY
326-
)
327-
navigator.updateLocation(rawLocation.toFixLocation())
328-
logD(
329-
"updateRawLocation; notify navigator for ($locationHash) - end",
330-
LOG_CATEGORY
331-
)
322+
if (state != TripSessionState.STARTED) {
323+
navigator.addNavigatorObserver(navigatorObserver)
324+
if (withTripService) {
325+
tripService.startService()
326+
}
327+
state = TripSessionState.STARTED
332328
}
329+
tripSessionLocationEngine.startLocationUpdates(withReplayEnabled, onRawLocationUpdate)
333330
}
334331

335332
/**

libnavigation-core/src/main/java/com/mapbox/navigation/core/trip/session/TripSessionLocationEngine.kt

Lines changed: 31 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import android.annotation.SuppressLint
44
import android.location.Location
55
import android.os.Looper
66
import android.os.SystemClock
7+
import androidx.annotation.VisibleForTesting
78
import com.mapbox.android.core.location.LocationEngine
89
import com.mapbox.android.core.location.LocationEngineCallback
910
import com.mapbox.android.core.location.LocationEngineResult
@@ -24,55 +25,61 @@ import java.util.concurrent.TimeUnit
2425
* trip session is not using replay, use the [NavigationOptions.locationEngine].
2526
*/
2627
internal class TripSessionLocationEngine constructor(
27-
val navigationOptions: NavigationOptions
28+
private val navigationOptions: NavigationOptions,
29+
@VisibleForTesting
30+
private val replayLocationEngineProvider: (MapboxReplayer) -> LocationEngine = {
31+
ReplayLocationEngine(it)
32+
}
2833
) {
2934

3035
val mapboxReplayer: MapboxReplayer by lazy { MapboxReplayer() }
3136

32-
private val replayLocationEngine: ReplayLocationEngine by lazy {
33-
ReplayLocationEngine(mapboxReplayer)
37+
private val replayLocationEngine: LocationEngine by lazy {
38+
replayLocationEngineProvider.invoke(mapboxReplayer)
3439
}
35-
private var locationEngine: LocationEngine = navigationOptions.locationEngine
40+
private var activeLocationEngine: LocationEngine? = null
3641
private var onRawLocationUpdate: (Location) -> Unit = { }
3742

43+
private val locationEngineCallback = object : LocationEngineCallback<LocationEngineResult> {
44+
override fun onSuccess(result: LocationEngineResult?) {
45+
logD(LOG_CATEGORY) {
46+
"successful location engine callback $result"
47+
}
48+
result?.locations?.lastOrNull()?.let {
49+
logIfLocationIsNotFreshEnough(it)
50+
onRawLocationUpdate(it)
51+
}
52+
}
53+
54+
override fun onFailure(exception: Exception) {
55+
logD("location on failure exception=$exception", LOG_CATEGORY)
56+
}
57+
}
58+
3859
@SuppressLint("MissingPermission")
3960
fun startLocationUpdates(isReplayEnabled: Boolean, onRawLocationUpdate: (Location) -> Unit) {
4061
logD(LOG_CATEGORY) {
4162
"starting location updates for ${if (isReplayEnabled) "replay " else ""}location engine"
4263
}
64+
stopLocationUpdates()
4365
this.onRawLocationUpdate = onRawLocationUpdate
44-
val locationEngine = if (isReplayEnabled) {
66+
activeLocationEngine = if (isReplayEnabled) {
4567
replayLocationEngine
4668
} else {
4769
navigationOptions.locationEngine
4870
}
49-
locationEngine.requestLocationUpdates(
71+
activeLocationEngine?.requestLocationUpdates(
5072
navigationOptions.locationEngineRequest,
5173
locationEngineCallback,
5274
Looper.getMainLooper()
5375
)
54-
locationEngine.getLastLocation(locationEngineCallback)
76+
activeLocationEngine?.getLastLocation(locationEngineCallback)
5577
}
5678

5779
fun stopLocationUpdates() {
5880
onRawLocationUpdate = { }
59-
locationEngine.removeLocationUpdates(locationEngineCallback)
60-
}
61-
62-
private var locationEngineCallback = object : LocationEngineCallback<LocationEngineResult> {
63-
override fun onSuccess(result: LocationEngineResult?) {
64-
logD(LOG_CATEGORY) {
65-
"successful location engine callback $result"
66-
}
67-
result?.locations?.lastOrNull()?.let {
68-
logIfLocationIsNotFreshEnough(it)
69-
onRawLocationUpdate(it)
70-
}
71-
}
72-
73-
override fun onFailure(exception: Exception) {
74-
logD("location on failure exception=$exception", LOG_CATEGORY)
75-
}
81+
activeLocationEngine?.removeLocationUpdates(locationEngineCallback)
82+
activeLocationEngine = null
7683
}
7784

7885
private fun logIfLocationIsNotFreshEnough(location: Location) {
@@ -88,7 +95,6 @@ internal class TripSessionLocationEngine constructor(
8895
}
8996

9097
private companion object {
91-
9298
private const val DELAYED_LOCATION_WARNING_THRESHOLD_MS = 500 // 0.5s
9399
private const val LOG_CATEGORY = "TripSessionLocationEngine"
94100
}

libnavigation-core/src/test/java/com/mapbox/navigation/core/replay/route/ReplayRouteSessionTest.kt

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -84,17 +84,6 @@ class ReplayRouteSessionTest {
8484
unmockkAll()
8585
}
8686

87-
@Test
88-
fun `onAttached - should stop trip session and start replay session`() {
89-
sut.onAttached(mapboxNavigation)
90-
91-
verifyOrder {
92-
mapboxNavigation.stopTripSession()
93-
mapboxNavigation.startReplayTripSession()
94-
replayer.play()
95-
}
96-
}
97-
9887
@Test
9988
fun `onAttached - should reset trip session and replayer when navigation routes are cleared`() {
10089
val routesObserver = slot<RoutesObserver>()
@@ -139,13 +128,13 @@ class ReplayRouteSessionTest {
139128
}
140129

141130
@Test
142-
fun `onDetached - should stop trip session and replayer`() {
131+
fun `onDetached - should stop and clear the replayer`() {
143132
sut.onDetached(mapboxNavigation)
144133

145134
verifyOrder {
135+
replayer.unregisterObserver(any())
146136
replayer.stop()
147137
replayer.clearEvents()
148-
mapboxNavigation.stopTripSession()
149138
}
150139
}
151140

@@ -251,7 +240,6 @@ class ReplayRouteSessionTest {
251240
)
252241

253242
verifyOrder {
254-
mapboxNavigation.stopTripSession()
255243
mapboxNavigation.startReplayTripSession()
256244
replayer.play()
257245
replayer.pushEvents(any())

libnavigation-core/src/test/java/com/mapbox/navigation/core/trip/session/MapboxTripSessionTest.kt

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ import com.mapbox.navigator.RouteAlternative
4242
import com.mapbox.navigator.RouteState
4343
import com.mapbox.navigator.SetRoutesReason
4444
import com.mapbox.navigator.SetRoutesResult
45+
import io.mockk.Ordering
4546
import io.mockk.Runs
4647
import io.mockk.clearMocks
4748
import io.mockk.coEvery
@@ -238,18 +239,42 @@ class MapboxTripSessionTest {
238239
@Test
239240
fun startSessionWithTripServiceCallStartAgain() {
240241
tripSession.start(true)
241-
242242
tripSession.start(false)
243-
244243
every { tripService.hasServiceStarted() } returns true
245-
246244
assertTrue(tripSession.isRunningWithForegroundService())
247-
verify(exactly = 1) { tripService.startService() }
248-
verify(exactly = 1) { tripSessionLocationEngine.startLocationUpdates(any(), any()) }
245+
tripSession.stop()
249246

247+
verifyOrder {
248+
navigator.addNavigatorObserver(any())
249+
tripService.startService()
250+
tripSessionLocationEngine.startLocationUpdates(any(), any())
251+
tripSessionLocationEngine.startLocationUpdates(any(), any())
252+
navigator.removeNavigatorObserver(any())
253+
tripSession.stop()
254+
tripSessionLocationEngine.stopLocationUpdates()
255+
}
256+
}
257+
258+
@Test
259+
fun startSessionWithReplayCallStartAgain() {
260+
tripSession.start(true, withReplayEnabled = false)
261+
tripSession.start(true, withReplayEnabled = true)
262+
tripSession.start(true, withReplayEnabled = false)
250263
tripSession.stop()
264+
265+
verifyOrder {
266+
navigator.addNavigatorObserver(any())
267+
tripService.startService()
268+
tripSessionLocationEngine.startLocationUpdates(false, any())
269+
tripSessionLocationEngine.startLocationUpdates(true, any())
270+
tripSessionLocationEngine.startLocationUpdates(false, any())
271+
navigator.removeNavigatorObserver(any())
272+
tripSession.stop()
273+
tripSessionLocationEngine.stopLocationUpdates()
274+
}
251275
}
252276

277+
253278
@Test
254279
fun stopSessionCallsTripServiceStopService() {
255280
tripSession.start(true)

0 commit comments

Comments
 (0)