Skip to content

Commit 8a85e74

Browse files
author
Cameron Mace
authored
reroute metric (#296)
* initial reroute metric added * more metadata added * removed safeguards used for preventing null objects * updated MAS with new metric fixes * remove staging info in manifest
1 parent 1b2e969 commit 8a85e74

6 files changed

Lines changed: 151 additions & 9 deletions

File tree

app/src/main/AndroidManifest.xml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,5 @@
4949
android:name="android.support.PARENT_ACTIVITY"
5050
android:value=".MainActivity"/>
5151
</activity>
52-
5352
</application>
5453
</manifest>

gradle/dependencies.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ ext {
99

1010
version = [
1111
mapboxMapSdk : '5.1.4',
12-
mapboxServices : '2.2.5',
12+
mapboxServices : '2.2.6',
1313
locationLayerPlugin: '0.1.0',
1414
autoValue : '1.4.1',
1515
autoValueParcel : '0.2.5',

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,10 @@
4848
* @since 0.1.0
4949
*/
5050
public class MapboxNavigation implements ServiceConnection, ProgressChangeListener {
51+
5152
private static final String MAPBOX_NAVIGATION_SDK_IDENTIFIER = "mapbox-navigation-android";
5253
private static final String MAPBOX_NAVIGATION_UI_SDK_IDENTIFIER = "mapbox-navigation-ui-android";
54+
5355
private NavigationEventDispatcher navigationEventDispatcher;
5456
private NavigationService navigationService;
5557
private DirectionsRoute directionsRoute;
@@ -373,6 +375,8 @@ public void startNavigation(@NonNull DirectionsRoute directionsRoute) {
373375
.currentDirectionRoute(directionsRoute)
374376
.rerouteCount(sessionState.rerouteCount() + 1)
375377
.build();
378+
379+
navigationService.rerouteOccurred();
376380
}
377381
}
378382

@@ -651,6 +655,10 @@ SessionState getSessionState() {
651655
return sessionState;
652656
}
653657

658+
void setSessionState(SessionState sessionState) {
659+
this.sessionState = sessionState;
660+
}
661+
654662
private Intent getServiceIntent() {
655663
return new Intent(context, NavigationService.class);
656664
}

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

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,68 @@ static void departEvent(SessionState sessionState, RouteProgress routeProgress,
6464
));
6565
}
6666

67+
static void rerouteEvent(SessionState sessionState, RouteProgress routeProgress, Location location) {
68+
String upcomingInstruction = null;
69+
String previousInstruction = null;
70+
String upcomingModifier = null;
71+
String previousModifier = null;
72+
String upcomingType = null;
73+
String upcomingName = null;
74+
String previousType = null;
75+
76+
if (routeProgress.currentLegProgress().upComingStep() != null) {
77+
upcomingName = routeProgress.currentLegProgress().upComingStep().getName();
78+
if (routeProgress.currentLegProgress().upComingStep().getManeuver() != null) {
79+
upcomingInstruction = routeProgress.currentLegProgress().upComingStep().getManeuver().getInstruction();
80+
upcomingType = routeProgress.currentLegProgress().upComingStep().getManeuver().getType();
81+
upcomingModifier = routeProgress.currentLegProgress().upComingStep().getManeuver().getModifier();
82+
}
83+
}
84+
85+
if (routeProgress.currentLegProgress().currentStep().getManeuver() != null) {
86+
previousInstruction = routeProgress.currentLegProgress().currentStep().getManeuver().getInstruction();
87+
previousType = routeProgress.currentLegProgress().currentStep().getManeuver().getType();
88+
previousModifier = routeProgress.currentLegProgress().currentStep().getManeuver().getModifier();
89+
}
90+
91+
Location[] beforeLocations = null;
92+
if (sessionState.beforeRerouteLocations() != null && !sessionState.beforeRerouteLocations().isEmpty()) {
93+
beforeLocations = (Location[]) sessionState.beforeRerouteLocations().toArray();
94+
}
95+
96+
Location[] afterLocations = null;
97+
if (sessionState.afterRerouteLocations() != null && !sessionState.afterRerouteLocations().isEmpty()) {
98+
afterLocations = (Location[]) sessionState.afterRerouteLocations().toArray();
99+
}
100+
101+
String previousName = routeProgress.currentLegProgress().currentStep().getName();
102+
103+
MapboxTelemetry.getInstance().pushEvent(MapboxNavigationEvent.buildRerouteEvent(
104+
sdkIdentifier, BuildConfig.MAPBOX_NAVIGATION_VERSION_NAME, sessionState.sessionIdentifier(),
105+
location.getLatitude(), location.getLongitude(),
106+
sessionState.currentGeometry(), "unknown",
107+
(int) routeProgress.directionsRoute().getDistance(),
108+
(int) routeProgress.directionsRoute().getDuration(),
109+
sessionState.rerouteCount(), sessionState.startTimestamp(), beforeLocations, afterLocations,
110+
(int) sessionState.routeProgressBeforeReroute().distanceTraveled(),
111+
(int) sessionState.routeProgressBeforeReroute().distanceRemaining(),
112+
(int) sessionState.routeProgressBeforeReroute().durationRemaining(),
113+
(int) routeProgress.distanceRemaining(),
114+
(int) routeProgress.durationRemaining(),
115+
sessionState.secondsSinceLastReroute(), "",
116+
routeProgress.directionsRoute().getGeometry(), sessionState.mockLocation(),
117+
null, null, sessionState.originalGeometry(),
118+
sessionState.originalDistance(), sessionState.originalDuration(), null,
119+
upcomingInstruction, upcomingType, upcomingModifier, upcomingName, previousInstruction,
120+
previousType, previousModifier,
121+
previousName, (int) routeProgress.currentLegProgress().currentStep().getDistance(),
122+
(int) routeProgress.currentLegProgress().currentStep().getDuration(),
123+
(int) routeProgress.currentLegProgress().currentStepProgress().distanceRemaining(),
124+
(int) routeProgress.currentLegProgress().currentStepProgress().durationRemaining(),
125+
sessionState.currentStepCount(), sessionState.originalStepCount()
126+
));
127+
}
128+
67129
static void turnstileEvent() {
68130
MapboxTelemetry.getInstance().setCustomTurnstileEvent(
69131
MapboxNavigationEvent.buildTurnstileEvent(sdkIdentifier, BuildConfig.MAPBOX_NAVIGATION_VERSION_NAME)

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

Lines changed: 49 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import com.mapbox.services.android.telemetry.location.LocationEngineListener;
2020
import com.mapbox.services.api.directions.v5.models.DirectionsRoute;
2121

22+
import java.util.Arrays;
2223
import java.util.List;
2324
import java.util.concurrent.TimeUnit;
2425

@@ -43,17 +44,22 @@ public class NavigationService extends Service implements LocationEngineListener
4344

4445
// Message id used when a new location update occurs and we send to the thread.
4546
private static final int MSG_LOCATION_UPDATED = 1001;
47+
private static final int TWENTY_SECOND_INTERVAL = 20000;
4648

4749
private RingBuffer<Integer> recentDistancesFromManeuverInMeters;
4850
private final IBinder localBinder = new LocalBinder();
4951
private NavigationNotification navNotificationManager;
52+
private RingBuffer<Location> locationBuffer;
5053
private long timeIntervalSinceLastOffRoute;
5154
private MapboxNavigation mapboxNavigation;
5255
private LocationEngine locationEngine;
5356
private RouteProgress routeProgress;
5457
private boolean firstProgressUpdate = true;
58+
private boolean queuedRerouteEvent;
5559
private NavigationEngine thread;
5660
private Location location;
61+
private Runnable runnable;
62+
private Handler handler;
5763

5864
@Nullable
5965
@Override
@@ -67,6 +73,7 @@ public void onCreate() {
6773
thread.start();
6874
thread.prepareHandler();
6975
recentDistancesFromManeuverInMeters = new RingBuffer<>(3);
76+
locationBuffer = new RingBuffer<>(20);
7077
}
7178

7279
/**
@@ -80,16 +87,25 @@ public int onStartCommand(Intent intent, int flags, int startId) {
8087

8188
@Override
8289
public void onDestroy() {
83-
super.onDestroy();
8490
if (mapboxNavigation.options().enableNotification()) {
8591
stopForeground(true);
8692
}
93+
94+
if (handler != null && runnable != null) {
95+
if (queuedRerouteEvent) {
96+
runnable.run();
97+
}
98+
handler.removeCallbacks(runnable);
99+
100+
}
101+
87102
// User canceled navigation session
88103
if (routeProgress != null && location != null) {
89104
NavigationMetricsWrapper.cancelEvent(mapboxNavigation.getSessionState(), routeProgress,
90105
location);
91106
}
92107
endNavigation();
108+
super.onDestroy();
93109
}
94110

95111
/**
@@ -166,11 +182,10 @@ public void onConnected() {
166182
@Override
167183
public void onLocationChanged(Location location) {
168184
Timber.d("onLocationChanged");
169-
if (location != null) {
170-
if (validLocationUpdate(location)) {
171-
thread.queueTask(MSG_LOCATION_UPDATED, NewLocationModel.create(location, mapboxNavigation,
172-
recentDistancesFromManeuverInMeters));
173-
}
185+
if (location != null && validLocationUpdate(location)) {
186+
locationBuffer.push(location);
187+
thread.queueTask(MSG_LOCATION_UPDATED, NewLocationModel.create(location, mapboxNavigation,
188+
recentDistancesFromManeuverInMeters));
174189
}
175190
}
176191

@@ -244,6 +259,34 @@ public void onUserOffRoute(Location location, boolean userOffRoute) {
244259
}
245260
}
246261

262+
public void rerouteOccurred() {
263+
mapboxNavigation.setSessionState(mapboxNavigation.getSessionState().toBuilder()
264+
.beforeRerouteLocations(Arrays.asList(
265+
locationBuffer.toArray(new Location[locationBuffer.size()])))
266+
.routeProgressBeforeReroute(routeProgress)
267+
.build());
268+
locationBuffer.clear();
269+
queuedRerouteEvent = true;
270+
271+
handler = new Handler();
272+
runnable = new Runnable() {
273+
@Override
274+
public void run() {
275+
mapboxNavigation.setSessionState(mapboxNavigation.getSessionState().toBuilder()
276+
.afterRerouteLocations(Arrays.asList(
277+
locationBuffer.toArray(new Location[locationBuffer.size()])))
278+
.build());
279+
280+
locationBuffer.clear();
281+
282+
NavigationMetricsWrapper.rerouteEvent(mapboxNavigation.getSessionState(), routeProgress,
283+
location);
284+
queuedRerouteEvent = false;
285+
}
286+
};
287+
handler.postDelayed(runnable, TWENTY_SECOND_INTERVAL);
288+
}
289+
247290
class LocalBinder extends Binder {
248291
NavigationService getService() {
249292
Timber.d("Local binder called.");

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

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,20 @@
11
package com.mapbox.services.android.navigation.v5.navigation;
22

3+
import android.location.Location;
34
import android.support.annotation.NonNull;
45
import android.support.annotation.Nullable;
56

67
import com.google.auto.value.AutoValue;
78
import com.mapbox.services.Constants;
9+
import com.mapbox.services.android.navigation.v5.routeprogress.RouteProgress;
810
import com.mapbox.services.api.directions.v5.models.DirectionsRoute;
911
import com.mapbox.services.api.directions.v5.models.RouteLeg;
1012
import com.mapbox.services.commons.models.Position;
1113
import com.mapbox.services.commons.utils.PolylineUtils;
1214

1315
import java.util.Date;
1416
import java.util.List;
17+
import java.util.concurrent.TimeUnit;
1518

1619
@AutoValue
1720
abstract class SessionState {
@@ -64,6 +67,17 @@ int currentStepCount() {
6467

6568
abstract DirectionsRoute currentDirectionRoute();
6669

70+
int secondsSinceLastReroute() {
71+
if (lastRerouteDate() == null) {
72+
return -1;
73+
}
74+
long diffInMs = lastRerouteDate().getTime() - new Date().getTime();
75+
return (int) TimeUnit.MILLISECONDS.toSeconds(diffInMs);
76+
}
77+
78+
@Nullable
79+
abstract Date lastRerouteDate();
80+
6781
abstract Date startTimestamp();
6882

6983
@Nullable
@@ -75,16 +89,30 @@ int currentStepCount() {
7589

7690
abstract double previousRouteDistancesCompleted();
7791

92+
@Nullable
93+
abstract List<Location> beforeRerouteLocations();
94+
95+
@Nullable
96+
abstract List<Location> afterRerouteLocations();
97+
98+
@Nullable
99+
abstract RouteProgress routeProgressBeforeReroute();
100+
78101
abstract Builder toBuilder();
79102

80103
static Builder builder() {
81104
return new AutoValue_SessionState.Builder();
82105
}
83106

84-
85107
@AutoValue.Builder
86108
abstract static class Builder {
87109

110+
abstract Builder routeProgressBeforeReroute(@Nullable RouteProgress routeProgress);
111+
112+
abstract Builder afterRerouteLocations(@Nullable List<Location> beforeLocations);
113+
114+
abstract Builder beforeRerouteLocations(@Nullable List<Location> beforeLocations);
115+
88116
abstract Builder originalDirectionRoute(@NonNull DirectionsRoute directionsRoute);
89117

90118
abstract Builder currentDirectionRoute(@NonNull DirectionsRoute directionsRoute);
@@ -95,6 +123,8 @@ abstract static class Builder {
95123

96124
abstract Builder requestIdentifier(@Nullable String requestIdentifier);
97125

126+
abstract Builder lastRerouteDate(@Nullable Date lastRerouteDate);
127+
98128
abstract Builder mockLocation(boolean mockLocation);
99129

100130
abstract Builder rerouteCount(int rerouteCount);

0 commit comments

Comments
 (0)