Skip to content

Commit 93a4c44

Browse files
Pablo Guardioladzinad
andauthored
Backport Copilot feature to release-v2.8 (#6791)
* add copilot options to navigation options (#6387) * cherry-pick #6456 * fix changelog and metalava * NAVAND-750: introduce HistoryRecordingSessionState * invoke HistoryRecordingStateChangeObserver#onShouldStartRecording with current state * [NOT WORKING] HistoryRecorderHandle.buildCompositeRecorder is missing from NN 115.0.1 as it was introduced as part of NN v119 add multiple history recorders support (needed for copilot) (#6509) * bump nn dependency version to 115.1.0 * add copilot feature (#6572) * remove libtesting-navigation-util test implementation dependency not available anymore causing building issues * follow up to improve copilot kdocs (#6591) * use mapbox navigation app lifecycle owner instead of process lifecycle owner to support android auto and remove android x lifecycle process dependency not necessary anymore (#6609) * [copilot] start recording as soon as on should start recording is called to include deferred events as part of the current history file session (#6655) * [copilot] make sure created from attachments api is the same as startedAt (#6660) * use either mapbox navigation app lifecycle owner or process lifecycle owner based on if mapbox navigation app is set up or not respectively to support both use cases in which mapbox navigation app is or is not integrated from the client side and add is copilot initialized check to prevent issues if apis are misused (#6690) * fix conflicts * fix mapbox copilot impl failing tests * fix changelog * fix merge conflict Co-authored-by: Dzina Dybouskaya <32109537+dzinad@users.noreply.github.com> Co-authored-by: Dzina Dybouskaya <dzina.dybouskaya@mapbox.com>
1 parent ecd64de commit 93a4c44

77 files changed

Lines changed: 5998 additions & 252 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ Mapbox welcomes participation and contributions from everyone.
44

55
## Unreleased
66
#### Features
7+
- Added public-preview Copilot feature. [#6791](https://github.com/mapbox/mapbox-navigation-android/pull/6791)
78
#### Bug fixes and improvements
9+
- Ensure map-matching considers HOV-only roads as auto accessible. [#6791](https://github.com/mapbox/mapbox-navigation-android/pull/6791)
810

911
## Mapbox Navigation SDK 2.8.1 - 13 December, 2022
1012
### Changelog

Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ libnavigation-util \
66
libnavigator \
77
libtrip-notification \
88
libnavigation-core \
9+
libnavigation-copilot \
910

1011
CORE_MODULES = $(RELEASED_CORE_MODULES)
1112

@@ -123,6 +124,7 @@ core-check-api: assemble-core-release
123124
./gradlew :libnavigator:checkApi -PhidePackage=com.mapbox.navigation.navigator.internal
124125
./gradlew :libtrip-notification:checkApi -PhidePackage=com.mapbox.navigation.trip.notification.internal
125126
./gradlew :libnavigation-core:checkApi -PhidePackage=com.mapbox.navigation.core.internal
127+
./gradlew :libnavigation-copilot:checkApi -PhidePackage=com.mapbox.navigation.copilot.internal
126128

127129
.PHONY: core-update-api
128130
core-update-api: assemble-core-release
@@ -133,6 +135,7 @@ core-update-api: assemble-core-release
133135
./gradlew :libnavigator:updateApi -PhidePackage=com.mapbox.navigation.navigator.internal
134136
./gradlew :libtrip-notification:updateApi -PhidePackage=com.mapbox.navigation.trip.notification.internal
135137
./gradlew :libnavigation-core:updateApi -PhidePackage=com.mapbox.navigation.core.internal
138+
./gradlew :libnavigation-copilot:updateApi -PhidePackage=com.mapbox.navigation.copilot.internal
136139

137140
.PHONY: assemble-ui-debug
138141
assemble-ui-debug:

gradle/dependencies.gradle

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ ext {
1313
// version which we should use in this build
1414
def mapboxNavigatorVersion = System.getenv("FORCE_MAPBOX_NAVIGATION_NATIVE_VERSION")
1515
if (mapboxNavigatorVersion == null || mapboxNavigatorVersion == '') {
16-
mapboxNavigatorVersion = '115.0.1'
16+
mapboxNavigatorVersion = '115.1.0'
1717
}
1818
println("Navigation Native version: " + mapboxNavigatorVersion)
1919

@@ -37,6 +37,7 @@ ext {
3737
androidXAnnotationVersion : '1.2.0',
3838
androidXFragmentVersion : '1.4.0',
3939
androidXDataStore : '1.0.0',
40+
androidXWorkManager : '2.7.1',
4041
cardViewVersion : '1.0.0',
4142
recyclerViewVersion : '1.1.0',
4243
materialDesignVersion : '1.1.0',
@@ -134,11 +135,13 @@ ext {
134135
androidXFragment : "androidx.fragment:fragment-ktx:${version.androidXFragmentVersion}",
135136
androidXArchCoreTesting : "androidx.arch.core:core-testing:${version.androidXArchCoreVersion}",
136137
androidXDataStore : "androidx.datastore:datastore-preferences:${version.androidXDataStore}",
138+
androidXWorkManager : "androidx.work:work-runtime-ktx:${version.androidXWorkManager}",
137139

138140
// lifecycle
139141
androidXLifecycleRuntime : "androidx.lifecycle:lifecycle-runtime-ktx:${version.androidXLifecycle}",
140142
androidXLifecycleLivedata : "androidx.lifecycle:lifecycle-livedata-ktx:${version.androidXLifecycle}",
141143
androidXLifecycleViewmodel: "androidx.lifecycle:lifecycle-viewmodel-ktx:${version.androidXLifecycle}",
144+
androidXLifecycleProcess : "androidx.lifecycle:lifecycle-process:${version.androidXLifecycle}",
142145
androidXLifecycleTesting : "androidx.lifecycle:lifecycle-runtime-testing:${version.androidXLifecycle}",
143146

144147
// square crew

gradle/publish.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ def sdkNameMap = [:]
5353
sdkNameMap["libnavigation-android"] = "mobile-navigation-android"
5454
sdkNameMap["libnavigation-base"] = "mobile-navigation-base"
5555
sdkNameMap["libnavigation-core"] = "mobile-navigation-core"
56+
sdkNameMap["libnavigation-copilot"] = "mobile-navigation-copilot"
5657
sdkNameMap["libnavigation-metrics"] = "mobile-navigation-metrics"
5758
sdkNameMap["libnavigator"] = "mobile-navigation-navigator"
5859
sdkNameMap["libtrip-notification"] = "mobile-navigation-notification"
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
package com.mapbox.navigation.instrumentation_tests.core
2+
3+
import android.location.Location
4+
import com.mapbox.api.directions.v5.models.RouteOptions
5+
import com.mapbox.navigation.base.ExperimentalPreviewMapboxNavigationAPI
6+
import com.mapbox.navigation.base.extensions.applyDefaultNavigationOptions
7+
import com.mapbox.navigation.base.extensions.applyLanguageAndVoiceUnitOptions
8+
import com.mapbox.navigation.base.options.NavigationOptions
9+
import com.mapbox.navigation.base.route.NavigationRoute
10+
import com.mapbox.navigation.base.route.RouterOrigin
11+
import com.mapbox.navigation.core.DeveloperMetadata
12+
import com.mapbox.navigation.core.DeveloperMetadataObserver
13+
import com.mapbox.navigation.core.MapboxNavigation
14+
import com.mapbox.navigation.core.MapboxNavigationProvider
15+
import com.mapbox.navigation.core.directions.session.RoutesExtra
16+
import com.mapbox.navigation.core.internal.HistoryRecordingSessionState
17+
import com.mapbox.navigation.core.internal.HistoryRecordingStateChangeObserver
18+
import com.mapbox.navigation.core.internal.extensions.registerHistoryRecordingStateChangeObserver
19+
import com.mapbox.navigation.instrumentation_tests.activity.EmptyTestActivity
20+
import com.mapbox.navigation.instrumentation_tests.utils.MapboxNavigationRule
21+
import com.mapbox.navigation.instrumentation_tests.utils.coroutines.clearNavigationRoutesAndWaitForUpdate
22+
import com.mapbox.navigation.instrumentation_tests.utils.coroutines.routesUpdates
23+
import com.mapbox.navigation.instrumentation_tests.utils.coroutines.sdkTest
24+
import com.mapbox.navigation.instrumentation_tests.utils.coroutines.setNavigationRoutesAndAwaitError
25+
import com.mapbox.navigation.instrumentation_tests.utils.history.MapboxHistoryTestRule
26+
import com.mapbox.navigation.instrumentation_tests.utils.routes.MockRoute
27+
import com.mapbox.navigation.instrumentation_tests.utils.routes.RoutesProvider
28+
import com.mapbox.navigation.testing.ui.BaseTest
29+
import com.mapbox.navigation.testing.ui.utils.getMapboxAccessTokenFromResources
30+
import com.mapbox.navigation.testing.ui.utils.runOnMainSync
31+
import kotlinx.coroutines.flow.filter
32+
import kotlinx.coroutines.flow.first
33+
import org.junit.Assert.assertEquals
34+
import org.junit.Before
35+
import org.junit.Rule
36+
import org.junit.Test
37+
38+
@OptIn(ExperimentalPreviewMapboxNavigationAPI::class)
39+
class CopilotIntegrationTest : BaseTest<EmptyTestActivity>(EmptyTestActivity::class.java) {
40+
41+
private lateinit var mapboxNavigation: MapboxNavigation
42+
private lateinit var mockRoute: MockRoute
43+
private lateinit var routes: List<NavigationRoute>
44+
45+
@get:Rule
46+
val mapboxNavigationRule = MapboxNavigationRule()
47+
48+
@get:Rule
49+
val mapboxHistoryTestRule = MapboxHistoryTestRule()
50+
51+
override fun setupMockLocation(): Location {
52+
mockRoute = RoutesProvider.dc_very_short(activity)
53+
routes = NavigationRoute.create(
54+
mockRoute.routeResponse,
55+
RouteOptions.builder()
56+
.applyDefaultNavigationOptions()
57+
.applyLanguageAndVoiceUnitOptions(activity)
58+
.baseUrl(mockWebServerRule.baseUrl)
59+
.coordinatesList(mockRoute.routeWaypoints).build(),
60+
RouterOrigin.Offboard
61+
)
62+
return mockLocationUpdatesRule.generateLocationUpdate {
63+
latitude = mockRoute.routeWaypoints.first().latitude()
64+
longitude = mockRoute.routeWaypoints.first().longitude()
65+
}
66+
}
67+
68+
@Before
69+
fun setUp() {
70+
runOnMainSync {
71+
mapboxNavigation = MapboxNavigationProvider.create(
72+
NavigationOptions.Builder(activity)
73+
.accessToken(getMapboxAccessTokenFromResources(activity))
74+
.build()
75+
)
76+
mapboxHistoryTestRule.historyRecorder = mapboxNavigation.historyRecorder
77+
}
78+
}
79+
80+
@Test
81+
fun copilotObserverReceivesSameIdsAsDeveloperMetadata() = sdkTest {
82+
val collectedDeveloperMetadatas = mutableListOf<DeveloperMetadata>()
83+
val developerMetadataObserver = DeveloperMetadataObserver {
84+
collectedDeveloperMetadatas.add(it)
85+
}
86+
val startedSessionObserverIds = mutableListOf<String>()
87+
val historyRecordingStateObserver = object : HistoryRecordingStateChangeObserver {
88+
override fun onShouldStartRecording(state: HistoryRecordingSessionState) {
89+
startedSessionObserverIds.add(state.sessionId)
90+
}
91+
override fun onShouldStopRecording(state: HistoryRecordingSessionState) {
92+
}
93+
94+
override fun onShouldCancelRecording(state: HistoryRecordingSessionState) {
95+
}
96+
}
97+
mapboxNavigation.registerDeveloperMetadataObserver(developerMetadataObserver)
98+
mockWebServerRule.requestHandlers.addAll(mockRoute.mockRequestHandlers)
99+
mapboxNavigation.historyRecorder.startRecording()
100+
mapboxNavigation.registerHistoryRecordingStateChangeObserver(historyRecordingStateObserver)
101+
102+
transitionFromIdleToFreeDrive()
103+
transitionFromFreeDriveToActiveGuidance()
104+
transitionFromActiveGuidanceToFreeDrive()
105+
transitionFromFreeDriveToStubActiveGuidanceAndBackToFreeDrive()
106+
transitionFromFreeDriveToIdle()
107+
108+
val collectedIds = collectedDeveloperMetadatas.map { it.copilotSessionId }
109+
// first and last are idle: not recorded by HistoryRecordingStateChangeObserver
110+
assertEquals(startedSessionObserverIds, collectedIds.drop(1).dropLast(1))
111+
}
112+
113+
private fun transitionFromIdleToFreeDrive() {
114+
mapboxNavigation.startTripSession()
115+
}
116+
117+
private suspend fun transitionFromFreeDriveToActiveGuidance() {
118+
mapboxNavigation.setNavigationRoutes(routes)
119+
mapboxNavigation.routesUpdates()
120+
.filter { it.reason == RoutesExtra.ROUTES_UPDATE_REASON_NEW }
121+
.first()
122+
}
123+
124+
private suspend fun transitionFromActiveGuidanceToFreeDrive() {
125+
mapboxNavigation.clearNavigationRoutesAndWaitForUpdate()
126+
}
127+
128+
private suspend fun transitionFromFreeDriveToStubActiveGuidanceAndBackToFreeDrive() {
129+
mapboxNavigation.setNavigationRoutesAndAwaitError(routes, 6)
130+
}
131+
132+
private fun transitionFromFreeDriveToIdle() {
133+
mapboxNavigation.stopTripSession()
134+
}
135+
}

0 commit comments

Comments
 (0)