Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
import com.mapbox.services.android.navigation.v5.exception.NavigationException;

class ElapsedTime {

private static final double ELAPSED_TIME_DENOMINATOR = 1e+9;
private static final double PRECISION = 100d;
private Long start = null;
private Long end = null;

Expand All @@ -29,10 +32,12 @@ Long getEnd() {
return end;
}

long getElapsedTime() {
double getElapsedTime() {
if (start == null || end == null) {
throw new NavigationException("Must call start() and end() before calling getElapsedTime()");
}
return end - start;
long elapsedTimeInNanoseconds = end - start;
double elapsedTimeInSeconds = elapsedTimeInNanoseconds / ELAPSED_TIME_DENOMINATOR;
return Math.round(elapsedTimeInSeconds * PRECISION) / PRECISION;
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,7 @@ static void feedbackEvent(SessionState sessionState, MetricsRouteProgress metric
mapboxTelemetry.push(feedbackEvent);
}

static void routeRetrievalEvent(long elapsedTime, String routeUuid, String sessionId) {
static void routeRetrievalEvent(double elapsedTime, String routeUuid, String sessionId) {
push(new RouteRetrievalEvent(elapsedTime, routeUuid, sessionId));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
import okhttp3.Interceptor;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;


/**
Expand All @@ -44,8 +43,7 @@
public final class NavigationRoute {

private final MapboxDirections mapboxDirections;
private final NavigationTelemetry navigationTelemetry;
private final ElapsedTime elapsedTime;
private static final NavigationRouteEventListener EVENT_LISTENER = new NavigationRouteEventListener();

/**
* Package private constructor used for the {@link Builder#build()} method.
Expand All @@ -54,14 +52,7 @@ public final class NavigationRoute {
* @since 0.5.0
*/
NavigationRoute(MapboxDirections mapboxDirections) {
this(mapboxDirections, NavigationTelemetry.getInstance(), new ElapsedTime());
}

NavigationRoute(MapboxDirections mapboxDirections, NavigationTelemetry navigationTelemetry,
ElapsedTime elapsedTime) {
this.mapboxDirections = mapboxDirections;
this.navigationTelemetry = navigationTelemetry;
this.elapsedTime = elapsedTime;
}

/**
Expand Down Expand Up @@ -90,24 +81,7 @@ static Builder builder(Context context, LocaleUtils localeUtils) {
* @since 0.5.0
*/
public void getRoute(final Callback<DirectionsResponse> callback) {
elapsedTime.start();

mapboxDirections.enqueueCall(new Callback<DirectionsResponse>() {
@Override
public void onResponse(Call<DirectionsResponse> call, Response<DirectionsResponse> response) {
elapsedTime.end();
callback.onResponse(call, response);
if (response.body() != null && !response.body().routes().isEmpty()) {
navigationTelemetry.routeRetrievalEvent(elapsedTime,
response.body().routes().get(0).routeOptions().requestUuid());
}
}

@Override
public void onFailure(Call<DirectionsResponse> call, Throwable throwable) {
callback.onFailure(call, throwable);
}
});
mapboxDirections.enqueueCall(new NavigationRouteCallback(EVENT_LISTENER, callback));
}

/**
Expand Down Expand Up @@ -148,6 +122,7 @@ public static final class Builder {
private static final String SEMICOLON = ";";
private static final String COMMA = ",";
private final MapboxDirections.Builder directionsBuilder;
private final NavigationRouteEventListener eventListener;

/**
* Private constructor for initializing the raw MapboxDirections.Builder
Expand All @@ -158,6 +133,7 @@ private Builder() {

Builder(MapboxDirections.Builder directionsBuilder) {
this.directionsBuilder = directionsBuilder;
this.eventListener = EVENT_LISTENER;
}

/**
Expand Down Expand Up @@ -667,7 +643,8 @@ public NavigationRoute build() {
.overview(DirectionsCriteria.OVERVIEW_FULL)
.voiceInstructions(true)
.bannerInstructions(true)
.roundaboutExits(true);
.roundaboutExits(true)
.eventListener(eventListener);
return new NavigationRoute(directionsBuilder.build());
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package com.mapbox.services.android.navigation.v5.navigation;

import android.support.annotation.NonNull;

import com.mapbox.api.directions.v5.models.DirectionsResponse;

import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

class NavigationRouteCallback implements Callback<DirectionsResponse> {

private final NavigationTelemetry telemetry;
private final NavigationRouteEventListener listener;
private final Callback<DirectionsResponse> callback;

NavigationRouteCallback(NavigationRouteEventListener listener, Callback<DirectionsResponse> callback) {
this(NavigationTelemetry.getInstance(), listener, callback);
}

NavigationRouteCallback(NavigationTelemetry telemetry, NavigationRouteEventListener listener,
Callback<DirectionsResponse> callback) {
this.telemetry = telemetry;
this.listener = listener;
this.callback = callback;
}

@Override
public void onResponse(@NonNull Call<DirectionsResponse> call, @NonNull Response<DirectionsResponse> response) {
callback.onResponse(call, response);
if (isValid(response)) {
String uuid = response.body().uuid();
sendEventWith(listener.getTime(), uuid);
}
}

@Override
public void onFailure(@NonNull Call<DirectionsResponse> call, @NonNull Throwable throwable) {
callback.onFailure(call, throwable);
}

private boolean isValid(Response<DirectionsResponse> response) {
return response.body() != null && !response.body().routes().isEmpty();
}

private void sendEventWith(ElapsedTime time, String uuid) {
telemetry.routeRetrievalEvent(time, uuid);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.mapbox.services.android.navigation.v5.navigation;

import okhttp3.Call;
import okhttp3.EventListener;

class NavigationRouteEventListener extends EventListener {

private final ElapsedTime time;

NavigationRouteEventListener() {
this(new ElapsedTime());
}

NavigationRouteEventListener(ElapsedTime time) {
this.time = time;
}

@Override
public void callStart(Call call) {
super.callStart(call);
time.start();
}

@Override
public void callEnd(Call call) {
super.callEnd(call);
time.end();
}

ElapsedTime getTime() {
return time;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,8 @@ void cancelFeedback(String feedbackId) {

void routeRetrievalEvent(ElapsedTime elapsedTime, String routeUuid) {
if (navigationSessionState != null && !navigationSessionState.sessionIdentifier().isEmpty()) {
NavigationMetricsWrapper.routeRetrievalEvent(elapsedTime.getElapsedTime(), routeUuid,
double time = elapsedTime.getElapsedTime();
NavigationMetricsWrapper.routeRetrievalEvent(time, routeUuid,
navigationSessionState.sessionIdentifier());
} else {
routeRetrievalElapsedTime = elapsedTime;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ class RouteRetrievalEvent extends NavigationPerformanceEvent implements Parcelab
private static final String ELAPSED_TIME_NAME = "elapsed_time";
private static final String ROUTE_UUID_NAME = "route_uuid";

RouteRetrievalEvent(long elapsedTime, String routeUuid, String sessionId) {
RouteRetrievalEvent(double elapsedTime, String routeUuid, String sessionId) {
super(sessionId);

addCounter(new LongCounter(ELAPSED_TIME_NAME, elapsedTime));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Class 'LongCounter' is never used

Could we remove it altogether?

addCounter(new DoubleCounter(ELAPSED_TIME_NAME, elapsedTime));
addAttribute(new Attribute(ROUTE_UUID_NAME, routeUuid));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,34 @@

public class ElapsedTimeTest {

private static final double DELTA = 1E-2;

@Test(expected = NavigationException.class)
public void errorThrownIfEndCalledBeforeStart() {
new ElapsedTime().end();
}

@Test
public void elapsedTime() {
public void elapsedTime_returnsCorrectTimeInSeconds() {
ElapsedTime elapsedTime = new ElapsedTime();

elapsedTime.start();
someOperation();
elapsedTime.end();

long start = elapsedTime.getStart();
long end = elapsedTime.getEnd();
long elapsedTimeInNanoseconds = end - start;
double elapsedTimeInSeconds = elapsedTimeInNanoseconds / 1e+9;
double roundedTime = Math.round(elapsedTimeInSeconds * 100d) / 100d;
assertEquals(roundedTime, elapsedTime.getElapsedTime(), DELTA);
}

assertEquals(elapsedTime.getElapsedTime(), end - start);
private void someOperation() {
try {
Thread.sleep(1000);
} catch (InterruptedException exception) {
exception.printStackTrace();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package com.mapbox.services.android.navigation.v5.navigation;

import android.support.annotation.NonNull;

import com.mapbox.api.directions.v5.models.DirectionsResponse;
import com.mapbox.api.directions.v5.models.DirectionsRoute;

import org.junit.Test;

import java.util.ArrayList;

import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

public class NavigationRouteCallbackTest {

@Test
public void onResponse_callbackIsCalled() {
NavigationTelemetry telemetry = mock(NavigationTelemetry.class);
NavigationRouteEventListener listener = mock(NavigationRouteEventListener.class);
Callback<DirectionsResponse> callback = mock(Callback.class);
Call call = mock(Call.class);
String uuid = "some_uuid";
Response response = buildMockResponse(uuid);
NavigationRouteCallback routeCallback = new NavigationRouteCallback(telemetry, listener, callback);

routeCallback.onResponse(call, response);

verify(callback).onResponse(call, response);
}

@Test
public void onResponse_validResponseSendsEvent() {
NavigationTelemetry telemetry = mock(NavigationTelemetry.class);
NavigationRouteEventListener listener = mock(NavigationRouteEventListener.class);
ElapsedTime elapsedTime = mock(ElapsedTime.class);
when(listener.getTime()).thenReturn(elapsedTime);
Callback<DirectionsResponse> callback = mock(Callback.class);
Call call = mock(Call.class);
String uuid = "some_uuid";
Response response = buildMockResponse(uuid);
NavigationRouteCallback routeCallback = new NavigationRouteCallback(telemetry, listener, callback);

routeCallback.onResponse(call, response);

verify(telemetry).routeRetrievalEvent(eq(elapsedTime), eq(uuid));
}

@Test
public void onFailure_callbackIsCalled() {
NavigationTelemetry telemetry = mock(NavigationTelemetry.class);
NavigationRouteEventListener listener = mock(NavigationRouteEventListener.class);
Callback<DirectionsResponse> callback = mock(Callback.class);
Call call = mock(Call.class);
Throwable throwable = mock(Throwable.class);
NavigationRouteCallback routeCallback = new NavigationRouteCallback(telemetry, listener, callback);

routeCallback.onFailure(call, throwable);

verify(callback).onFailure(call, throwable);
}

@NonNull
private Response buildMockResponse(String uuid) {
Response response = mock(Response.class);
DirectionsResponse directionsResponse = mock(DirectionsResponse.class);
ArrayList<DirectionsRoute> routes = new ArrayList<>();
routes.add(mock(DirectionsRoute.class));
when(directionsResponse.uuid()).thenReturn(uuid);
when(directionsResponse.routes()).thenReturn(routes);
when(response.body()).thenReturn(directionsResponse);
return response;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.mapbox.services.android.navigation.v5.navigation;

import org.junit.Test;

import okhttp3.Call;

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;

public class NavigationRouteEventListenerTest {

@Test
public void callStart_timeStartIsCalled() {
ElapsedTime time = mock(ElapsedTime.class);
NavigationRouteEventListener listener = new NavigationRouteEventListener(time);

listener.callStart(mock(Call.class));

verify(time).start();
}

@Test
public void callEnd_timeEndIsCalled() {
ElapsedTime time = mock(ElapsedTime.class);
NavigationRouteEventListener listener = new NavigationRouteEventListener(time);

listener.callEnd(mock(Call.class));

verify(time).end();
}
}
Loading