diff --git a/libnavigation-core/src/main/java/com/mapbox/navigation/core/telemetry/MapboxNavigationTelemetry.kt b/libnavigation-core/src/main/java/com/mapbox/navigation/core/telemetry/MapboxNavigationTelemetry.kt index 840f9ab4aa9..2f227867267 100644 --- a/libnavigation-core/src/main/java/com/mapbox/navigation/core/telemetry/MapboxNavigationTelemetry.kt +++ b/libnavigation-core/src/main/java/com/mapbox/navigation/core/telemetry/MapboxNavigationTelemetry.kt @@ -15,6 +15,7 @@ import com.mapbox.navigation.base.metrics.MetricsReporter import com.mapbox.navigation.base.options.NavigationOptions import com.mapbox.navigation.base.trip.model.RouteLegProgress import com.mapbox.navigation.base.trip.model.RouteProgress +import com.mapbox.navigation.base.trip.model.RouteProgressState import com.mapbox.navigation.core.BuildConfig import com.mapbox.navigation.core.MapboxNavigation import com.mapbox.navigation.core.arrival.ArrivalObserver @@ -93,18 +94,31 @@ private data class SessionMetadata( * @param timeOfReroute time of reroute. Unit is **time in millis**. * @param timeSinceLastReroute time since last reroute. Unit is **millis**. * @param driverModeArrivalTime arrival time of driver mode + * @param currentDistanceTraveled for the active session */ private data class DynamicSessionValues( var rerouteCount: Int = 0, var timeOfReroute: Long = 0L, var timeSinceLastReroute: Int = 0, var driverModeArrivalTime: Date? = null, + var currentDistanceTraveled: Int = 0, + var accumulatedDistanceTraveled: Int = 0, ) { fun reset() { rerouteCount = 0 timeOfReroute = 0 timeSinceLastReroute = 0 driverModeArrivalTime = null + currentDistanceTraveled = 0 + accumulatedDistanceTraveled = 0 + } + + fun accumulateDistanceTraveled(distance: Int) { + accumulatedDistanceTraveled += distance + } + + fun resetCurrentDistanceTraveled() { + currentDistanceTraveled = 0 } } @@ -289,6 +303,16 @@ internal object MapboxNavigationTelemetry { private val routeProgressObserver = RouteProgressObserver { routeProgress -> this.routeData.routeProgress = routeProgress + val dynamicValues = getSessionMetadataIfTelemetryRunning()?.dynamicValues + if (routeProgress.currentState == RouteProgressState.OFF_ROUTE) { + dynamicValues?.accumulateDistanceTraveled( + routeProgress.distanceTraveled.toInt() + ) + dynamicValues?.resetCurrentDistanceTraveled() + } else { + dynamicValues?.currentDistanceTraveled = + routeProgress.distanceTraveled.toInt() + } } private val onRouteDataChanged: () -> Unit = { @@ -480,6 +504,8 @@ internal object MapboxNavigationTelemetry { this.feedbackSubType = feedbackSubType this.locationsBefore = feedbackMetadata.locationsBeforeEvent this.locationsAfter = feedbackMetadata.locationsAfterEvent + val distanceTraveled = + getSessionMetadataIfTelemetryRunning()?.dynamicValues.retrieveDistanceTraveled() populate( this@MapboxNavigationTelemetry.sdkIdentifier, null, @@ -493,6 +519,7 @@ internal object MapboxNavigationTelemetry { feedbackMetadata.driverMode, feedbackMetadata.driverModeStartTime, feedbackMetadata.rerouteCount, + distanceTraveled, feedbackMetadata.eventVersion, feedbackMetadata.appMetadata, ) @@ -727,6 +754,7 @@ internal object MapboxNavigationTelemetry { } private fun NavigationEvent.populateWithLocalVars(sessionMetadata: SessionMetadata?) { + val distanceTraveled = sessionMetadata?.dynamicValues.retrieveDistanceTraveled() this.populate( this@MapboxNavigationTelemetry.sdkIdentifier, routeData.originalRoute, @@ -740,11 +768,18 @@ internal object MapboxNavigationTelemetry { sessionMetadata?.telemetryNavSessionState?.getModeName(), sessionMetadata?.driverModeStartTime?.let { generateCreateDateFormatted(it) }, sessionMetadata?.dynamicValues?.rerouteCount, + distanceTraveled, EVENT_VERSION, createAppMetadata() ) } + private fun DynamicSessionValues?.retrieveDistanceTraveled(): Int { + val currentDistanceTraveled = this?.currentDistanceTraveled ?: 0 + val accumulatedDistanceTraveled = this?.accumulatedDistanceTraveled ?: 0 + return currentDistanceTraveled + accumulatedDistanceTraveled + } + private fun NavigationFreeDriveEvent.populate( type: FreeDriveEventType, navSessionIdentifier: String, diff --git a/libnavigation-core/src/main/java/com/mapbox/navigation/core/telemetry/NavEventsPopulateUtil.kt b/libnavigation-core/src/main/java/com/mapbox/navigation/core/telemetry/NavEventsPopulateUtil.kt index 0c073319c8a..31f84eb0e1c 100644 --- a/libnavigation-core/src/main/java/com/mapbox/navigation/core/telemetry/NavEventsPopulateUtil.kt +++ b/libnavigation-core/src/main/java/com/mapbox/navigation/core/telemetry/NavEventsPopulateUtil.kt @@ -28,6 +28,7 @@ import com.mapbox.navigation.utils.internal.logD * @param driverModeStartTime driver mode start time. * Use [TelemetryUtils.generateCreateDateFormatted] * @param rerouteCount reroute count + * @param distanceTraveled accumulated for the session * @param eventVersion events version [MapboxNavigationTelemetry.EVENT_VERSION] * @param appMetadata use [MapboxNavigationTelemetry.createAppMetadata] */ @@ -44,6 +45,7 @@ internal fun NavigationEvent.populate( @FeedbackEvent.DriverMode driverMode: String?, driverModeStartTime: String?, rerouteCount: Int?, + distanceTraveled: Int, eventVersion: Int, appMetadata: AppMetadata?, ) { @@ -56,7 +58,7 @@ internal fun NavigationEvent.populate( distanceRemaining = routeProgressNonNull.distanceRemaining.toInt() durationRemaining = routeProgressNonNull.durationRemaining.toInt() - distanceCompleted = routeProgressNonNull.distanceTraveled.toInt() + distanceCompleted = distanceTraveled routeProgressNonNull.route.let { geometry = it.geometry() diff --git a/libnavigation-core/src/test/java/com/mapbox/navigation/core/telemetry/MapboxNavigationTelemetryTest.kt b/libnavigation-core/src/test/java/com/mapbox/navigation/core/telemetry/MapboxNavigationTelemetryTest.kt index 0cd56ad3786..7e05a6a41ed 100644 --- a/libnavigation-core/src/test/java/com/mapbox/navigation/core/telemetry/MapboxNavigationTelemetryTest.kt +++ b/libnavigation-core/src/test/java/com/mapbox/navigation/core/telemetry/MapboxNavigationTelemetryTest.kt @@ -21,6 +21,7 @@ import com.mapbox.navigation.base.metrics.MetricEvent import com.mapbox.navigation.base.options.NavigationOptions import com.mapbox.navigation.base.trip.model.RouteLegProgress import com.mapbox.navigation.base.trip.model.RouteProgress +import com.mapbox.navigation.base.trip.model.RouteProgressState.OFF_ROUTE import com.mapbox.navigation.base.trip.model.RouteProgressState.TRACKING import com.mapbox.navigation.base.trip.model.RouteStepProgress import com.mapbox.navigation.core.MapboxNavigation @@ -708,6 +709,33 @@ class MapboxNavigationTelemetryTest { checkEventsInSameSession(events) } + @Test + fun rerouteEvent_accumulates_distance_traveled_on_offRoute() { + baseMock() + mockAnotherRoute() + mockRouteProgress() + + baseInitialization() + updateRoute(anotherRoute, RoutesExtra.ROUTES_UPDATE_REASON_REROUTE) + locationsCollector.flushBuffers() + every { routeProgress.currentState } returns OFF_ROUTE + updateRouteProgress(count = 1) + every { routeProgress.currentState } returns TRACKING + updateRouteProgress(count = 1) + updateRoute(anotherRoute, RoutesExtra.ROUTES_UPDATE_REASON_REROUTE) + locationsCollector.flushBuffers() + + val events = captureAndVerifyMetricsReporter(exactly = 4) + assertTrue(events[0] is NavigationAppUserTurnstileEvent) + assertTrue(events[1] is NavigationDepartEvent) + assertTrue(events[2] is NavigationRerouteEvent) + assertTrue(events[3] is NavigationRerouteEvent) + assertEquals( + (ROUTE_PROGRESS_DISTANCE_TRAVELED * 2).toInt(), + (events[3] as NavigationRerouteEvent).distanceCompleted + ) + } + @Test fun departEvent_populated_correctly() { baseMock() @@ -717,6 +745,7 @@ class MapboxNavigationTelemetryTest { val departEvent = events[1] as NavigationDepartEvent checkOriginalParams(departEvent, originalRoute) + assertEquals(0, departEvent.distanceCompleted) } @Test @@ -733,6 +762,7 @@ class MapboxNavigationTelemetryTest { val rerouteEvent = events[2] as NavigationRerouteEvent checkOriginalParams(rerouteEvent, anotherRoute) + assertEquals(routeProgress.distanceTraveled.toInt(), rerouteEvent.distanceCompleted) } @Test @@ -1449,7 +1479,6 @@ class MapboxNavigationTelemetryTest { ) assertEquals(routeProgress.distanceRemaining.toInt(), event.distanceRemaining) assertEquals(routeProgress.durationRemaining.toInt(), event.durationRemaining) - assertEquals(routeProgress.distanceTraveled.toInt(), event.distanceCompleted) assertEquals(currentRoute.geometry(), event.geometry) assertEquals(currentRoute.routeOptions()?.profile(), event.profile) assertEquals(currentRoute.routeIndex()?.toInt(), event.legIndex)