-
Notifications
You must be signed in to change notification settings - Fork 319
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Kyle Madsen
committed
Mar 18, 2020
1 parent
244361f
commit a164785
Showing
12 changed files
with
351 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
54 changes: 54 additions & 0 deletions
54
libnavigation-core/src/main/java/com/mapbox/navigation/core/routerefresh/RouteRefreshApi.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
package com.mapbox.navigation.core.routerefresh | ||
|
||
import com.mapbox.api.directions.v5.models.DirectionsRoute | ||
import com.mapbox.api.directionsrefresh.v1.MapboxDirectionsRefresh | ||
import com.mapbox.navigation.base.trip.model.RouteProgress | ||
|
||
internal class RouteRefreshApi( | ||
private val routeRefreshRetrofit: RouteRefreshRetrofit | ||
) { | ||
fun supportsRefresh(route: DirectionsRoute?): Boolean { | ||
val isTrafficProfile = route?.routeOptions() | ||
?.profile()?.contains(other = "traffic", ignoreCase = true) | ||
return isTrafficProfile == true | ||
} | ||
|
||
fun refreshRoute( | ||
accessToken: String, | ||
route: DirectionsRoute?, | ||
routeProgress: RouteProgress?, | ||
callback: RouteRefreshCallback | ||
) { | ||
val refreshBuilder = MapboxDirectionsRefresh.builder() | ||
if (accessToken.isNotEmpty()) { | ||
refreshBuilder.accessToken(accessToken) | ||
} | ||
|
||
val originalRoute: DirectionsRoute = route ?: run { | ||
callback.onError(RouteRefreshError("No DirectionsRoute to refresh")) | ||
return | ||
} | ||
|
||
if (!supportsRefresh(originalRoute)) { | ||
callback.onError(RouteRefreshError("Unsupported profile ${originalRoute.routeOptions()?.profile()}")) | ||
return | ||
} | ||
|
||
originalRoute.routeOptions()?.requestUuid()?.let { | ||
refreshBuilder.requestId(it) | ||
} | ||
|
||
val legIndex = routeProgress?.currentLegProgress()?.legIndex() ?: 0 | ||
refreshBuilder.legIndex(legIndex) | ||
|
||
return try { | ||
val mapboxDirectionsRefresh = refreshBuilder.build() | ||
val callbackMapper = RouteRefreshCallbackMapper(originalRoute, legIndex, callback) | ||
routeRefreshRetrofit.enqueueCall(mapboxDirectionsRefresh, callbackMapper) | ||
} catch (throwable: Throwable) { | ||
callback.onError(RouteRefreshError( | ||
message = "Route refresh call failed", | ||
throwable = throwable)) | ||
} | ||
} | ||
} |
14 changes: 14 additions & 0 deletions
14
...gation-core/src/main/java/com/mapbox/navigation/core/routerefresh/RouteRefreshCallback.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package com.mapbox.navigation.core.routerefresh | ||
|
||
import com.mapbox.api.directions.v5.models.DirectionsRoute | ||
|
||
interface RouteRefreshCallback { | ||
fun onRefresh(directionsRoute: DirectionsRoute) | ||
|
||
fun onError(error: RouteRefreshError) | ||
} | ||
|
||
data class RouteRefreshError( | ||
val message: String? = null, | ||
val throwable: Throwable? = null | ||
) |
51 changes: 51 additions & 0 deletions
51
...-core/src/main/java/com/mapbox/navigation/core/routerefresh/RouteRefreshCallbackMapper.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
package com.mapbox.navigation.core.routerefresh | ||
|
||
import com.mapbox.api.directions.v5.models.DirectionsRoute | ||
import com.mapbox.api.directionsrefresh.v1.models.DirectionsRefreshResponse | ||
import retrofit2.Call | ||
import retrofit2.Callback | ||
import retrofit2.Response | ||
|
||
internal class RouteRefreshCallbackMapper( | ||
private val originalRoute: DirectionsRoute, | ||
private val currentLegIndex: Int, | ||
private val callback: RouteRefreshCallback | ||
) : Callback<DirectionsRefreshResponse> { | ||
|
||
override fun onResponse(call: Call<DirectionsRefreshResponse>, response: Response<DirectionsRefreshResponse>) { | ||
val routeAnnotations = response.body()?.route() | ||
var errorThrowable: Throwable? = null | ||
val refreshedDirectionsRoute = try { | ||
mapToDirectionsRoute(routeAnnotations) | ||
} catch (t: Throwable) { | ||
errorThrowable = t | ||
null | ||
} | ||
if (refreshedDirectionsRoute != null) { | ||
callback.onRefresh(refreshedDirectionsRoute) | ||
} else { | ||
callback.onError(RouteRefreshError( | ||
message = "Failed to read refresh response", | ||
throwable = errorThrowable)) | ||
} | ||
} | ||
|
||
override fun onFailure(call: Call<DirectionsRefreshResponse>, t: Throwable) { | ||
callback.onError(RouteRefreshError(throwable = t)) | ||
} | ||
|
||
private fun mapToDirectionsRoute(routeAnnotations: DirectionsRoute?): DirectionsRoute? { | ||
val validRouteAnnotations = routeAnnotations ?: return null | ||
val refreshedRouteLegs = originalRoute.legs()?.let { oldRouteLegsList -> | ||
val legs = oldRouteLegsList.toMutableList() | ||
for (i in currentLegIndex until legs.size) { | ||
validRouteAnnotations.legs()?.let { annotationHolderRouteLegsList -> | ||
val updatedAnnotation = annotationHolderRouteLegsList[i - currentLegIndex].annotation() | ||
legs[i] = legs[i].toBuilder().annotation(updatedAnnotation).build() | ||
} | ||
} | ||
legs.toList() | ||
} | ||
return originalRoute.toBuilder().legs(refreshedRouteLegs).build() | ||
} | ||
} |
65 changes: 65 additions & 0 deletions
65
...tion-core/src/main/java/com/mapbox/navigation/core/routerefresh/RouteRefreshController.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
package com.mapbox.navigation.core.routerefresh | ||
|
||
import android.util.Log | ||
import com.mapbox.api.directions.v5.models.DirectionsRoute | ||
import com.mapbox.navigation.core.trip.session.TripSession | ||
import com.mapbox.navigation.utils.timer.MapboxTimer | ||
import java.util.concurrent.TimeUnit | ||
import kotlinx.coroutines.Job | ||
|
||
/** | ||
* This class is responsible for refreshing the current direction route's traffic at a | ||
* specified [intervalSeconds]. This does not support alternative routes. | ||
* | ||
* If the route is route is successfully refreshed, this class will update the [TripSession.route] | ||
* | ||
* [start] and [stop] are attached to the application lifecycle. Observing routes that | ||
* can be refreshed are handled by this class. Calling [start] will restart the refresh timer. | ||
*/ | ||
internal class RouteRefreshController( | ||
private var accessToken: String, | ||
private val tripSession: TripSession | ||
) { | ||
private val routerRefreshTimer = MapboxTimer() | ||
private val routeRefreshRetrofit = RouteRefreshRetrofit() | ||
private val routeRefreshApi = RouteRefreshApi(routeRefreshRetrofit) | ||
|
||
var intervalSeconds: Long = TimeUnit.MILLISECONDS.toSeconds(routerRefreshTimer.restartAfterMillis) | ||
set(value) { | ||
routerRefreshTimer.restartAfterMillis = TimeUnit.SECONDS.toMillis(value) | ||
field = value | ||
} | ||
|
||
fun start(): Job { | ||
stop() | ||
return routerRefreshTimer.startTimer { | ||
if (routeRefreshApi.supportsRefresh(tripSession.route)) { | ||
routeRefreshApi.refreshRoute( | ||
accessToken, | ||
tripSession.route, | ||
tripSession.getRouteProgress(), | ||
routeRefreshCallback) | ||
} | ||
} | ||
} | ||
|
||
fun stop() { | ||
routerRefreshTimer.stopJobs() | ||
} | ||
|
||
private val routeRefreshCallback = object : RouteRefreshCallback { | ||
|
||
override fun onRefresh(directionsRoute: DirectionsRoute) { | ||
Log.i("RouteRefresh", "Successful refresh") | ||
tripSession.route = directionsRoute | ||
} | ||
|
||
override fun onError(error: RouteRefreshError) { | ||
if (error.throwable != null) { | ||
Log.e("RouteRefresh", error.message, error.throwable) | ||
} else { | ||
Log.e("RouteRefresh", error.message) | ||
} | ||
} | ||
} | ||
} |
18 changes: 18 additions & 0 deletions
18
...gation-core/src/main/java/com/mapbox/navigation/core/routerefresh/RouteRefreshRetrofit.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package com.mapbox.navigation.core.routerefresh | ||
|
||
import com.mapbox.api.directionsrefresh.v1.MapboxDirectionsRefresh | ||
import com.mapbox.api.directionsrefresh.v1.models.DirectionsRefreshResponse | ||
import retrofit2.Callback | ||
|
||
/** | ||
* This class is used for adding unit tests to [RouteRefreshApi] | ||
*/ | ||
internal class RouteRefreshRetrofit { | ||
|
||
internal fun enqueueCall( | ||
mapboxDirectionsRefresh: MapboxDirectionsRefresh, | ||
callback: Callback<DirectionsRefreshResponse> | ||
) { | ||
mapboxDirectionsRefresh.enqueueCall(callback) | ||
} | ||
} |
Oops, something went wrong.