From 789fbf58dba313a591bbdf0fd9b49d431c407aba Mon Sep 17 00:00:00 2001 From: Bart Louwers Date: Mon, 13 Feb 2023 13:39:36 +0100 Subject: [PATCH] Remove `com.google.android.gms.location` (#379) --- platform/android/CHANGELOG.md | 7 +- .../android/MapboxGLAndroidSDK/build.gradle | 1 - .../com/mapbox/mapboxsdk/geometry/LatLng.kt | 3 +- .../mapboxsdk/location/LocationComponent.java | 267 +----------------- .../engine/GoogleLocationEngineImpl.java | 146 ---------- .../location/engine/LocationEngineDefault.kt | 12 + .../engine/LocationEngineProvider.java | 62 ---- .../location/engine/LocationEngineResult.java | 15 +- .../location/LocationComponentTest.kt | 113 +++----- ...oogleLocationEngineImplAdditionalTest.java | 129 --------- .../engine/GoogleLocationEngineImplTest.java | 66 ----- .../engine/LocationEngineProviderTest.java | 14 - .../MapboxGLAndroidSDKTestApp/build.gradle | 1 - .../testapp/style/StyleLoaderTest.kt | 2 +- .../mapbox/mapboxsdk/utils/FontUtilsTest.kt | 2 +- .../location/ManualLocationUpdatesActivity.kt | 4 +- platform/android/gradle/dependencies.gradle | 1 - 17 files changed, 79 insertions(+), 766 deletions(-) delete mode 100644 platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/engine/GoogleLocationEngineImpl.java create mode 100644 platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/engine/LocationEngineDefault.kt delete mode 100644 platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/engine/LocationEngineProvider.java delete mode 100644 platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/location/engine/GoogleLocationEngineImplAdditionalTest.java delete mode 100644 platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/location/engine/GoogleLocationEngineImplTest.java delete mode 100644 platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/location/engine/LocationEngineProviderTest.java diff --git a/platform/android/CHANGELOG.md b/platform/android/CHANGELOG.md index bc6794900d2..fcb8a12715b 100644 --- a/platform/android/CHANGELOG.md +++ b/platform/android/CHANGELOG.md @@ -6,12 +6,17 @@ MapLibre welcomes participation and contributions from everyone. Please read [`C * Add your pull request... -## 10.0.0 - February 10, 2023 +## 10.0.0 - February 14, 2023 ### ✨ Features and improvements * Breaking: Changed resourcePrefix to `maplibre_` from `mapbox_` [647](https://github.com/maplibre/maplibre-gl-native/pull/647) and renamed resources accordingly. Note that this is a breaking change since the names of public resources were renamed as well. Replaced Mapbox logo with MapLibre logo. * GMS location: Replace new LocationRequest() with LocationRequest.Builder, and LocationRequest.PRIORITY_X with Priority.PRIORITY_X ([620](https://github.com/maplibre/maplibre-gl-native/pull/620)) +* Breaking: several deprecated overloads of `LocationComponent.activateLocationComponent` were removed. Use `LocationComponentActivationOptions.Builder` instead. +* Breaking: the `LocationEngine` implemented with Google Location Services has been removed to make MapLibre GL Native for Android fully FLOSS ([#379](https://github.com/maplibre/maplibre-gl-native/issues/379)). To migrate: + * Include the source code of the removed `[GoogleLocationEngineImpl](https://github.com/maplibre/maplibre-gl-native/blob/main/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/engine/GoogleLocationEngineImpl.java)` in your source tree. + * Pass an instance of `LocationEngine` based on `GoogleLocationEngineImpl` to `LocationComponentActivationOptions.Builder.locationEngine`. Refer to how this was done in the now-removed `[LocationEngineProvider](https://github.com/maplibre/maplibre-gl-native/blob/68d58d6f6f453d5c6cc0fa92fcc6c6cfe0cf967f/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/engine/LocationEngineProvider.java#L59)`. + * The static `LocationEngineResult.extractResult` can no longer extract a `LocationEngineResult` from a Google Play intent. To migrate, include and use the [previous implementation](https://github.com/maplibre/maplibre-gl-native/blob/ea234edf67bb3aec75f077e15c1c30c99756b926/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/engine/LocationEngineResult.java#L97) in your source tree. ### 🐞 Bug fixes diff --git a/platform/android/MapboxGLAndroidSDK/build.gradle b/platform/android/MapboxGLAndroidSDK/build.gradle index 1dc8b50dda5..aecd63cb035 100644 --- a/platform/android/MapboxGLAndroidSDK/build.gradle +++ b/platform/android/MapboxGLAndroidSDK/build.gradle @@ -17,7 +17,6 @@ dependencies { implementation dependenciesList.supportAnnotations implementation dependenciesList.supportFragmentV4 implementation dependenciesList.okhttp3 - implementation dependenciesList.gmsLocation implementation dependenciesList.timber implementation dependenciesList.interpolator diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLng.kt b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLng.kt index 4fa897182be..ae1bf1ea283 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLng.kt +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLng.kt @@ -40,7 +40,8 @@ class LatLng : Parcelable { @Keep var latitude = 0.0 set( - @FloatRange(from = GeometryConstants.MIN_LATITUDE, to = GeometryConstants.MAX_LATITUDE) latitude) { + @FloatRange(from = GeometryConstants.MIN_LATITUDE, to = GeometryConstants.MAX_LATITUDE) latitude + ) { require(!latitude.isNaN()) { "latitude must not be NaN" } require(abs(latitude) <= GeometryConstants.MAX_LATITUDE) { "latitude must be between -90 and 90" } field = latitude diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationComponent.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationComponent.java index 072a029b21c..8b77f885bae 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationComponent.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationComponent.java @@ -20,7 +20,7 @@ import com.mapbox.mapboxsdk.geometry.LatLng; import com.mapbox.mapboxsdk.location.engine.LocationEngine; import com.mapbox.mapboxsdk.location.engine.LocationEngineCallback; -import com.mapbox.mapboxsdk.location.engine.LocationEngineProvider; +import com.mapbox.mapboxsdk.location.engine.LocationEngineDefault; import com.mapbox.mapboxsdk.location.engine.LocationEngineRequest; import com.mapbox.mapboxsdk.location.engine.LocationEngineResult; import com.mapbox.mapboxsdk.location.modes.CameraMode; @@ -66,7 +66,7 @@ *

* * To get the component object use {@link MapboxMap#getLocationComponent()} and activate it with - * {@link #activateLocationComponent(Context, Style)} or one of the overloads. + * {@link #activateLocationComponent(LocationComponentActivationOptions)}. * Then, manage its visibility with {@link #setLocationComponentEnabled(boolean)}. * The component will not process location updates right after activation, but only after being enabled. * @@ -76,19 +76,16 @@ * {@code ACCESS_COARSE_LOCATION} or {@code ACCESS_FINE_LOCATION} permissions can be requested for * this component to work as expected. *

- * This component offers a default, built-in {@link LocationEngine} with some of the activation methods. - * This engine will be obtained by {@link LocationEngineProvider#getBestLocationEngine(Context, boolean)} which defaults - * to the {@link com.mapbox.mapboxsdk.location.engine.MapboxFusedLocationEngineImpl}. If you'd like to utilize Google - * Play Services - * for more precise location updates, simply add the Google Play Location Services dependency in your build script. - * This will make the default engine the {@link com.mapbox.mapboxsdk.location.engine.GoogleLocationEngineImpl} instead. + * This component offers a default, built-in {@link LocationEngine} called {@link com.mapbox.mapboxsdk.location.engine.MapboxFusedLocationEngineImpl}. + * If you'd like to utilize the previously available Google Play Services for more precise location updates, + * refer to the migration guide of 10.0.0 in the changelog. * After a custom engine is passed to the component, or the built-in is initialized, * the location updates are going to be requested with the {@link LocationEngineRequest}, either a default one, * or the one passed during the activation. * When using any engine, requesting/removing the location updates is going to be managed internally. *

* You can also push location updates to the component without any internal engine management. - * To achieve that, use {@link #activateLocationComponent(Context, Style, boolean)} with false. + * To achieve that, set `useDefaultLocationEngine` in {@link LocationComponentActivationOptions} to false. * No engine is going to be initialized and you can push location updates with {@link #forceLocationUpdate(Location)}. *

* For location puck animation purposes, like navigation, @@ -105,8 +102,6 @@ public final class LocationComponent { private final Transform transform; private Style style; private LocationComponentOptions options; - @NonNull - private InternalLocationEngineProvider internalLocationEngineProvider = new InternalLocationEngineProvider(); @Nullable private LocationEngine locationEngine; @NonNull @@ -218,7 +213,6 @@ public LocationComponent(@NonNull MapboxMap mapboxMap, @NonNull LocationAnimatorCoordinator locationAnimatorCoordinator, @NonNull StaleStateManager staleStateManager, @NonNull CompassEngine compassEngine, - @NonNull InternalLocationEngineProvider internalLocationEngineProvider, boolean useSpecializedLocationLayer) { this.mapboxMap = mapboxMap; this.transform = transform; @@ -230,242 +224,10 @@ public LocationComponent(@NonNull MapboxMap mapboxMap, this.locationAnimatorCoordinator = locationAnimatorCoordinator; this.staleStateManager = staleStateManager; this.compassEngine = compassEngine; - this.internalLocationEngineProvider = internalLocationEngineProvider; this.useSpecializedLocationLayer = useSpecializedLocationLayer; isComponentInitialized = true; } - /** - * This method initializes the component and needs to be called before any other operations are performed. - * Afterwards, you can manage component's visibility by {@link #setLocationComponentEnabled(boolean)}. - *

- * Note: This method will initialize and use an internal {@link LocationEngine} when enabled. - * - * @param context the context - * @param style the proxy object for current map style. More info at {@link Style} - * @deprecated use {@link LocationComponentActivationOptions.Builder} instead - */ - @Deprecated - public void activateLocationComponent(@NonNull Context context, @NonNull Style style) { - activateLocationComponent(context, style, - LocationComponentOptions.createFromAttributes(context, R.style.maplibre_LocationComponent)); - } - - /** - * This method initializes the component and needs to be called before any other operations are performed. - * Afterwards, you can manage component's visibility by {@link #setLocationComponentEnabled(boolean)}. - * - * @param context the context - * @param style the proxy object for current map style. More info at {@link Style} - * @param useDefaultLocationEngine true if you want to initialize and use the built-in location engine or false if - * there should be no location engine initialized - * @deprecated use {@link LocationComponentActivationOptions.Builder} instead - */ - @Deprecated - public void activateLocationComponent(@NonNull Context context, @NonNull Style style, - boolean useDefaultLocationEngine) { - if (useDefaultLocationEngine) { - activateLocationComponent(context, style, R.style.maplibre_LocationComponent); - } else { - activateLocationComponent(context, style, null, R.style.maplibre_LocationComponent); - } - } - - /** - * This method initializes the component and needs to be called before any other operations are performed. - * Afterwards, you can manage component's visibility by {@link #setLocationComponentEnabled(boolean)}. - * - * @param context the context - * @param style the proxy object for current map style. More info at {@link Style} - * @param useDefaultLocationEngine true if you want to initialize and use the built-in location engine or false if - * there should be no location engine initialized - * @param locationEngineRequest the location request - * @deprecated use {@link LocationComponentActivationOptions.Builder} instead - */ - @Deprecated - public void activateLocationComponent(@NonNull Context context, @NonNull Style style, - boolean useDefaultLocationEngine, - @NonNull LocationEngineRequest locationEngineRequest) { - setLocationEngineRequest(locationEngineRequest); - if (useDefaultLocationEngine) { - activateLocationComponent(context, style, R.style.maplibre_LocationComponent); - } else { - activateLocationComponent(context, style, null, R.style.maplibre_LocationComponent); - } - } - - /** - * This method initializes the component and needs to be called before any other operations are performed. - * Afterwards, you can manage component's visibility by {@link #setLocationComponentEnabled(boolean)}. - * - * @param context the context - * @param style the proxy object for current map style. More info at {@link Style} - * @param useDefaultLocationEngine true if you want to initialize and use the built-in location engine or false if - * there should be no location engine initialized - * @param locationEngineRequest the location request - * @param options the options - * @deprecated use {@link LocationComponentActivationOptions.Builder} instead - */ - @Deprecated - public void activateLocationComponent(@NonNull Context context, @NonNull Style style, - boolean useDefaultLocationEngine, - @NonNull LocationEngineRequest locationEngineRequest, - @NonNull LocationComponentOptions options) { - setLocationEngineRequest(locationEngineRequest); - if (useDefaultLocationEngine) { - activateLocationComponent(context, style, options); - } else { - activateLocationComponent(context, style, null, options); - } - } - - /** - * This method initializes the component and needs to be called before any other operations are performed. - * Afterwards, you can manage component's visibility by {@link #setLocationComponentEnabled(boolean)}. - *

- * Note: This method will initialize and use an internal {@link LocationEngine} when enabled. - * - * @param context the context - * @param style the proxy object for current map style. More info at {@link Style} - * @param styleRes the LocationComponent style res - * @deprecated use {@link LocationComponentActivationOptions.Builder} instead - */ - @Deprecated - public void activateLocationComponent(@NonNull Context context, @NonNull Style style, @StyleRes int styleRes) { - activateLocationComponent(context, style, LocationComponentOptions.createFromAttributes(context, styleRes)); - } - - /** - * This method initializes the component and needs to be called before any other operations are performed. - * Afterwards, you can manage component's visibility by {@link #setLocationComponentEnabled(boolean)}. - *

- * Note: This method will initialize and use an internal {@link LocationEngine} when enabled. - *

- * - * @param context the context - * @param style the proxy object for current map style. More info at {@link Style} - * @param options the options - * @deprecated use {@link LocationComponentActivationOptions.Builder} instead - */ - @Deprecated - public void activateLocationComponent(@NonNull Context context, @NonNull Style style, - @NonNull LocationComponentOptions options) { - initialize(context, style, false, options); - initializeLocationEngine(context); - applyStyle(options); - } - - /** - * This method initializes the component and needs to be called before any other operations are performed. - * Afterwards, you can manage component's visibility by {@link #setLocationComponentEnabled(boolean)}. - * - * @param context the context - * @param style the proxy object for current map style. More info at {@link Style} - * @param locationEngine the engine, or null if you'd like to only force location updates - * @param styleRes the LocationComponent style res - * @deprecated use {@link LocationComponentActivationOptions.Builder} instead - */ - @Deprecated - public void activateLocationComponent(@NonNull Context context, @NonNull Style style, - @Nullable LocationEngine locationEngine, @StyleRes int styleRes) { - activateLocationComponent(context, style, locationEngine, - LocationComponentOptions.createFromAttributes(context, styleRes)); - } - - /** - * This method initializes the component and needs to be called before any other operations are performed. - * Afterwards, you can manage component's visibility by {@link #setLocationComponentEnabled(boolean)}. - * - * @param context the context - * @param style the proxy object for current map style. More info at {@link Style} - * @param locationEngine the engine, or null if you'd like to only force location updates - * @param locationEngineRequest the location request - * @param styleRes the LocationComponent style res - * @deprecated use {@link LocationComponentActivationOptions.Builder} instead - */ - @Deprecated - public void activateLocationComponent(@NonNull Context context, @NonNull Style style, - @Nullable LocationEngine locationEngine, - @NonNull LocationEngineRequest locationEngineRequest, @StyleRes int styleRes) { - activateLocationComponent(context, style, locationEngine, locationEngineRequest, - LocationComponentOptions.createFromAttributes(context, styleRes)); - } - - /** - * This method will show the location icon and enable the camera tracking the location. - * - * @param context the context - * @param style the proxy object for current map style. More info at {@link Style} - * @param locationEngine the engine - * @deprecated use {@link LocationComponentActivationOptions.Builder} instead - */ - @Deprecated - public void activateLocationComponent(@NonNull Context context, @NonNull Style style, - @Nullable LocationEngine locationEngine) { - activateLocationComponent(context, style, locationEngine, R.style.maplibre_LocationComponent); - } - - /** - * This method will show the location icon and enable the camera tracking the location. - * - * @param context the context - * @param style the proxy object for current map style. More info at {@link Style} - * @param locationEngine the engine - * @param locationEngineRequest the location request - * @deprecated use {@link LocationComponentActivationOptions.Builder} instead - */ - @Deprecated - public void activateLocationComponent(@NonNull Context context, @NonNull Style style, - @Nullable LocationEngine locationEngine, - @NonNull LocationEngineRequest locationEngineRequest) { - activateLocationComponent( - context, - style, - locationEngine, - locationEngineRequest, - R.style.maplibre_LocationComponent); - } - - /** - * This method initializes the component and needs to be called before any other operations are performed. - * Afterwards, you can manage component's visibility by {@link #setLocationComponentEnabled(boolean)}. - * - * @param locationEngine the engine, or null if you'd like to only force location updates - * @param style the proxy object for current map style. More info at {@link Style} - * @param options the options - * @deprecated use {@link LocationComponentActivationOptions.Builder} instead - */ - @Deprecated - public void activateLocationComponent(@NonNull Context context, @NonNull Style style, - @Nullable LocationEngine locationEngine, - @NonNull LocationComponentOptions options) { - initialize(context, style, false, options); - setLocationEngine(locationEngine); - applyStyle(options); - } - - /** - * This method initializes the component and needs to be called before any other operations are performed. - * Afterwards, you can manage component's visibility by {@link #setLocationComponentEnabled(boolean)}. - * - * @param context the context - * @param style the proxy object for current map style. More info at {@link Style} - * @param locationEngine the engine, or null if you'd like to only force location updates - * @param locationEngineRequest the location request - * @param options the options - * @deprecated use {@link LocationComponentActivationOptions.Builder} instead - */ - @Deprecated - public void activateLocationComponent(@NonNull Context context, @NonNull Style style, - @Nullable LocationEngine locationEngine, - @NonNull LocationEngineRequest locationEngineRequest, - @NonNull LocationComponentOptions options) { - initialize(context, style, false, options); - setLocationEngineRequest(locationEngineRequest); - setLocationEngine(locationEngine); - applyStyle(options); - } - /** * This method initializes the component and needs to be called before any other operations are performed. * Afterwards, you can manage component's visibility by {@link #setLocationComponentEnabled(boolean)}. @@ -503,7 +265,7 @@ public void activateLocationComponent(@NonNull LocationComponentActivationOption setLocationEngine(locationEngine); } else { if (activationOptions.useDefaultLocationEngine()) { - initializeLocationEngine(activationOptions.context()); + setLocationEngine(LocationEngineDefault.INSTANCE.getDefaultLocationEngine(activationOptions.context())); } else { setLocationEngine(null); } @@ -1353,14 +1115,6 @@ private void initialize(@NonNull final Context context, @NonNull Style style, bo onLocationLayerStart(); } - - private void initializeLocationEngine(@NonNull Context context) { - if (this.locationEngine != null) { - this.locationEngine.removeLocationUpdates(currentLocationEngineListener); - } - setLocationEngine(internalLocationEngineProvider.getBestLocationEngine(context, false)); - } - private void updateCompassListenerState(boolean canListen) { if (compassEngine != null) { if (!canListen) { @@ -1711,13 +1465,6 @@ public void onDeveloperAnimationStarted() { } } }; - - static class InternalLocationEngineProvider { - LocationEngine getBestLocationEngine(@NonNull Context context, boolean background) { - return LocationEngineProvider.getBestLocationEngine(context, background); - } - } - private void checkActivationState() { if (!isComponentInitialized) { throw new LocationComponentNotInitializedException(); diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/engine/GoogleLocationEngineImpl.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/engine/GoogleLocationEngineImpl.java deleted file mode 100644 index b6e6afb23da..00000000000 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/engine/GoogleLocationEngineImpl.java +++ /dev/null @@ -1,146 +0,0 @@ -package com.mapbox.mapboxsdk.location.engine; - -import android.annotation.SuppressLint; -import android.app.PendingIntent; -import android.content.Context; -import android.location.Location; -import android.os.Looper; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.annotation.VisibleForTesting; - -import com.google.android.gms.location.FusedLocationProviderClient; -import com.google.android.gms.location.LocationCallback; -import com.google.android.gms.location.LocationRequest; -import com.google.android.gms.location.LocationResult; -import com.google.android.gms.location.LocationServices; -import com.google.android.gms.location.Priority; -import com.google.android.gms.tasks.OnFailureListener; -import com.google.android.gms.tasks.OnSuccessListener; - -import java.util.Collections; -import java.util.List; - -/** - * Wraps implementation of Fused Location Provider - */ -class GoogleLocationEngineImpl implements LocationEngineImpl { - private final FusedLocationProviderClient fusedLocationProviderClient; - - @VisibleForTesting - GoogleLocationEngineImpl(FusedLocationProviderClient fusedLocationProviderClient) { - this.fusedLocationProviderClient = fusedLocationProviderClient; - } - - GoogleLocationEngineImpl(@NonNull Context context) { - this.fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(context); - } - - @NonNull - @Override - public LocationCallback createListener(LocationEngineCallback callback) { - return new GoogleLocationEngineCallbackTransport(callback); - } - - @SuppressLint("MissingPermission") - @Override - public void getLastLocation(@NonNull LocationEngineCallback callback) - throws SecurityException { - GoogleLastLocationEngineCallbackTransport transport = - new GoogleLastLocationEngineCallbackTransport(callback); - fusedLocationProviderClient.getLastLocation().addOnSuccessListener(transport).addOnFailureListener(transport); - } - - @SuppressLint("MissingPermission") - @Override - public void requestLocationUpdates(@NonNull LocationEngineRequest request, - @NonNull LocationCallback listener, - @Nullable Looper looper) throws SecurityException { - fusedLocationProviderClient.requestLocationUpdates(toGMSLocationRequest(request), listener, looper); - } - - @SuppressLint("MissingPermission") - @Override - public void requestLocationUpdates(@NonNull LocationEngineRequest request, - @NonNull PendingIntent pendingIntent) throws SecurityException { - fusedLocationProviderClient.requestLocationUpdates(toGMSLocationRequest(request), pendingIntent); - } - - @Override - public void removeLocationUpdates(@NonNull LocationCallback listener) { - if (listener != null) { - fusedLocationProviderClient.removeLocationUpdates(listener); - } - } - - @Override - public void removeLocationUpdates(PendingIntent pendingIntent) { - if (pendingIntent != null) { - fusedLocationProviderClient.removeLocationUpdates(pendingIntent); - } - } - - private static LocationRequest toGMSLocationRequest(LocationEngineRequest request) { - LocationRequest.Builder builder = new LocationRequest.Builder(request.getInterval()); - builder.setMinUpdateIntervalMillis(request.getFastestInterval()); - builder.setMinUpdateDistanceMeters(request.getDisplacement()); - builder.setMaxUpdateDelayMillis(request.getMaxWaitTime()); - builder.setPriority(toGMSLocationPriority(request.getPriority())); - return builder.build(); - } - - private static int toGMSLocationPriority(int enginePriority) { - switch (enginePriority) { - case LocationEngineRequest.PRIORITY_HIGH_ACCURACY: - return Priority.PRIORITY_HIGH_ACCURACY; - case LocationEngineRequest.PRIORITY_BALANCED_POWER_ACCURACY: - return Priority.PRIORITY_BALANCED_POWER_ACCURACY; - case LocationEngineRequest.PRIORITY_LOW_POWER: - return Priority.PRIORITY_LOW_POWER; - case LocationEngineRequest.PRIORITY_NO_POWER: - default: - return Priority.PRIORITY_PASSIVE; - } - } - - private static final class GoogleLocationEngineCallbackTransport extends LocationCallback { - private final LocationEngineCallback callback; - - GoogleLocationEngineCallbackTransport(LocationEngineCallback callback) { - this.callback = callback; - } - - @Override - public void onLocationResult(LocationResult locationResult) { - super.onLocationResult(locationResult); - List locations = locationResult.getLocations(); - if (!locations.isEmpty()) { - callback.onSuccess(LocationEngineResult.create(locations)); - } else { - callback.onFailure(new Exception("Unavailable location")); - } - } - } - - @VisibleForTesting - static final class GoogleLastLocationEngineCallbackTransport - implements OnSuccessListener, OnFailureListener { - private final LocationEngineCallback callback; - - GoogleLastLocationEngineCallbackTransport(LocationEngineCallback callback) { - this.callback = callback; - } - - @Override - public void onSuccess(Location location) { - callback.onSuccess(location != null ? LocationEngineResult.create(location) : - LocationEngineResult.create(Collections.emptyList())); - } - - @Override - public void onFailure(@NonNull Exception e) { - callback.onFailure(e); - } - } -} diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/engine/LocationEngineDefault.kt b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/engine/LocationEngineDefault.kt new file mode 100644 index 00000000000..a9be77ec188 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/engine/LocationEngineDefault.kt @@ -0,0 +1,12 @@ +package com.mapbox.mapboxsdk.location.engine + +import android.content.Context + +object LocationEngineDefault { + /** + * Returns the default `LocationEngine`. + */ + fun getDefaultLocationEngine(context: Context): LocationEngine { + return LocationEngineProxy(MapboxFusedLocationEngineImpl(context.applicationContext)) + } +} diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/engine/LocationEngineProvider.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/engine/LocationEngineProvider.java deleted file mode 100644 index 643dd71cd48..00000000000 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/engine/LocationEngineProvider.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.mapbox.mapboxsdk.location.engine; - -import android.content.Context; - -import androidx.annotation.NonNull; - -import com.google.android.gms.common.ConnectionResult; -import com.google.android.gms.common.GoogleApiAvailability; - -import static com.mapbox.mapboxsdk.location.engine.Utils.checkNotNull; -import static com.mapbox.mapboxsdk.location.engine.Utils.isOnClasspath; - -/** - * The main entry point for location engine integration. - */ -public final class LocationEngineProvider { - private static final String GOOGLE_LOCATION_SERVICES = "com.google.android.gms.location.LocationServices"; - private static final String GOOGLE_API_AVAILABILITY = "com.google.android.gms.common.GoogleApiAvailability"; - - private LocationEngineProvider() { - // prevent instantiation - } - - /** - * Returns instance to the best location engine, given the included libraries. - * - * @param context {@link Context}. - * @param background true if background optimized engine is desired (note: parameter deprecated) - * @return a unique instance of {@link LocationEngine} every time method is called. - * @since 1.0.0 - */ - @NonNull - @Deprecated - public static LocationEngine getBestLocationEngine(@NonNull Context context, boolean background) { - return getBestLocationEngine(context); - } - - /** - * Returns instance to the best location engine, given the included libraries. - * - * @param context {@link Context}. - * @return a unique instance of {@link LocationEngine} every time method is called. - * @since 1.1.0 - */ - @NonNull - public static LocationEngine getBestLocationEngine(@NonNull Context context) { - checkNotNull(context, "context == null"); - - boolean hasGoogleLocationServices = isOnClasspath(GOOGLE_LOCATION_SERVICES); - if (isOnClasspath(GOOGLE_API_AVAILABILITY)) { - // Check Google Play services APK is available and up-to-date on this device - hasGoogleLocationServices &= GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(context) - == ConnectionResult.SUCCESS; - } - return getLocationEngine(context, hasGoogleLocationServices); - } - - private static LocationEngine getLocationEngine(Context context, boolean isGoogle) { - return isGoogle ? new LocationEngineProxy<>(new GoogleLocationEngineImpl(context.getApplicationContext())) : - new LocationEngineProxy<>(new MapboxFusedLocationEngineImpl(context.getApplicationContext())); - } -} diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/engine/LocationEngineResult.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/engine/LocationEngineResult.java index c7dd05a9056..8a0dadc4255 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/engine/LocationEngineResult.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/engine/LocationEngineResult.java @@ -7,8 +7,6 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import com.google.android.gms.location.LocationResult; - import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -23,8 +21,6 @@ * @since 1.0.0 */ public final class LocationEngineResult { - private static final String GOOGLE_PLAY_LOCATION_RESULT = "com.google.android.gms.location.LocationResult"; - private final List locations; private LocationEngineResult(List locations) { @@ -95,16 +91,7 @@ public List getLocations() { */ @Nullable public static LocationEngineResult extractResult(Intent intent) { - LocationEngineResult result = null; - if (isOnClasspath(GOOGLE_PLAY_LOCATION_RESULT)) { - result = extractGooglePlayResult(intent); - } - return result == null ? extractAndroidResult(intent) : result; - } - - private static LocationEngineResult extractGooglePlayResult(Intent intent) { - LocationResult result = LocationResult.extractResult(intent); - return result != null ? LocationEngineResult.create(result.getLocations()) : null; + return extractAndroidResult(intent); } private static LocationEngineResult extractAndroidResult(Intent intent) { diff --git a/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/location/LocationComponentTest.kt b/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/location/LocationComponentTest.kt index 68830f91112..29eb1814a44 100644 --- a/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/location/LocationComponentTest.kt +++ b/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/location/LocationComponentTest.kt @@ -1,11 +1,8 @@ package com.mapbox.mapboxsdk.location import android.content.Context -import android.content.res.Resources -import android.content.res.TypedArray import android.location.Location import android.os.Looper -import com.mapbox.mapboxsdk.R import com.mapbox.mapboxsdk.camera.CameraPosition import com.mapbox.mapboxsdk.location.LocationComponentConstants.TRANSITION_ANIMATION_DURATION_MS import com.mapbox.mapboxsdk.location.engine.LocationEngine @@ -69,60 +66,45 @@ class LocationComponentTest { @Mock private lateinit var staleStateManager: StaleStateManager - @Mock - private lateinit var locationEngineProvider: LocationComponent.InternalLocationEngineProvider - @Mock private lateinit var style: Style private lateinit var developerAnimationListeners: List + private val defaultOptions: LocationComponentActivationOptions + get() = LocationComponentActivationOptions.builder(context, style).locationEngine(locationEngine).locationEngineRequest(locationEngineRequest).locationComponentOptions(locationComponentOptions).build() + @Before fun before() { MockitoAnnotations.initMocks(this) developerAnimationListeners = mutableListOf() - locationComponent = LocationComponent(mapboxMap, transform, developerAnimationListeners, currentListener, lastListener, locationLayerController, locationCameraController, locationAnimatorCoordinator, staleStateManager, compassEngine, locationEngineProvider, false) - doReturn(locationEngine).`when`(locationEngineProvider).getBestLocationEngine(context, false) + locationComponent = LocationComponent(mapboxMap, transform, developerAnimationListeners, currentListener, lastListener, locationLayerController, locationCameraController, locationAnimatorCoordinator, staleStateManager, compassEngine, false) doReturn(style).`when`(mapboxMap).style - } - - @Test - fun activateWithRequestTest() { - locationComponent.activateLocationComponent(context, mock(Style::class.java), locationEngine, locationEngineRequest, locationComponentOptions) - - Assert.assertEquals(locationEngineRequest, locationComponent.locationEngineRequest) - - doReturn(mock(TypedArray::class.java)).`when`(context) - .obtainStyledAttributes(R.style.maplibre_LocationComponent, R.styleable.maplibre_LocationComponent) - - val resources = mock(Resources::class.java) - - doReturn(resources).`when`(context).resources - doReturn(0f).`when`(resources) - .getDimension(R.dimen.maplibre_locationComponentTrackingMultiFingerMoveThreshold) - doReturn(0f).`when`(resources) - .getDimension(R.dimen.maplibre_locationComponentTrackingMultiFingerMoveThreshold) - locationComponent.activateLocationComponent(context, mock(Style::class.java), true, locationEngineRequest) - Assert.assertEquals(locationEngineRequest, locationComponent.locationEngineRequest) + `when`(style.isFullyLoaded).thenReturn(true) } @Test fun activateWithDefaultLocationEngineRequestAndOptionsTestDefaultLocationEngine() { - locationComponent.activateLocationComponent(context, mock(Style::class.java), true, locationEngineRequest, locationComponentOptions) + val options = LocationComponentActivationOptions.builder(context, style).locationEngine(locationEngine).locationEngineRequest(locationEngineRequest).locationComponentOptions(locationComponentOptions).build() + locationComponent.activateLocationComponent(options) + Assert.assertEquals(locationEngineRequest, locationComponent.locationEngineRequest) Assert.assertNotNull(locationComponent.locationEngine) } @Test fun activateWithDefaultLocationEngineRequestAndOptionsTestCustomLocationEngine() { - locationComponent.activateLocationComponent(context, mock(Style::class.java), false, locationEngineRequest, locationComponentOptions) + val options = LocationComponentActivationOptions.builder(context, style).useDefaultLocationEngine(false).locationEngineRequest(locationEngineRequest).locationComponentOptions(locationComponentOptions).build() + locationComponent.activateLocationComponent(options) + Assert.assertEquals(locationEngineRequest, locationComponent.locationEngineRequest) Assert.assertNull(locationComponent.locationEngine) } @Test fun locationUpdatesWhenEnabledDisableTest() { - locationComponent.activateLocationComponent(context, mock(Style::class.java), locationEngine, locationEngineRequest, locationComponentOptions) + locationComponent.activateLocationComponent(defaultOptions) + verify(locationEngine, times(0)).removeLocationUpdates(currentListener) verify(locationEngine, times(0)).requestLocationUpdates(eq(locationEngineRequest), eq(currentListener), any(Looper::class.java)) @@ -140,7 +122,8 @@ class LocationComponentTest { @Test fun locationUpdatesWhenStartedStoppedTest() { - locationComponent.activateLocationComponent(context, mock(Style::class.java), locationEngine, locationEngineRequest, locationComponentOptions) + locationComponent.activateLocationComponent(defaultOptions) + locationComponent.onStart() locationComponent.isLocationComponentEnabled = true @@ -153,7 +136,7 @@ class LocationComponentTest { @Test fun locationUpdatesWhenNewRequestTest() { - locationComponent.activateLocationComponent(context, mock(Style::class.java), locationEngine, locationEngineRequest, locationComponentOptions) + locationComponent.activateLocationComponent(defaultOptions) locationComponent.onStart() locationComponent.isLocationComponentEnabled = true @@ -165,7 +148,7 @@ class LocationComponentTest { @Test fun lastLocationUpdateOnStartTest() { - locationComponent.activateLocationComponent(context, mock(Style::class.java), locationEngine, locationEngineRequest, locationComponentOptions) + locationComponent.activateLocationComponent(defaultOptions) locationComponent.onStart() locationComponent.isLocationComponentEnabled = true @@ -174,7 +157,7 @@ class LocationComponentTest { @Test fun transitionCallbackFinishedTest() { - locationComponent.activateLocationComponent(context, mock(Style::class.java), locationEngine, locationEngineRequest, locationComponentOptions) + locationComponent.activateLocationComponent(defaultOptions) locationComponent.onStart() locationComponent.isLocationComponentEnabled = true `when`(mapboxMap.cameraPosition).thenReturn(CameraPosition.DEFAULT) @@ -192,7 +175,7 @@ class LocationComponentTest { @Test fun transitionCallbackCanceledTest() { - locationComponent.activateLocationComponent(context, mock(Style::class.java), locationEngine, locationEngineRequest, locationComponentOptions) + locationComponent.activateLocationComponent(defaultOptions) locationComponent.onStart() locationComponent.isLocationComponentEnabled = true `when`(mapboxMap.cameraPosition).thenReturn(CameraPosition.DEFAULT) @@ -210,7 +193,8 @@ class LocationComponentTest { @Test fun transitionCustomFinishedTest() { - locationComponent.activateLocationComponent(context, mock(Style::class.java), locationEngine, locationEngineRequest, locationComponentOptions) + locationComponent.activateLocationComponent(defaultOptions) + locationComponent.onStart() locationComponent.isLocationComponentEnabled = true `when`(mapboxMap.cameraPosition).thenReturn(CameraPosition.DEFAULT) @@ -228,7 +212,7 @@ class LocationComponentTest { @Test fun compass_listenWhenConsumedByNoneCamera() { - locationComponent.activateLocationComponent(context, mock(Style::class.java), locationEngine, locationEngineRequest, locationComponentOptions) + locationComponent.activateLocationComponent(defaultOptions) locationComponent.onStart() locationComponent.isLocationComponentEnabled = true `when`(mapboxMap.cameraPosition).thenReturn(CameraPosition.DEFAULT) @@ -240,7 +224,7 @@ class LocationComponentTest { @Test fun compass_listenWhenConsumedByTrackingCamera() { - locationComponent.activateLocationComponent(context, mock(Style::class.java), locationEngine, locationEngineRequest, locationComponentOptions) + locationComponent.activateLocationComponent(defaultOptions) locationComponent.onStart() locationComponent.isLocationComponentEnabled = true `when`(mapboxMap.cameraPosition).thenReturn(CameraPosition.DEFAULT) @@ -252,7 +236,7 @@ class LocationComponentTest { @Test fun compass_listenWhenConsumedByLayer() { - locationComponent.activateLocationComponent(context, mock(Style::class.java), locationEngine, locationEngineRequest, locationComponentOptions) + locationComponent.activateLocationComponent(defaultOptions) locationComponent.onStart() locationComponent.isLocationComponentEnabled = true `when`(mapboxMap.cameraPosition).thenReturn(CameraPosition.DEFAULT) @@ -264,7 +248,7 @@ class LocationComponentTest { @Test fun compass_notListenWhenNotConsumed() { - locationComponent.activateLocationComponent(context, mock(Style::class.java), locationEngine, locationEngineRequest, locationComponentOptions) + locationComponent.activateLocationComponent(defaultOptions) locationComponent.onStart() locationComponent.isLocationComponentEnabled = true `when`(mapboxMap.cameraPosition).thenReturn(CameraPosition.DEFAULT) @@ -283,7 +267,7 @@ class LocationComponentTest { @Test fun compass_removeListenerOnChange() { - locationComponent.activateLocationComponent(context, mock(Style::class.java), locationEngine, locationEngineRequest, locationComponentOptions) + locationComponent.activateLocationComponent(defaultOptions) locationComponent.onStart() locationComponent.isLocationComponentEnabled = true `when`(mapboxMap.cameraPosition).thenReturn(CameraPosition.DEFAULT) @@ -297,7 +281,7 @@ class LocationComponentTest { @Test fun compass_removeListenerOnStop() { - locationComponent.activateLocationComponent(context, mock(Style::class.java), locationEngine, locationEngineRequest, locationComponentOptions) + locationComponent.activateLocationComponent(defaultOptions) locationComponent.onStart() locationComponent.isLocationComponentEnabled = true `when`(mapboxMap.cameraPosition).thenReturn(CameraPosition.DEFAULT) @@ -310,7 +294,7 @@ class LocationComponentTest { @Test fun compass_reAddListenerOnStart() { - locationComponent.activateLocationComponent(context, mock(Style::class.java), locationEngine, locationEngineRequest, locationComponentOptions) + locationComponent.activateLocationComponent(defaultOptions) locationComponent.onStart() locationComponent.isLocationComponentEnabled = true `when`(mapboxMap.cameraPosition).thenReturn(CameraPosition.DEFAULT) @@ -324,7 +308,7 @@ class LocationComponentTest { @Test fun compass_removeListenerOnStyleStartLoad() { - locationComponent.activateLocationComponent(context, mock(Style::class.java), locationEngine, locationEngineRequest, locationComponentOptions) + locationComponent.activateLocationComponent(defaultOptions) locationComponent.onStart() locationComponent.isLocationComponentEnabled = true `when`(mapboxMap.cameraPosition).thenReturn(CameraPosition.DEFAULT) @@ -337,7 +321,7 @@ class LocationComponentTest { @Test fun compass_reAddListenerOnStyleLoadFinished() { - locationComponent.activateLocationComponent(context, mock(Style::class.java), locationEngine, locationEngineRequest, locationComponentOptions) + locationComponent.activateLocationComponent(defaultOptions) locationComponent.onStart() locationComponent.isLocationComponentEnabled = true `when`(mapboxMap.cameraPosition).thenReturn(CameraPosition.DEFAULT) @@ -351,7 +335,7 @@ class LocationComponentTest { @Test fun compass_reAddListenerOnlyWhenEnabled() { - locationComponent.activateLocationComponent(context, mock(Style::class.java), locationEngine, locationEngineRequest, locationComponentOptions) + locationComponent.activateLocationComponent(defaultOptions) locationComponent.onStart() locationComponent.isLocationComponentEnabled = true `when`(mapboxMap.cameraPosition).thenReturn(CameraPosition.DEFAULT) @@ -367,7 +351,7 @@ class LocationComponentTest { @Test fun compass_notAdListenerWhenDisabled() { - locationComponent.activateLocationComponent(context, mock(Style::class.java), locationEngine, locationEngineRequest, locationComponentOptions) + locationComponent.activateLocationComponent(defaultOptions) locationComponent.onStart() `when`(mapboxMap.cameraPosition).thenReturn(CameraPosition.DEFAULT) @@ -378,7 +362,7 @@ class LocationComponentTest { @Test fun compass_notAdListenerWhenStopped() { - locationComponent.activateLocationComponent(context, mock(Style::class.java), locationEngine, locationEngineRequest, locationComponentOptions) + locationComponent.activateLocationComponent(defaultOptions) locationComponent.isLocationComponentEnabled = true `when`(mapboxMap.cameraPosition).thenReturn(CameraPosition.DEFAULT) @@ -389,7 +373,7 @@ class LocationComponentTest { @Test fun compass_notAddListenerWhenLayerNotReady() { - locationComponent.activateLocationComponent(context, mock(Style::class.java), locationEngine, locationEngineRequest, locationComponentOptions) + locationComponent.activateLocationComponent(defaultOptions) locationComponent.onStart() locationComponent.isLocationComponentEnabled = true `when`(mapboxMap.cameraPosition).thenReturn(CameraPosition.DEFAULT) @@ -406,7 +390,7 @@ class LocationComponentTest { @Test fun developerAnimationCalled() { - locationComponent.activateLocationComponent(context, mock(Style::class.java), locationEngine, locationEngineRequest, locationComponentOptions) + locationComponent.activateLocationComponent(defaultOptions) locationComponent.isLocationComponentEnabled = true for (listener in developerAnimationListeners) { listener.onDeveloperAnimationStarted() @@ -416,7 +400,7 @@ class LocationComponentTest { @Test fun internal_cameraTrackingChangedListener_onCameraTrackingDismissed() { - locationComponent.activateLocationComponent(context, mock(Style::class.java), locationEngine, locationEngineRequest, locationComponentOptions) + locationComponent.activateLocationComponent(defaultOptions) locationComponent.isLocationComponentEnabled = true val cameraChangeListener: OnCameraTrackingChangedListener = mock(OnCameraTrackingChangedListener::class.java) @@ -429,7 +413,7 @@ class LocationComponentTest { @Test fun internal_cameraTrackingChangedListener_onCameraTrackingChanged() { - locationComponent.activateLocationComponent(context, mock(Style::class.java), locationEngine, locationEngineRequest, locationComponentOptions) + locationComponent.activateLocationComponent(defaultOptions) locationComponent.isLocationComponentEnabled = true val cameraValueListener: AnimatorListenerHolder = mock(AnimatorListenerHolder::class.java) @@ -451,7 +435,7 @@ class LocationComponentTest { @Test fun internal_renderModeChangedListener_onRenderModeChanged() { - locationComponent.activateLocationComponent(context, mock(Style::class.java), locationEngine, locationEngineRequest, locationComponentOptions) + locationComponent.activateLocationComponent(defaultOptions) locationComponent.isLocationComponentEnabled = true val cameraListener: AnimatorListenerHolder = mock(AnimatorListenerHolder::class.java) @@ -476,7 +460,6 @@ class LocationComponentTest { val projection: Projection = mock(Projection::class.java) `when`(projection.getMetersPerPixelAtLatitude(location.latitude)).thenReturn(10.0) `when`(mapboxMap.projection).thenReturn(projection) - `when`(style.isFullyLoaded).thenReturn(true) `when`(mapboxMap.cameraPosition).thenReturn(CameraPosition.DEFAULT) locationComponent.activateLocationComponent( @@ -500,7 +483,7 @@ class LocationComponentTest { @Test fun tiltWhileTracking_notReady() { `when`(mapboxMap.cameraPosition).thenReturn(CameraPosition.DEFAULT) - locationComponent.activateLocationComponent(context, mock(Style::class.java), locationEngine, locationEngineRequest, locationComponentOptions) + locationComponent.activateLocationComponent(defaultOptions) locationComponent.isLocationComponentEnabled = true val callback = mock(MapboxMap.CancelableCallback::class.java) @@ -514,7 +497,7 @@ class LocationComponentTest { fun tiltWhileTracking_notTracking() { `when`(mapboxMap.cameraPosition).thenReturn(CameraPosition.DEFAULT) `when`(locationCameraController.cameraMode).thenReturn(CameraMode.NONE) - locationComponent.activateLocationComponent(context, mock(Style::class.java), locationEngine, locationEngineRequest, locationComponentOptions) + locationComponent.activateLocationComponent(defaultOptions) locationComponent.isLocationComponentEnabled = true locationComponent.onStart() @@ -530,7 +513,7 @@ class LocationComponentTest { `when`(mapboxMap.cameraPosition).thenReturn(CameraPosition.DEFAULT) `when`(locationCameraController.cameraMode).thenReturn(CameraMode.TRACKING) `when`(locationCameraController.isTransitioning).thenReturn(true) - locationComponent.activateLocationComponent(context, mock(Style::class.java), locationEngine, locationEngineRequest, locationComponentOptions) + locationComponent.activateLocationComponent(defaultOptions) locationComponent.isLocationComponentEnabled = true locationComponent.onStart() @@ -546,7 +529,7 @@ class LocationComponentTest { `when`(mapboxMap.cameraPosition).thenReturn(CameraPosition.DEFAULT) `when`(locationCameraController.cameraMode).thenReturn(CameraMode.TRACKING) `when`(locationCameraController.isTransitioning).thenReturn(false) - locationComponent.activateLocationComponent(context, mock(Style::class.java), locationEngine, locationEngineRequest, locationComponentOptions) + locationComponent.activateLocationComponent(defaultOptions) locationComponent.isLocationComponentEnabled = true locationComponent.onStart() @@ -560,7 +543,7 @@ class LocationComponentTest { @Test fun zoomWhileTracking_notReady() { `when`(mapboxMap.cameraPosition).thenReturn(CameraPosition.DEFAULT) - locationComponent.activateLocationComponent(context, mock(Style::class.java), locationEngine, locationEngineRequest, locationComponentOptions) + locationComponent.activateLocationComponent(defaultOptions) locationComponent.isLocationComponentEnabled = true val callback = mock(MapboxMap.CancelableCallback::class.java) @@ -574,7 +557,7 @@ class LocationComponentTest { fun zoomWhileTracking_notTracking() { `when`(mapboxMap.cameraPosition).thenReturn(CameraPosition.DEFAULT) `when`(locationCameraController.cameraMode).thenReturn(CameraMode.NONE) - locationComponent.activateLocationComponent(context, mock(Style::class.java), locationEngine, locationEngineRequest, locationComponentOptions) + locationComponent.activateLocationComponent(defaultOptions) locationComponent.isLocationComponentEnabled = true locationComponent.onStart() @@ -590,7 +573,7 @@ class LocationComponentTest { `when`(mapboxMap.cameraPosition).thenReturn(CameraPosition.DEFAULT) `when`(locationCameraController.cameraMode).thenReturn(CameraMode.TRACKING) `when`(locationCameraController.isTransitioning).thenReturn(true) - locationComponent.activateLocationComponent(context, mock(Style::class.java), locationEngine, locationEngineRequest, locationComponentOptions) + locationComponent.activateLocationComponent(defaultOptions) locationComponent.isLocationComponentEnabled = true locationComponent.onStart() @@ -606,7 +589,7 @@ class LocationComponentTest { `when`(mapboxMap.cameraPosition).thenReturn(CameraPosition.DEFAULT) `when`(locationCameraController.cameraMode).thenReturn(CameraMode.TRACKING) `when`(locationCameraController.isTransitioning).thenReturn(false) - locationComponent.activateLocationComponent(context, mock(Style::class.java), locationEngine, locationEngineRequest, locationComponentOptions) + locationComponent.activateLocationComponent(defaultOptions) locationComponent.isLocationComponentEnabled = true locationComponent.onStart() @@ -624,7 +607,6 @@ class LocationComponentTest { val projection: Projection = mock(Projection::class.java) `when`(projection.getMetersPerPixelAtLatitude(location.latitude)).thenReturn(10.0) `when`(mapboxMap.projection).thenReturn(projection) - `when`(style.isFullyLoaded).thenReturn(true) locationComponent.activateLocationComponent( LocationComponentActivationOptions.builder(context, style) .locationComponentOptions(locationComponentOptions) @@ -643,8 +625,7 @@ class LocationComponentTest { fun newLocation_accuracy_indicatorLayerRadiusValue() { val location = Location("test") location.accuracy = 50f - `when`(style.isFullyLoaded).thenReturn(true) - locationComponent = LocationComponent(mapboxMap, transform, developerAnimationListeners, currentListener, lastListener, locationLayerController, locationCameraController, locationAnimatorCoordinator, staleStateManager, compassEngine, locationEngineProvider, true) + locationComponent = LocationComponent(mapboxMap, transform, developerAnimationListeners, currentListener, lastListener, locationLayerController, locationCameraController, locationAnimatorCoordinator, staleStateManager, compassEngine, true) locationComponent.activateLocationComponent( LocationComponentActivationOptions.builder(context, style) .locationComponentOptions(locationComponentOptions) diff --git a/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/location/engine/GoogleLocationEngineImplAdditionalTest.java b/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/location/engine/GoogleLocationEngineImplAdditionalTest.java deleted file mode 100644 index b1ff31c99ed..00000000000 --- a/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/location/engine/GoogleLocationEngineImplAdditionalTest.java +++ /dev/null @@ -1,129 +0,0 @@ -package com.mapbox.mapboxsdk.location.engine; - -import android.location.Location; -import android.os.Looper; - -import androidx.annotation.NonNull; - -import com.google.android.gms.location.FusedLocationProviderClient; -import com.google.android.gms.location.LocationCallback; -import com.google.android.gms.location.LocationRequest; -import com.google.android.gms.location.LocationResult; -import com.google.android.gms.tasks.OnSuccessListener; -import com.google.android.gms.tasks.Task; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.junit.MockitoJUnitRunner; -import org.mockito.stubbing.Answer; - -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -@RunWith(MockitoJUnitRunner.class) -public class GoogleLocationEngineImplAdditionalTest { - private static final long INTERVAL = 1000L; - private LocationEngineProxy engine; - private Location location; - private List locationList = new ArrayList<>(); - private FusedLocationProviderClient fusedLocationProviderClient; - private Task mockTask; - private Task mockLocationTask; - - @Before - public void setUp() { - location = mock(Location.class); - when(location.getLatitude()).thenReturn(1.0); - when(location.getLongitude()).thenReturn(2.0); - locationList.clear(); - locationList.add(location); - fusedLocationProviderClient = mock(FusedLocationProviderClient.class); - mockTask = mock(Task.class); - mockLocationTask = mock(Task.class); - when(fusedLocationProviderClient.getLastLocation()).thenReturn(mockLocationTask); - when(fusedLocationProviderClient - .requestLocationUpdates(any(LocationRequest.class), any(LocationCallback.class), any(Looper.class))) - .thenAnswer(new Answer>() { - @Override - public Task answer(InvocationOnMock invocation) { - LocationCallback listener = (LocationCallback) invocation.getArguments()[1]; - listener.onLocationResult(LocationResult.create(locationList)); - return mockTask; - } - }); - - engine = new LocationEngineProxy<>(new GoogleLocationEngineImpl(fusedLocationProviderClient)); - } - - @Test - public void checkGetLastLocation() throws InterruptedException { - final CountDownLatch latch = new CountDownLatch(1); - - when(mockLocationTask.addOnSuccessListener(any(OnSuccessListener.class))) - .thenAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - OnSuccessListener listener = (OnSuccessListener) invocation.getArguments()[0]; - listener.onSuccess(location); - return mock(Task.class); - } - }); - engine.getLastLocation(new LocationEngineCallback() { - @Override - public void onSuccess(LocationEngineResult result) { - List list = result.getLocations(); - assertEquals(1, list.size()); - assertEquals(1.0, list.get(0).getLatitude(), 0); - assertEquals(2.0, list.get(0).getLongitude(), 0); - latch.countDown(); - } - - @Override - public void onFailure(@NonNull Exception exception) { - - } - }); - assertTrue(latch.await(1, TimeUnit.SECONDS)); - } - - @Test - public void checkRequestAndRemoveLocationUpdates() throws InterruptedException { - final CountDownLatch latch = new CountDownLatch(1); - - LocationEngineCallback engineCallback = new LocationEngineCallback() { - @Override - public void onSuccess(LocationEngineResult result) { - List list = result.getLocations(); - assertEquals(1, list.size()); - assertEquals(1.0, list.get(0).getLatitude(), 0); - assertEquals(2.0, list.get(0).getLongitude(), 0); - latch.countDown(); - } - - @Override - public void onFailure(@NonNull Exception exception) { - - } - }; - engine.requestLocationUpdates(getRequest(INTERVAL, LocationEngineRequest.PRIORITY_HIGH_ACCURACY), - engineCallback, mock(Looper.class)); - assertTrue(latch.await(1, TimeUnit.SECONDS)); - - assertNotNull(engine.removeListener(engineCallback)); - } - - private static LocationEngineRequest getRequest(long interval, int priority) { - return new LocationEngineRequest.Builder(interval).setPriority(priority).build(); - } -} diff --git a/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/location/engine/GoogleLocationEngineImplTest.java b/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/location/engine/GoogleLocationEngineImplTest.java deleted file mode 100644 index a0305137052..00000000000 --- a/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/location/engine/GoogleLocationEngineImplTest.java +++ /dev/null @@ -1,66 +0,0 @@ -package com.mapbox.mapboxsdk.location.engine; - -import android.app.PendingIntent; - -import com.google.android.gms.location.FusedLocationProviderClient; -import com.google.android.gms.location.LocationCallback; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.junit.MockitoJUnitRunner; - -import static org.mockito.Mockito.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.reset; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -@RunWith(MockitoJUnitRunner.class) -public class GoogleLocationEngineImplTest { - @Mock - private FusedLocationProviderClient fusedLocationProviderClientMock; - - private LocationEngine engine; - private GoogleLocationEngineImpl googleLocationEngineImpl; - - @Before - public void setUp() { - googleLocationEngineImpl = new GoogleLocationEngineImpl(fusedLocationProviderClientMock); - engine = new LocationEngineProxy<>(googleLocationEngineImpl); - } - - @Test - public void removeLocationUpdatesForInvalidListener() { - LocationEngineCallback callback = mock(LocationEngineCallback.class); - engine.removeLocationUpdates(callback); - verify(fusedLocationProviderClientMock, never()).removeLocationUpdates(any(LocationCallback.class)); - } - - @Test - public void removeLocationUpdatesForPendingIntent() { - PendingIntent pendingIntent = mock(PendingIntent.class); - engine.removeLocationUpdates(pendingIntent); - verify(fusedLocationProviderClientMock, times(1)) - .removeLocationUpdates(any(PendingIntent.class)); - } - - @Test(expected = NullPointerException.class) - public void getLastLocationNullCallback() { - engine.getLastLocation(null); - } - - @Test(expected = NullPointerException.class) - public void requestLocationUpdatesNullCallback() { - engine.requestLocationUpdates(null, null, null); - } - - @After - public void tearDown() { - reset(fusedLocationProviderClientMock); - engine = null; - } -} diff --git a/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/location/engine/LocationEngineProviderTest.java b/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/location/engine/LocationEngineProviderTest.java deleted file mode 100644 index 34a7280c589..00000000000 --- a/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/location/engine/LocationEngineProviderTest.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.mapbox.mapboxsdk.location.engine; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.junit.MockitoJUnitRunner; - -@RunWith(MockitoJUnitRunner.class) -public class LocationEngineProviderTest { - - @Test(expected = NullPointerException.class) - public void passNullContext() { - LocationEngineProvider.getBestLocationEngine(null, false); - } -} diff --git a/platform/android/MapboxGLAndroidSDKTestApp/build.gradle b/platform/android/MapboxGLAndroidSDKTestApp/build.gradle index c44858bc540..98939db22d4 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/build.gradle +++ b/platform/android/MapboxGLAndroidSDKTestApp/build.gradle @@ -74,7 +74,6 @@ dependencies { implementation dependenciesList.multidex - implementation dependenciesList.gmsLocation implementation dependenciesList.timber implementation dependenciesList.okhttp3 diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/StyleLoaderTest.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/StyleLoaderTest.kt index a5e8c7676ed..2a804e45cdb 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/StyleLoaderTest.kt +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/StyleLoaderTest.kt @@ -71,4 +71,4 @@ class StyleLoaderTest : EspressoTest() { } } } -} \ No newline at end of file +} diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/utils/FontUtilsTest.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/utils/FontUtilsTest.kt index ed03b5999aa..05b1ac20fc3 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/utils/FontUtilsTest.kt +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/utils/FontUtilsTest.kt @@ -28,4 +28,4 @@ class FontUtilsTest { val actual = FontUtils.extractValidFont(null) Assert.assertNull(actual) } -} \ No newline at end of file +} diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/location/ManualLocationUpdatesActivity.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/location/ManualLocationUpdatesActivity.kt index 9d956caf776..439418a0c84 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/location/ManualLocationUpdatesActivity.kt +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/location/ManualLocationUpdatesActivity.kt @@ -10,7 +10,7 @@ import com.mapbox.mapboxsdk.geometry.LatLngBounds import com.mapbox.mapboxsdk.location.LocationComponent import com.mapbox.mapboxsdk.location.LocationComponentActivationOptions import com.mapbox.mapboxsdk.location.engine.LocationEngine -import com.mapbox.mapboxsdk.location.engine.LocationEngineProvider +import com.mapbox.mapboxsdk.location.engine.LocationEngineDefault import com.mapbox.mapboxsdk.location.engine.LocationEngineRequest import com.mapbox.mapboxsdk.location.modes.RenderMode import com.mapbox.mapboxsdk.location.permissions.PermissionsListener @@ -29,7 +29,7 @@ class ManualLocationUpdatesActivity : AppCompatActivity(), OnMapReadyCallback { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_location_manual_update) - locationEngine = LocationEngineProvider.getBestLocationEngine(this, false) + locationEngine = LocationEngineDefault.getDefaultLocationEngine(mapView.context) val fabManualUpdate = findViewById(R.id.fabManualLocationChange) fabManualUpdate.setOnClickListener { v: View? -> if (locationComponent != null && locationComponent!!.locationEngine == null) { diff --git a/platform/android/gradle/dependencies.gradle b/platform/android/gradle/dependencies.gradle index d82f60d345f..5aa68fd8fbc 100644 --- a/platform/android/gradle/dependencies.gradle +++ b/platform/android/gradle/dependencies.gradle @@ -75,7 +75,6 @@ ext { appCenter : "com.microsoft.appcenter:espresso-test-extension:${versions.appcenter}", commonsIO : "commons-io:commons-io:${versions.commonsIO}", - gmsLocation : "com.google.android.gms:play-services-location:${versions.gms}", timber : "com.jakewharton.timber:timber:${versions.timber}", okhttp3 : "com.squareup.okhttp3:okhttp:${versions.okhttp}", leakCanary : "com.squareup.leakcanary:leakcanary-android:${versions.leakCanary}",