Skip to content

Commit 951a809

Browse files
committed
Update RouteRetrievalEvent
1 parent 6bf87c7 commit 951a809

File tree

12 files changed

+231
-86
lines changed

12 files changed

+231
-86
lines changed

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

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
import com.mapbox.services.android.navigation.v5.exception.NavigationException;
66

77
class ElapsedTime {
8+
9+
private static final double ELAPSED_TIME_DENOMINATOR = 1e+9;
10+
private static final double PRECISION = 100d;
811
private Long start = null;
912
private Long end = null;
1013

@@ -29,10 +32,12 @@ Long getEnd() {
2932
return end;
3033
}
3134

32-
long getElapsedTime() {
35+
double getElapsedTime() {
3336
if (start == null || end == null) {
3437
throw new NavigationException("Must call start() and end() before calling getElapsedTime()");
3538
}
36-
return end - start;
39+
long elapsedTimeInNanoseconds = end - start;
40+
double elapsedTimeInSeconds = elapsedTimeInNanoseconds / ELAPSED_TIME_DENOMINATOR;
41+
return Math.round(elapsedTimeInSeconds * PRECISION) / PRECISION;
3742
}
3843
}

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

Lines changed: 0 additions & 8 deletions
This file was deleted.

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -371,7 +371,7 @@ static void feedbackEvent(SessionState sessionState, MetricsRouteProgress metric
371371
mapboxTelemetry.push(feedbackEvent);
372372
}
373373

374-
static void routeRetrievalEvent(long elapsedTime, String routeUuid, String sessionId) {
374+
static void routeRetrievalEvent(double elapsedTime, String routeUuid, String sessionId) {
375375
push(new RouteRetrievalEvent(elapsedTime, routeUuid, sessionId));
376376
}
377377

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

Lines changed: 9 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424

2525
import retrofit2.Call;
2626
import retrofit2.Callback;
27-
import retrofit2.Response;
2827

2928

3029
/**
@@ -42,8 +41,7 @@
4241
public final class NavigationRoute {
4342

4443
private final MapboxDirections mapboxDirections;
45-
private final NavigationTelemetry navigationTelemetry;
46-
private final ElapsedTime elapsedTime;
44+
private static final NavigationRouteEventListener EVENT_LISTENER = new NavigationRouteEventListener();
4745

4846
/**
4947
* Package private constructor used for the {@link Builder#build()} method.
@@ -52,14 +50,7 @@ public final class NavigationRoute {
5250
* @since 0.5.0
5351
*/
5452
NavigationRoute(MapboxDirections mapboxDirections) {
55-
this(mapboxDirections, NavigationTelemetry.getInstance(), new ElapsedTime());
56-
}
57-
58-
NavigationRoute(MapboxDirections mapboxDirections, NavigationTelemetry navigationTelemetry,
59-
ElapsedTime elapsedTime) {
6053
this.mapboxDirections = mapboxDirections;
61-
this.navigationTelemetry = navigationTelemetry;
62-
this.elapsedTime = elapsedTime;
6354
}
6455

6556
/**
@@ -73,7 +64,7 @@ public static Builder builder(Context context) {
7364
}
7465

7566
static Builder builder(Context context, LocaleUtils localeUtils) {
76-
return new Builder()
67+
return new Builder(EVENT_LISTENER)
7768
.annotations(DirectionsCriteria.ANNOTATION_CONGESTION, DirectionsCriteria.ANNOTATION_DISTANCE)
7869
.language(context, localeUtils)
7970
.voiceUnits(context, localeUtils)
@@ -88,24 +79,7 @@ static Builder builder(Context context, LocaleUtils localeUtils) {
8879
* @since 0.5.0
8980
*/
9081
public void getRoute(final Callback<DirectionsResponse> callback) {
91-
elapsedTime.start();
92-
93-
mapboxDirections.enqueueCall(new Callback<DirectionsResponse>() {
94-
@Override
95-
public void onResponse(Call<DirectionsResponse> call, Response<DirectionsResponse> response) {
96-
elapsedTime.end();
97-
callback.onResponse(call, response);
98-
if (response.body() != null && !response.body().routes().isEmpty()) {
99-
navigationTelemetry.routeRetrievalEvent(elapsedTime,
100-
response.body().routes().get(0).routeOptions().requestUuid());
101-
}
102-
}
103-
104-
@Override
105-
public void onFailure(Call<DirectionsResponse> call, Throwable throwable) {
106-
callback.onFailure(call, throwable);
107-
}
108-
});
82+
mapboxDirections.enqueueCall(new NavigationRouteCallback(EVENT_LISTENER, callback));
10983
}
11084

11185
/**
@@ -146,12 +120,14 @@ public static final class Builder {
146120
private static final String SEMICOLON = ";";
147121
private static final String COMMA = ",";
148122
private final MapboxDirections.Builder directionsBuilder;
123+
private final NavigationRouteEventListener eventListener;
149124

150125
/**
151126
* Private constructor for initializing the raw MapboxDirections.Builder
152127
*/
153-
private Builder() {
154-
directionsBuilder = MapboxDirections.builder();
128+
private Builder(NavigationRouteEventListener eventListener) {
129+
this.eventListener = eventListener;
130+
this.directionsBuilder = MapboxDirections.builder();
155131
}
156132

157133
/**
@@ -639,7 +615,8 @@ public NavigationRoute build() {
639615
.overview(DirectionsCriteria.OVERVIEW_FULL)
640616
.voiceInstructions(true)
641617
.bannerInstructions(true)
642-
.roundaboutExits(true);
618+
.roundaboutExits(true)
619+
.eventListener(eventListener);
643620
return new NavigationRoute(directionsBuilder.build());
644621
}
645622

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.v5.navigation;
2+
3+
import android.support.annotation.NonNull;
4+
5+
import com.mapbox.api.directions.v5.models.DirectionsResponse;
6+
7+
import retrofit2.Call;
8+
import retrofit2.Callback;
9+
import retrofit2.Response;
10+
11+
class NavigationRouteCallback implements Callback<DirectionsResponse> {
12+
13+
private final NavigationTelemetry telemetry;
14+
private final NavigationRouteEventListener listener;
15+
private final Callback<DirectionsResponse> callback;
16+
17+
NavigationRouteCallback(NavigationRouteEventListener listener, Callback<DirectionsResponse> callback) {
18+
this(NavigationTelemetry.getInstance(), listener, callback);
19+
}
20+
21+
NavigationRouteCallback(NavigationTelemetry telemetry, NavigationRouteEventListener listener,
22+
Callback<DirectionsResponse> callback) {
23+
this.telemetry = telemetry;
24+
this.listener = listener;
25+
this.callback = callback;
26+
}
27+
28+
@Override
29+
public void onResponse(@NonNull Call<DirectionsResponse> call, @NonNull Response<DirectionsResponse> response) {
30+
callback.onResponse(call, response);
31+
if (isValid(response)) {
32+
String uuid = response.body().uuid();
33+
sendEventWith(listener.getTime(), uuid);
34+
}
35+
}
36+
37+
@Override
38+
public void onFailure(@NonNull Call<DirectionsResponse> call, @NonNull Throwable throwable) {
39+
callback.onFailure(call, throwable);
40+
}
41+
42+
private boolean isValid(Response<DirectionsResponse> response) {
43+
return response.body() != null && !response.body().routes().isEmpty();
44+
}
45+
46+
private void sendEventWith(ElapsedTime time, String uuid) {
47+
telemetry.routeRetrievalEvent(time, uuid);
48+
}
49+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package com.mapbox.services.android.navigation.v5.navigation;
2+
3+
import okhttp3.Call;
4+
import okhttp3.EventListener;
5+
6+
class NavigationRouteEventListener extends EventListener {
7+
8+
private final ElapsedTime time;
9+
10+
NavigationRouteEventListener() {
11+
this(new ElapsedTime());
12+
}
13+
14+
NavigationRouteEventListener(ElapsedTime time) {
15+
this.time = time;
16+
}
17+
18+
@Override
19+
public void callStart(Call call) {
20+
super.callStart(call);
21+
time.start();
22+
}
23+
24+
@Override
25+
public void callEnd(Call call) {
26+
super.callEnd(call);
27+
time.end();
28+
}
29+
30+
ElapsedTime getTime() {
31+
return time;
32+
}
33+
}

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,8 @@ void cancelFeedback(String feedbackId) {
303303

304304
void routeRetrievalEvent(ElapsedTime elapsedTime, String routeUuid) {
305305
if (navigationSessionState != null && !navigationSessionState.sessionIdentifier().isEmpty()) {
306-
NavigationMetricsWrapper.routeRetrievalEvent(elapsedTime.getElapsedTime(), routeUuid,
306+
double time = elapsedTime.getElapsedTime();
307+
NavigationMetricsWrapper.routeRetrievalEvent(time, routeUuid,
307308
navigationSessionState.sessionIdentifier());
308309
} else {
309310
routeRetrievalElapsedTime = elapsedTime;

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ class RouteRetrievalEvent extends NavigationPerformanceEvent implements Parcelab
99
private static final String ELAPSED_TIME_NAME = "elapsed_time";
1010
private static final String ROUTE_UUID_NAME = "route_uuid";
1111

12-
RouteRetrievalEvent(long elapsedTime, String routeUuid, String sessionId) {
12+
RouteRetrievalEvent(double elapsedTime, String routeUuid, String sessionId) {
1313
super(sessionId);
1414

15-
addCounter(new LongCounter(ELAPSED_TIME_NAME, elapsedTime));
15+
addCounter(new DoubleCounter(ELAPSED_TIME_NAME, elapsedTime));
1616
addAttribute(new Attribute(ROUTE_UUID_NAME, routeUuid));
1717
}
1818
}

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

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,34 @@
88

99
public class ElapsedTimeTest {
1010

11+
private static final double DELTA = 1E-2;
12+
1113
@Test(expected = NavigationException.class)
1214
public void errorThrownIfEndCalledBeforeStart() {
1315
new ElapsedTime().end();
1416
}
1517

1618
@Test
17-
public void elapsedTime() {
19+
public void elapsedTime_returnsCorrectTimeInSeconds() {
1820
ElapsedTime elapsedTime = new ElapsedTime();
21+
1922
elapsedTime.start();
23+
someOperation();
2024
elapsedTime.end();
25+
2126
long start = elapsedTime.getStart();
2227
long end = elapsedTime.getEnd();
28+
long elapsedTimeInNanoseconds = end - start;
29+
double elapsedTimeInSeconds = elapsedTimeInNanoseconds / 1e+9;
30+
double roundedTime = Math.round(elapsedTimeInSeconds * 100d) / 100d;
31+
assertEquals(roundedTime, elapsedTime.getElapsedTime(), DELTA);
32+
}
2333

24-
assertEquals(elapsedTime.getElapsedTime(), end - start);
34+
private void someOperation() {
35+
try {
36+
Thread.sleep(1000);
37+
} catch (InterruptedException exception) {
38+
exception.printStackTrace();
39+
}
2540
}
2641
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
package com.mapbox.services.android.navigation.v5.navigation;
2+
3+
import android.support.annotation.NonNull;
4+
5+
import com.mapbox.api.directions.v5.models.DirectionsResponse;
6+
import com.mapbox.api.directions.v5.models.DirectionsRoute;
7+
8+
import org.junit.Test;
9+
10+
import java.util.ArrayList;
11+
12+
import retrofit2.Call;
13+
import retrofit2.Callback;
14+
import retrofit2.Response;
15+
16+
import static org.mockito.ArgumentMatchers.eq;
17+
import static org.mockito.Mockito.mock;
18+
import static org.mockito.Mockito.verify;
19+
import static org.mockito.Mockito.when;
20+
21+
public class NavigationRouteCallbackTest {
22+
23+
@Test
24+
public void onResponse_callbackIsCalled() {
25+
NavigationTelemetry telemetry = mock(NavigationTelemetry.class);
26+
NavigationRouteEventListener listener = mock(NavigationRouteEventListener.class);
27+
Callback<DirectionsResponse> callback = mock(Callback.class);
28+
Call call = mock(Call.class);
29+
String uuid = "some_uuid";
30+
Response response = buildMockResponse(uuid);
31+
NavigationRouteCallback routeCallback = new NavigationRouteCallback(telemetry, listener, callback);
32+
33+
routeCallback.onResponse(call, response);
34+
35+
verify(callback).onResponse(call, response);
36+
}
37+
38+
@Test
39+
public void onResponse_validResponseSendsEvent() {
40+
NavigationTelemetry telemetry = mock(NavigationTelemetry.class);
41+
NavigationRouteEventListener listener = mock(NavigationRouteEventListener.class);
42+
ElapsedTime elapsedTime = mock(ElapsedTime.class);
43+
when(listener.getTime()).thenReturn(elapsedTime);
44+
Callback<DirectionsResponse> callback = mock(Callback.class);
45+
Call call = mock(Call.class);
46+
String uuid = "some_uuid";
47+
Response response = buildMockResponse(uuid);
48+
NavigationRouteCallback routeCallback = new NavigationRouteCallback(telemetry, listener, callback);
49+
50+
routeCallback.onResponse(call, response);
51+
52+
verify(telemetry).routeRetrievalEvent(eq(elapsedTime), eq(uuid));
53+
}
54+
55+
@Test
56+
public void onFailure_callbackIsCalled() {
57+
NavigationTelemetry telemetry = mock(NavigationTelemetry.class);
58+
NavigationRouteEventListener listener = mock(NavigationRouteEventListener.class);
59+
Callback<DirectionsResponse> callback = mock(Callback.class);
60+
Call call = mock(Call.class);
61+
Throwable throwable = mock(Throwable.class);
62+
NavigationRouteCallback routeCallback = new NavigationRouteCallback(telemetry, listener, callback);
63+
64+
routeCallback.onFailure(call, throwable);
65+
66+
verify(callback).onFailure(call, throwable);
67+
}
68+
69+
@NonNull
70+
private Response buildMockResponse(String uuid) {
71+
Response response = mock(Response.class);
72+
DirectionsResponse directionsResponse = mock(DirectionsResponse.class);
73+
ArrayList<DirectionsRoute> routes = new ArrayList<>();
74+
routes.add(mock(DirectionsRoute.class));
75+
when(directionsResponse.uuid()).thenReturn(uuid);
76+
when(directionsResponse.routes()).thenReturn(routes);
77+
when(response.body()).thenReturn(directionsResponse);
78+
return response;
79+
}
80+
}

0 commit comments

Comments
 (0)