From 49a2c63a889180e4a87323c89488b391bd5a136a Mon Sep 17 00:00:00 2001 From: Seth Bourget Date: Tue, 25 Jun 2024 10:31:50 -0700 Subject: [PATCH] Using semaphore rather than synchronizing on generic object. --- .../examples/mincompile/DropInUIActivity.kt | 2 -- .../internal/route/RouteCompatibilityCache.kt | 15 ++++++++++++++- .../internal/route/RouteCompatibilityCacheTest.kt | 2 ++ .../mapbox/navigation/core/MapboxNavigation.kt | 2 ++ .../directions/session/MapboxDirectionsSession.kt | 1 + 5 files changed, 19 insertions(+), 3 deletions(-) diff --git a/app-mincompile/src/main/java/com/mapbox/navigation/examples/mincompile/DropInUIActivity.kt b/app-mincompile/src/main/java/com/mapbox/navigation/examples/mincompile/DropInUIActivity.kt index 73125df4e12..d37f93eb0cf 100644 --- a/app-mincompile/src/main/java/com/mapbox/navigation/examples/mincompile/DropInUIActivity.kt +++ b/app-mincompile/src/main/java/com/mapbox/navigation/examples/mincompile/DropInUIActivity.kt @@ -3,8 +3,6 @@ package com.mapbox.navigation.examples.mincompile import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import com.mapbox.navigation.examples.mincompile.databinding.LayoutActivityDropinBinding -import com.mapbox.navigation.examples.mincompile.databinding.LayoutActivityMainBinding -import com.mapbox.navigation.examples.mincompile.databinding.LayoutActivityNavigationBinding class DropInUIActivity : AppCompatActivity() { private lateinit var binding: LayoutActivityDropinBinding diff --git a/libnavigation-base/src/main/java/com/mapbox/navigation/base/internal/route/RouteCompatibilityCache.kt b/libnavigation-base/src/main/java/com/mapbox/navigation/base/internal/route/RouteCompatibilityCache.kt index c15fd9c68d3..3b3a062f3d6 100644 --- a/libnavigation-base/src/main/java/com/mapbox/navigation/base/internal/route/RouteCompatibilityCache.kt +++ b/libnavigation-base/src/main/java/com/mapbox/navigation/base/internal/route/RouteCompatibilityCache.kt @@ -5,7 +5,7 @@ import com.mapbox.api.directions.v5.models.DirectionsRoute import com.mapbox.navigation.base.route.NavigationRoute /** - * **Internal** cache object that aims to improve the performance performance of compatibility functions + * **Internal** cache object that aims to improve the performance of compatibility functions * that transform the [DirectionsRoute] route into a [NavigationRoute]. * * It caches up to 3 randomly created [NavigationRoute] instances, @@ -34,6 +34,19 @@ object RouteCompatibilityCache { * Use to put all routes tracked by `MapboxDirectionsSession` to cache (and clear everything else). */ fun setDirectionsSessionResult(routes: List) { + // A crash was reported due to an LruCache inconsistency. + // The caching implementation is using java.concurrent + // classes for synchronization. This method is getting called + // from a coroutine upstream. Putting this call on it's own thread + // should make the synchronization effective. + Thread { + run { + setDirectionsSessionResultInternal(routes) + } + }.start() + } + + private fun setDirectionsSessionResultInternal(routes: List) { synchronized(lock) { creationCache.evictAll() directionsSessionCache.clear() diff --git a/libnavigation-base/src/test/java/com/mapbox/navigation/base/internal/route/RouteCompatibilityCacheTest.kt b/libnavigation-base/src/test/java/com/mapbox/navigation/base/internal/route/RouteCompatibilityCacheTest.kt index 90decc10ba4..829493d15ff 100644 --- a/libnavigation-base/src/test/java/com/mapbox/navigation/base/internal/route/RouteCompatibilityCacheTest.kt +++ b/libnavigation-base/src/test/java/com/mapbox/navigation/base/internal/route/RouteCompatibilityCacheTest.kt @@ -24,6 +24,7 @@ class RouteCompatibilityCacheTest { every { directionsRoute } returns directionsRouteMock } RouteCompatibilityCache.setDirectionsSessionResult(listOf(navigationRoute)) + Thread.sleep(50) val result = RouteCompatibilityCache.getFor(directionsRouteMock) @@ -56,6 +57,7 @@ class RouteCompatibilityCacheTest { every { directionsRoute } returns directionsRouteMock2 } RouteCompatibilityCache.setDirectionsSessionResult(listOf(navigationRoute2)) + Thread.sleep(50) assertNull(RouteCompatibilityCache.getFor(directionsRouteMock1)) diff --git a/libnavigation-core/src/main/java/com/mapbox/navigation/core/MapboxNavigation.kt b/libnavigation-core/src/main/java/com/mapbox/navigation/core/MapboxNavigation.kt index ef8e5e3df4b..0139d73afbd 100644 --- a/libnavigation-core/src/main/java/com/mapbox/navigation/core/MapboxNavigation.kt +++ b/libnavigation-core/src/main/java/com/mapbox/navigation/core/MapboxNavigation.kt @@ -6,6 +6,7 @@ package com.mapbox.navigation.core import android.Manifest.permission.ACCESS_COARSE_LOCATION import android.Manifest.permission.ACCESS_FINE_LOCATION +import android.util.Log import androidx.annotation.RequiresPermission import androidx.annotation.UiThread import androidx.annotation.VisibleForTesting @@ -54,6 +55,7 @@ import com.mapbox.navigation.core.arrival.AutoArrivalController import com.mapbox.navigation.core.directions.LegacyNavigationRouterAdapter import com.mapbox.navigation.core.directions.LegacyRouterAdapter import com.mapbox.navigation.core.directions.session.DirectionsSession +import com.mapbox.navigation.core.directions.session.DirectionsSessionRoutes import com.mapbox.navigation.core.directions.session.RoutesExtra import com.mapbox.navigation.core.directions.session.RoutesObserver import com.mapbox.navigation.core.directions.session.RoutesSetStartedParams diff --git a/libnavigation-core/src/main/java/com/mapbox/navigation/core/directions/session/MapboxDirectionsSession.kt b/libnavigation-core/src/main/java/com/mapbox/navigation/core/directions/session/MapboxDirectionsSession.kt index e6b1951623f..78e00bcac76 100644 --- a/libnavigation-core/src/main/java/com/mapbox/navigation/core/directions/session/MapboxDirectionsSession.kt +++ b/libnavigation-core/src/main/java/com/mapbox/navigation/core/directions/session/MapboxDirectionsSession.kt @@ -46,6 +46,7 @@ internal class MapboxDirectionsSession( ) { return } + RouteCompatibilityCache.setDirectionsSessionResult(routes.acceptedRoutes) val result = routes.toRoutesUpdatedResult().also { routesUpdatedResult = it }