Skip to content

Commit 7548779

Browse files
committed
Create NavigationViewRouter timeout to unblock routing state
1 parent b65953a commit 7548779

File tree

4 files changed

+142
-30
lines changed

4 files changed

+142
-30
lines changed

libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationViewRouter.java

Lines changed: 42 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import com.mapbox.services.android.navigation.v5.route.RouteListener;
1616
import com.mapbox.services.android.navigation.v5.routeprogress.RouteProgress;
1717

18+
import java.util.Date;
1819
import java.util.List;
1920

2021
class NavigationViewRouter implements RouteListener {
@@ -29,7 +30,7 @@ class NavigationViewRouter implements RouteListener {
2930
private RouteOptions routeOptions;
3031
private DirectionsRoute currentRoute;
3132
private Location location;
32-
private boolean isRouting;
33+
private RouteCallStatus callStatus;
3334

3435
NavigationViewRouter(RouteFetcher onlineRouter, ConnectivityStatusProvider connectivityStatus,
3536
ViewRouteListener listener) {
@@ -43,25 +44,26 @@ class NavigationViewRouter implements RouteListener {
4344
// Extra fields for testing purposes
4445
NavigationViewRouter(RouteFetcher onlineRouter, NavigationViewOfflineRouter offlineRouter,
4546
ConnectivityStatusProvider connectivityStatus, RouteComparator routeComparator,
46-
ViewRouteListener listener) {
47+
ViewRouteListener listener, RouteCallStatus callStatus) {
4748
this.onlineRouter = onlineRouter;
4849
this.offlineRouter = offlineRouter;
4950
this.connectivityStatus = connectivityStatus;
50-
this.listener = listener;
5151
this.routeComparator = routeComparator;
52+
this.listener = listener;
53+
this.callStatus = callStatus;
5254
onlineRouter.addRouteListener(this);
5355
}
5456

5557
@Override
5658
public void onResponseReceived(DirectionsResponse response, @Nullable RouteProgress routeProgress) {
5759
routeComparator.compare(response, currentRoute);
58-
isRouting = false;
60+
updateCallStatusReceived();
5961
}
6062

6163
@Override
6264
public void onErrorReceived(Throwable throwable) {
6365
onRequestError(throwable.getMessage());
64-
isRouting = false;
66+
updateCallStatusReceived();
6567
}
6668

6769
void extractRouteOptions(NavigationViewOptions options) {
@@ -70,19 +72,16 @@ void extractRouteOptions(NavigationViewOptions options) {
7072
}
7173

7274
void findRouteFrom(@Nullable RouteProgress routeProgress) {
73-
if (isRouting) {
75+
if (isRouting()) {
7476
return;
7577
}
7678
NavigationRoute.Builder builder = onlineRouter.buildRequestFrom(location, routeProgress);
7779
if (connectivityStatus.isConnectedFast()) {
78-
onlineRouter.findRouteWith(builder);
79-
isRouting = true;
80+
findOnlineRouteWith(builder);
8081
} else if (isOfflineConfigured()) {
81-
offlineRouter.findRouteWith(builder);
82-
isRouting = true;
82+
findOfflineRouteWith(builder);
8383
} else if (connectivityStatus.isConnected()) {
84-
onlineRouter.findRouteWith(builder);
85-
isRouting = true;
84+
findOnlineRouteWith(builder);
8685
}
8786
}
8887

@@ -95,6 +94,12 @@ void updateCurrentRoute(DirectionsRoute currentRoute) {
9594
listener.onRouteUpdate(currentRoute);
9695
}
9796

97+
private void updateCallStatusReceived() {
98+
if (callStatus != null) {
99+
callStatus.setResponseReceived();
100+
}
101+
}
102+
98103
void onRequestError(String errorMessage) {
99104
listener.onRouteRequestError(errorMessage);
100105
}
@@ -115,6 +120,16 @@ private void cacheRouteOptions(RouteOptions routeOptions) {
115120
cacheRouteDestination();
116121
}
117122

123+
private void cacheRouteDestination() {
124+
boolean hasValidCoordinates = routeOptions != null && !routeOptions.coordinates().isEmpty();
125+
if (hasValidCoordinates) {
126+
List<Point> coordinates = routeOptions.coordinates();
127+
int destinationCoordinate = coordinates.size() - 1;
128+
Point destinationPoint = coordinates.get(destinationCoordinate);
129+
listener.onDestinationSet(destinationPoint);
130+
}
131+
}
132+
118133
private void initializeOfflineFrom(NavigationViewOptions options) {
119134
String offlinePath = options.offlineRoutingTilesPath();
120135
String offlineTilesVersion = options.offlineRoutingTilesVersion();
@@ -131,13 +146,21 @@ private boolean isOfflineConfigured() {
131146
return offlineRouter != null && offlineRouter.isConfigured();
132147
}
133148

134-
private void cacheRouteDestination() {
135-
boolean hasValidCoordinates = routeOptions != null && !routeOptions.coordinates().isEmpty();
136-
if (hasValidCoordinates) {
137-
List<Point> coordinates = routeOptions.coordinates();
138-
int destinationCoordinate = coordinates.size() - 1;
139-
Point destinationPoint = coordinates.get(destinationCoordinate);
140-
listener.onDestinationSet(destinationPoint);
149+
private void findOnlineRouteWith(NavigationRoute.Builder builder) {
150+
onlineRouter.cancelRouteCall();
151+
onlineRouter.findRouteWith(builder);
152+
callStatus = new RouteCallStatus(new Date());
153+
}
154+
155+
private void findOfflineRouteWith(NavigationRoute.Builder builder) {
156+
offlineRouter.findRouteWith(builder);
157+
callStatus = new RouteCallStatus(new Date());
158+
}
159+
160+
private boolean isRouting() {
161+
if (callStatus == null) {
162+
return false;
141163
}
164+
return callStatus.isRouting(new Date());
142165
}
143166
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package com.mapbox.services.android.navigation.ui.v5;
2+
3+
import java.util.Date;
4+
5+
class RouteCallStatus {
6+
7+
private static final int TWO_SECONDS_IN_MILLISECONDS = 2000;
8+
private boolean responseReceived;
9+
private final Date callDate;
10+
11+
RouteCallStatus(Date callDate) {
12+
this.callDate = callDate;
13+
}
14+
15+
void setResponseReceived() {
16+
this.responseReceived = true;
17+
}
18+
19+
boolean isRouting(Date currentDate) {
20+
if (responseReceived) {
21+
return false;
22+
}
23+
return diffInMilliseconds(callDate, currentDate) < TWO_SECONDS_IN_MILLISECONDS;
24+
}
25+
26+
private long diffInMilliseconds(Date callDate, Date currentDate) {
27+
return currentDate.getTime() - callDate.getTime();
28+
}
29+
}

libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/NavigationViewRouterTest.java

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,8 @@ public void findRouteFrom_fastConnectionGoesToOnline() {
103103
null, // Null offline (simulate no data)
104104
status,
105105
mock(RouteComparator.class),
106-
mock(ViewRouteListener.class)
106+
mock(ViewRouteListener.class),
107+
mock(RouteCallStatus.class)
107108
);
108109
router.updateLocation(mock(Location.class));
109110

@@ -125,7 +126,8 @@ public void findRouteFrom_nullOfflineAndSlowConnectionGoesToOnline() {
125126
null, // Null offline (simulate no data)
126127
status,
127128
mock(RouteComparator.class),
128-
mock(ViewRouteListener.class)
129+
mock(ViewRouteListener.class),
130+
mock(RouteCallStatus.class)
129131
);
130132
router.updateLocation(mock(Location.class));
131133

@@ -148,7 +150,8 @@ public void findRouteFrom_slowConnectionGoesToOffline() {
148150
offlineRouter,
149151
status,
150152
mock(RouteComparator.class),
151-
mock(ViewRouteListener.class)
153+
mock(ViewRouteListener.class),
154+
mock(RouteCallStatus.class)
152155
);
153156
router.updateLocation(mock(Location.class));
154157

@@ -171,7 +174,8 @@ public void findRouteFrom_secondRequestIgnored() {
171174
offlineRouter,
172175
status,
173176
mock(RouteComparator.class),
174-
mock(ViewRouteListener.class)
177+
mock(ViewRouteListener.class),
178+
mock(RouteCallStatus.class)
175179
);
176180
router.updateLocation(mock(Location.class));
177181

@@ -189,7 +193,8 @@ public void onDestroy_clearsListeners() {
189193
mock(NavigationViewOfflineRouter.class),
190194
mock(ConnectivityStatusProvider.class),
191195
mock(RouteComparator.class),
192-
mock(ViewRouteListener.class)
196+
mock(ViewRouteListener.class),
197+
mock(RouteCallStatus.class)
193198
);
194199

195200
router.onDestroy();
@@ -205,7 +210,8 @@ public void onDestroy_cancelsOnlineRouteCall() {
205210
mock(NavigationViewOfflineRouter.class),
206211
mock(ConnectivityStatusProvider.class),
207212
mock(RouteComparator.class),
208-
mock(ViewRouteListener.class)
213+
mock(ViewRouteListener.class),
214+
mock(RouteCallStatus.class)
209215
);
210216

211217
router.onDestroy();
@@ -227,7 +233,8 @@ public void checksOfflineRouterIsConfiguredIfPathAndTilesVersionArePresent() thr
227233
offlineRouter,
228234
mock(ConnectivityStatusProvider.class),
229235
mock(RouteComparator.class),
230-
mock(ViewRouteListener.class)
236+
mock(ViewRouteListener.class),
237+
mock(RouteCallStatus.class)
231238
);
232239

233240
router.extractRouteOptions(options);
@@ -249,7 +256,8 @@ public void checksOfflineRouterIsNotConfiguredIfPathIsNull() throws Exception {
249256
offlineRouter,
250257
mock(ConnectivityStatusProvider.class),
251258
mock(RouteComparator.class),
252-
mock(ViewRouteListener.class)
259+
mock(ViewRouteListener.class),
260+
mock(RouteCallStatus.class)
253261
);
254262

255263
router.extractRouteOptions(options);
@@ -271,7 +279,8 @@ public void checksOfflineRouterIsNotConfiguredIfPathIsEmpty() throws Exception {
271279
offlineRouter,
272280
mock(ConnectivityStatusProvider.class),
273281
mock(RouteComparator.class),
274-
mock(ViewRouteListener.class)
282+
mock(ViewRouteListener.class),
283+
mock(RouteCallStatus.class)
275284
);
276285

277286
router.extractRouteOptions(options);
@@ -294,7 +303,8 @@ public void checksOfflineRouterIsNotConfiguredIfTilesVersionIsNull() throws Exce
294303
offlineRouter,
295304
mock(ConnectivityStatusProvider.class),
296305
mock(RouteComparator.class),
297-
mock(ViewRouteListener.class)
306+
mock(ViewRouteListener.class),
307+
mock(RouteCallStatus.class)
298308
);
299309

300310
router.extractRouteOptions(options);
@@ -317,7 +327,8 @@ public void checksOfflineRouterIsNotConfiguredIfTilesVersionIsEmpty() throws Exc
317327
offlineRouter,
318328
mock(ConnectivityStatusProvider.class),
319329
mock(RouteComparator.class),
320-
mock(ViewRouteListener.class)
330+
mock(ViewRouteListener.class),
331+
mock(RouteCallStatus.class)
321332
);
322333

323334
router.extractRouteOptions(options);
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package com.mapbox.services.android.navigation.ui.v5;
2+
3+
import org.junit.Test;
4+
5+
import java.util.Date;
6+
7+
import static org.junit.Assert.assertFalse;
8+
import static org.junit.Assert.assertTrue;
9+
import static org.mockito.Mockito.mock;
10+
import static org.mockito.Mockito.when;
11+
12+
public class RouteCallStatusTest {
13+
14+
@Test
15+
public void setResponseReceived_isNoLongerRouting() {
16+
Date callDate = mock(Date.class);
17+
RouteCallStatus callStatus = new RouteCallStatus(callDate);
18+
19+
callStatus.setResponseReceived();
20+
21+
assertFalse(callStatus.isRouting(mock(Date.class)));
22+
}
23+
24+
@Test
25+
public void isRouting_returnsTrueUnderTwoSeconds() {
26+
Date callDate = mock(Date.class);
27+
when(callDate.getTime()).thenReturn(0L);
28+
Date currentDate = mock(Date.class);
29+
when((currentDate.getTime())).thenReturn(1000L);
30+
RouteCallStatus callStatus = new RouteCallStatus(callDate);
31+
32+
boolean isRouting = callStatus.isRouting(currentDate);
33+
34+
assertTrue(isRouting);
35+
}
36+
37+
@Test
38+
public void isRouting_returnsFalseOverTwoSeconds() {
39+
Date callDate = mock(Date.class);
40+
when(callDate.getTime()).thenReturn(0L);
41+
Date currentDate = mock(Date.class);
42+
when((currentDate.getTime())).thenReturn(2100L);
43+
RouteCallStatus callStatus = new RouteCallStatus(callDate);
44+
45+
boolean isRouting = callStatus.isRouting(currentDate);
46+
47+
assertFalse(isRouting);
48+
}
49+
}

0 commit comments

Comments
 (0)