summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAntonio Zugaldia <antonio@mapbox.com>2017-02-03 15:12:13 -0500
committerGitHub <noreply@github.com>2017-02-03 15:12:13 -0500
commitc97ec3be0397290e172299c49361f5033270f150 (patch)
treec66ceec30a95c484e5df9fabe1a22d8381bd8b19
parente5c9db47931174911f0403a1f640a5ae33814b60 (diff)
downloadqtlocation-mapboxgl-c97ec3be0397290e172299c49361f5033270f150.tar.gz
[android] Extract telemetry into MAS
* [android] add the mapbox-android-telemetry module dependency. * update javadoc
-rw-r--r--platform/android/MapboxGLAndroidSDK/build.gradle7
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/Mapbox.java9
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraPosition.java6
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraUpdateFactory.java2
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/GeoConstants.java38
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/TelemetryServiceNotConfiguredException.java22
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLng.java4
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/http/HTTPRequest.java2
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationListener.java17
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationServices.java213
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationSource.java144
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapGestureDetector.java58
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java10
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/TrackingSettings.java30
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationView.java30
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/GzipRequestInterceptor.java58
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/MapboxEvent.java161
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/MapboxEventManager.java828
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/TelemetryLocationReceiver.java70
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/TelemetryService.java156
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/package-info.java4
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/utils/MathUtils.java66
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/maps/widgets/MyLocationViewTest.java4
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml2
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MyLocationDrawableActivity.java13
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MyLocationTintActivity.java15
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MyLocationToggleActivity.java29
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/telemetry/ExponentialBackOffTest.java19
-rw-r--r--platform/android/MapboxGLAndroidSDKWearTestApp/src/main/AndroidManifest.xml2
29 files changed, 283 insertions, 1736 deletions
diff --git a/platform/android/MapboxGLAndroidSDK/build.gradle b/platform/android/MapboxGLAndroidSDK/build.gradle
index e4b1afe119..c3768db0a8 100644
--- a/platform/android/MapboxGLAndroidSDK/build.gradle
+++ b/platform/android/MapboxGLAndroidSDK/build.gradle
@@ -16,6 +16,11 @@ dependencies {
compile('com.mapbox.mapboxsdk:mapbox-java-geojson:2.0.0-SNAPSHOT@jar') {
transitive = true
}
+
+ // Mapbox Android Services (Telemetry support)
+ compile('com.mapbox.mapboxsdk:mapbox-android-telemetry:2.0.0-SNAPSHOT@aar') {
+ transitive = true
+ }
}
android {
@@ -25,8 +30,6 @@ android {
defaultConfig {
minSdkVersion Integer.parseInt(project.ANDROID_MIN_SDK)
targetSdkVersion Integer.parseInt(project.ANDROID_BUILD_TARGET_SDK_VERSION)
- buildConfigField "String", "MAPBOX_EVENTS_USER_AGENT_BASE", String.format("\"MapboxEventsAndroid/%s\"", project.VERSION_NAME)
- buildConfigField "String", "MAPBOX_VERSION_STRING", String.format("\"Mapbox/%s\"", project.VERSION_NAME)
buildConfigField "String", "GIT_REVISION_SHORT", String.format("\"%s\"", getGitRevision())
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/Mapbox.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/Mapbox.java
index 2abdb37041..f954073974 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/Mapbox.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/Mapbox.java
@@ -8,8 +8,11 @@ import android.text.TextUtils;
import com.mapbox.mapboxsdk.constants.MapboxConstants;
import com.mapbox.mapboxsdk.exceptions.InvalidAccessTokenException;
+import com.mapbox.mapboxsdk.location.LocationSource;
import com.mapbox.mapboxsdk.net.ConnectivityReceiver;
-import com.mapbox.mapboxsdk.telemetry.MapboxEventManager;
+import com.mapbox.services.android.telemetry.MapboxTelemetry;
+import com.mapbox.services.android.telemetry.location.LocationEngine;
+import com.mapbox.services.android.telemetry.location.LocationEnginePriority;
public final class Mapbox {
@@ -32,7 +35,9 @@ public final class Mapbox {
if (INSTANCE == null) {
Context appContext = context.getApplicationContext();
INSTANCE = new Mapbox(appContext, accessToken);
- MapboxEventManager.getMapboxEventManager().initialize(appContext, accessToken);
+ LocationEngine locationEngine = new LocationSource(appContext);
+ locationEngine.setPriority(LocationEnginePriority.NO_POWER);
+ MapboxTelemetry.getInstance().initialize(appContext, accessToken, locationEngine);
ConnectivityReceiver.instance(appContext);
}
return INSTANCE;
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraPosition.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraPosition.java
index 79045b68bb..941f13d812 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraPosition.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraPosition.java
@@ -7,9 +7,7 @@ import android.os.Parcelable;
import com.mapbox.mapboxsdk.R;
import com.mapbox.mapboxsdk.constants.MapboxConstants;
import com.mapbox.mapboxsdk.geometry.LatLng;
-import com.mapbox.mapboxsdk.utils.MathUtils;
-
-import static com.mapbox.mapboxsdk.utils.MathUtils.convertNativeBearing;
+import com.mapbox.services.android.telemetry.utils.MathUtils;
/**
* Resembles the position, angle, zoom and tilt of the user's viewpoint.
@@ -245,7 +243,7 @@ public final class CameraPosition implements Parcelable {
super();
if (nativeCameraValues != null && nativeCameraValues.length == 5) {
target(new LatLng(nativeCameraValues[0], nativeCameraValues[1]));
- bearing(convertNativeBearing(nativeCameraValues[2]));
+ bearing(MathUtils.convertNativeBearing(nativeCameraValues[2]));
tilt(nativeCameraValues[3]);
zoom(nativeCameraValues[4]);
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraUpdateFactory.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraUpdateFactory.java
index aecc51530b..fb0614c4a4 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraUpdateFactory.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraUpdateFactory.java
@@ -11,7 +11,7 @@ import com.mapbox.mapboxsdk.geometry.LatLngBounds;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.maps.Projection;
import com.mapbox.mapboxsdk.maps.UiSettings;
-import com.mapbox.mapboxsdk.utils.MathUtils;
+import com.mapbox.services.android.telemetry.utils.MathUtils;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/GeoConstants.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/GeoConstants.java
deleted file mode 100644
index 009ae936d5..0000000000
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/GeoConstants.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package com.mapbox.mapboxsdk.constants;
-
-/**
- * GeoConstants exposes constants for doing locational calculations on Earth
- */
-public class GeoConstants {
-
- /**
- * The <a href='http://en.wikipedia.org/wiki/Earth_radius#Equatorial_radius'>equatorial radius</a>
- * value in meters
- */
- public static final int RADIUS_EARTH_METERS = 6378137;
-
- /**
- * The minimum latitude on Earth. This is the minimum latitude representable
- * by Mapbox GL's Mercator projection, because the projection distorts latitude
- * near the poles towards infinity.
- */
- public static final double MIN_LATITUDE = -85.05112878;
-
- /**
- * The maximum latitude on Earth. This is the maximum latitude representable
- * by Mapbox GL's Mercator projection, because the projection distorts latitude
- * near the poles towards infinity.
- */
- public static final double MAX_LATITUDE = 85.05112878;
-
- /**
- * The minimum longitude on Earth
- */
- public static final double MIN_LONGITUDE = -180;
-
- /**
- * The maximum longitude on Earth
- */
- public static final double MAX_LONGITUDE = 180;
-
-}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/TelemetryServiceNotConfiguredException.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/TelemetryServiceNotConfiguredException.java
deleted file mode 100644
index 50dddd36e6..0000000000
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/TelemetryServiceNotConfiguredException.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package com.mapbox.mapboxsdk.exceptions;
-
-import android.os.Bundle;
-
-import com.mapbox.mapboxsdk.maps.MapView;
-
-/**
- * A {@code TelemetryServiceNotConfiguredException} is thrown by {@link MapView} when it checks and finds that
- * TelemetryService has not been configured in the app's AndroidManifest.xml {@link MapView#onCreate(Bundle)}
- *
- * @see MapView#onCreate(Bundle)
- */
-public class TelemetryServiceNotConfiguredException extends RuntimeException {
-
- public TelemetryServiceNotConfiguredException() {
- super("\nTelemetryService is not configured in your applications AndroidManifest.xml. "
- + "\nPlease add \"com.mapbox.mapboxsdk.telemetry.TelemetryService\" service in your applications "
- + "AndroidManifest.xml"
- + "\nFor an example visit http://goo.gl/cET0Jn. For more information visit https://www.mapbox.com/android-sdk/.");
- }
-
-}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLng.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLng.java
index b18b7e87b0..a6a86e7e1c 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLng.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLng.java
@@ -4,8 +4,8 @@ import android.location.Location;
import android.os.Parcel;
import android.os.Parcelable;
-import com.mapbox.mapboxsdk.constants.GeoConstants;
-import com.mapbox.mapboxsdk.utils.MathUtils;
+import com.mapbox.services.android.telemetry.constants.GeoConstants;
+import com.mapbox.services.android.telemetry.utils.MathUtils;
/**
* A geographical location which contains a single latitude, longitude pair, with
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/http/HTTPRequest.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/http/HTTPRequest.java
index 9c8cda5544..cedc5fe46c 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/http/HTTPRequest.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/http/HTTPRequest.java
@@ -183,7 +183,7 @@ class HTTPRequest implements Callback {
return USER_AGENT_STRING = Util.toHumanReadableAscii(
String.format("%s %s (%s) Android/%s (%s)",
getApplicationIdentifier(),
- BuildConfig.MAPBOX_VERSION_STRING,
+ com.mapbox.services.android.telemetry.BuildConfig.MAPBOX_VERSION_STRING,
BuildConfig.GIT_REVISION_SHORT,
Build.VERSION.SDK_INT,
Build.CPU_ABI)
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationListener.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationListener.java
deleted file mode 100644
index 7d86d8b096..0000000000
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationListener.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package com.mapbox.mapboxsdk.location;
-
-import android.location.Location;
-
-/**
- * Callback interface for when a location change occurs.
- */
-public interface LocationListener {
-
- /**
- * Callback method for receiving location updates from LocationServices.
- *
- * @param location The new Location data
- */
- void onLocationChanged(Location location);
-
-}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationServices.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationServices.java
deleted file mode 100644
index 364d925d37..0000000000
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationServices.java
+++ /dev/null
@@ -1,213 +0,0 @@
-package com.mapbox.mapboxsdk.location;
-
-import android.Manifest;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.location.Location;
-import android.location.LocationManager;
-import android.support.annotation.NonNull;
-import android.support.v4.content.ContextCompat;
-import android.support.v4.content.LocalBroadcastManager;
-
-import timber.log.Timber;
-
-import com.mapbox.mapboxsdk.telemetry.TelemetryLocationReceiver;
-import com.mapzen.android.lost.api.LocationRequest;
-import com.mapzen.android.lost.api.LostApiClient;
-
-import java.util.concurrent.CopyOnWriteArrayList;
-
-import static com.mapzen.android.lost.api.LocationServices.FusedLocationApi;
-
-/**
- * Manages locational updates. Contains methods to register and unregister location listeners.
- * <ul>
- * <li>You can register a {@link LocationListener} with {@link #addLocationListener(LocationListener)} to receive
- * location updates.</li>
- * <li> You can unregister a {@link LocationListener} with {@link #removeLocationListener(LocationListener)}.</li>
- * </ul>
- * <p>
- * Note: If registering a listener in your Activity.onStart() implementation, you should unregister it in
- * Activity.onStop(). (You won't receive location updates when paused, and this will cut down on unnecessary system
- * overhead). Do not unregister in Activity.onSaveInstanceState(), because this won't be called if the user moves back
- * in the history stack.
- * </p>
- */
-public class LocationServices implements LostApiClient.ConnectionCallbacks,
- com.mapzen.android.lost.api.LocationListener {
-
- private static LocationServices instance;
-
- private Context context;
- private LostApiClient locationClient;
- private Location lastLocation;
-
- private CopyOnWriteArrayList<LocationListener> locationListeners;
-
- private boolean isGpsEnabled;
-
- /**
- * Private constructor for singleton LocationServices
- */
- private LocationServices(Context context) {
- super();
- this.context = context;
- // Setup location services
- locationClient = new LostApiClient.Builder(context).addConnectionCallbacks(this).build();
- locationListeners = new CopyOnWriteArrayList<>();
- }
-
- /**
- * Primary (singleton) access method for LocationServices
- *
- * @param context Context
- * @return LocationServices
- */
- public static LocationServices getLocationServices(@NonNull final Context context) {
- if (instance == null) {
- instance = new LocationServices(context.getApplicationContext());
- }
- return instance;
- }
-
- /**
- * Enabled / Disable GPS focused location tracking
- *
- * @param enableGPS true if GPS is to be enabled, false if GPS is to be disabled
- */
- public void toggleGPS(boolean enableGPS) {
- if (!areLocationPermissionsGranted()) {
- Timber.w("Location Permissions Not Granted Yet. Try again after requesting.");
- return;
- }
-
- // Disconnect
- if (locationClient.isConnected()) {
- // Disconnect first to ensure that the new requests are GPS
- FusedLocationApi.removeLocationUpdates(locationClient, this);
- locationClient.disconnect();
- }
- isGpsEnabled = enableGPS;
-
- // Setup Fresh
- locationClient.connect();
- }
-
- @Override
- public void onConnected() {
- // noinspection MissingPermission
- Location lastLocation = FusedLocationApi.getLastLocation(locationClient);
- if (lastLocation != null) {
- this.lastLocation = lastLocation;
- }
-
- LocationRequest locationRequest;
-
- if (isGpsEnabled) {
- // LocationRequest Tuned for GPS
- locationRequest = LocationRequest.create()
- .setFastestInterval(1000)
- .setSmallestDisplacement(3.0f)
- .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
- // noinspection MissingPermission
- FusedLocationApi.requestLocationUpdates(locationClient, locationRequest, this);
- } else {
- // LocationRequest Tuned for PASSIVE
- locationRequest = LocationRequest.create()
- .setFastestInterval(1000)
- .setSmallestDisplacement(3.0f)
- .setPriority(LocationRequest.PRIORITY_NO_POWER);
- // noinspection MissingPermission
- FusedLocationApi.requestLocationUpdates(locationClient, locationRequest, this);
- }
- }
-
- @Override
- public void onConnectionSuspended() {
- }
-
- /**
- * Returns if the GPS sensor is currently enabled
- *
- * @return active state of the GPS
- */
- public boolean isGpsEnabled() {
- return isGpsEnabled;
- }
-
- /**
- * Called when the location has changed.
- *
- * @param location The updated location
- */
- @Override
- public void onLocationChanged(Location location) {
- // Timber.d("onLocationChanged()..." + location);
- this.lastLocation = location;
-
- // Update Listeners
- for (LocationListener listener : this.locationListeners) {
- listener.onLocationChanged(location);
- }
-
- // Update the Telemetry Receiver
- Intent locIntent = new Intent(TelemetryLocationReceiver.INTENT_STRING);
- locIntent.putExtra(LocationManager.KEY_LOCATION_CHANGED, location);
- LocalBroadcastManager.getInstance(context.getApplicationContext()).sendBroadcast(locIntent);
- }
-
- /**
- * Last known location
- *
- * @return Last known location data
- */
- public Location getLastLocation() {
- return lastLocation;
- }
-
- /**
- * Registers a LocationListener to receive location updates
- *
- * @param locationListener LocationListener
- */
- public void addLocationListener(@NonNull LocationListener locationListener) {
- if (!this.locationListeners.contains(locationListener)) {
- this.locationListeners.add(locationListener);
- }
- }
-
- /**
- * Unregister a LocationListener to stop receiving location updates
- *
- * @param locationListener LocationListener to remove
- * @return True if LocationListener was found and removed, False if it was not
- */
- public boolean removeLocationListener(@NonNull LocationListener locationListener) {
- return this.locationListeners.remove(locationListener);
- }
-
- /**
- * Check status of Location Permissions
- *
- * @return True if granted to the app, False if not
- */
- public boolean areLocationPermissionsGranted() {
- if ((ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION)
- != PackageManager.PERMISSION_GRANTED)
- && (ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION)
- != PackageManager.PERMISSION_GRANTED)) {
- Timber.w("Location Permissions Not Granted Yet. Try again after requesting.");
- return false;
- }
- return true;
- }
-
- @Override
- public void onProviderDisabled(String provider) {
- }
-
- @Override
- public void onProviderEnabled(String provider) {
- }
-}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationSource.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationSource.java
new file mode 100644
index 0000000000..ff367abe1f
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationSource.java
@@ -0,0 +1,144 @@
+package com.mapbox.mapboxsdk.location;
+
+import android.content.Context;
+import android.location.Location;
+import android.util.Log;
+
+import com.mapbox.services.android.telemetry.location.LocationEngine;
+import com.mapbox.services.android.telemetry.location.LocationEngineListener;
+import com.mapbox.services.android.telemetry.location.LocationEnginePriority;
+import com.mapbox.services.android.telemetry.permissions.PermissionsManager;
+import com.mapzen.android.lost.api.LocationListener;
+import com.mapzen.android.lost.api.LocationRequest;
+import com.mapzen.android.lost.api.LocationServices;
+import com.mapzen.android.lost.api.LostApiClient;
+
+/**
+ * Manages locational updates. Contains methods to register and unregister location listeners.
+ * <ul>
+ * <li>You can register a {@link LocationEngineListener} with
+ * {@link #addLocationEngineListener(LocationEngineListener)} to receive
+ * location updates.</li>
+ * <li> You can unregister a {@link LocationEngineListener} with
+ * {@link #removeLocationEngineListener(LocationEngineListener)} to stop receiving location updates.</li>
+ * </ul>
+ * <p>
+ * Note: If registering a listener in your Activity.onStart() implementation, you should unregister it in
+ * Activity.onStop(). (You won't receive location updates when paused, and this will cut down on unnecessary system
+ * overhead). Do not unregister in Activity.onSaveInstanceState(), because this won't be called if the user moves back
+ * in the history stack.
+ * </p>
+ */
+public class LocationSource extends LocationEngine implements
+ LostApiClient.ConnectionCallbacks, LocationListener {
+
+ private static final String LOG_TAG = LocationSource.class.getSimpleName();
+
+ private static LocationEngine instance;
+
+ private Context context;
+ private LostApiClient lostApiClient;
+
+ public LocationSource(Context context) {
+ super();
+ this.context = context;
+ lostApiClient = new LostApiClient.Builder(context)
+ .addConnectionCallbacks(this)
+ .build();
+ }
+
+ public static synchronized LocationEngine getLocationEngine(Context context) {
+ if (instance == null) {
+ instance = new LocationSource(context.getApplicationContext());
+ }
+
+ return instance;
+ }
+
+ @Override
+ public void activate() {
+ if (lostApiClient != null && !lostApiClient.isConnected()) {
+ lostApiClient.connect();
+ }
+ }
+
+ @Override
+ public void deactivate() {
+ if (lostApiClient != null && lostApiClient.isConnected()) {
+ lostApiClient.disconnect();
+ }
+ }
+
+ @Override
+ public boolean isConnected() {
+ return lostApiClient.isConnected();
+ }
+
+ @Override
+ public void onConnected() {
+ for (LocationEngineListener listener : locationListeners) {
+ listener.onConnected();
+ }
+ }
+
+ @Override
+ public void onConnectionSuspended() {
+ Log.d(LOG_TAG, "Connection suspended.");
+ }
+
+ @Override
+ public Location getLastLocation() {
+ if (lostApiClient.isConnected() && PermissionsManager.areLocationPermissionsGranted(context)) {
+ //noinspection MissingPermission
+ return LocationServices.FusedLocationApi.getLastLocation(lostApiClient);
+ }
+
+ return null;
+ }
+
+ @Override
+ public void requestLocationUpdates() {
+ // Common params
+ LocationRequest request = LocationRequest.create()
+ .setFastestInterval(1000)
+ .setSmallestDisplacement(3.0f);
+
+ // Priority matching is straightforward
+ if (priority == LocationEnginePriority.NO_POWER) {
+ request.setPriority(LocationRequest.PRIORITY_NO_POWER);
+ } else if (priority == LocationEnginePriority.LOW_POWER) {
+ request.setPriority(LocationRequest.PRIORITY_LOW_POWER);
+ } else if (priority == LocationEnginePriority.BALANCED_POWER_ACCURACY) {
+ request.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
+ } else if (priority == LocationEnginePriority.HIGH_ACCURACY) {
+ request.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
+ }
+
+ if (lostApiClient.isConnected() && PermissionsManager.areLocationPermissionsGranted(context)) {
+ //noinspection MissingPermission
+ LocationServices.FusedLocationApi.requestLocationUpdates(lostApiClient, request, this);
+ }
+ }
+
+ @Override
+ public void removeLocationUpdates() {
+ LocationServices.FusedLocationApi.removeLocationUpdates(lostApiClient, this);
+ }
+
+ @Override
+ public void onLocationChanged(Location location) {
+ for (LocationEngineListener listener : locationListeners) {
+ listener.onLocationChanged(location);
+ }
+ }
+
+ @Override
+ public void onProviderDisabled(String provider) {
+ Log.d(LOG_TAG, "Provider disabled: " + provider);
+ }
+
+ @Override
+ public void onProviderEnabled(String provider) {
+ Log.d(LOG_TAG, "Provider enabled: " + provider);
+ }
+}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapGestureDetector.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapGestureDetector.java
index bdd5ae1c1b..b73a74c433 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapGestureDetector.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapGestureDetector.java
@@ -2,6 +2,7 @@ package com.mapbox.mapboxsdk.maps;
import android.content.Context;
import android.graphics.PointF;
+import android.location.Location;
import android.support.annotation.NonNull;
import android.support.v4.view.GestureDetectorCompat;
import android.support.v4.view.ScaleGestureDetectorCompat;
@@ -15,8 +16,11 @@ import com.almeros.android.multitouch.gesturedetectors.RotateGestureDetector;
import com.almeros.android.multitouch.gesturedetectors.ShoveGestureDetector;
import com.almeros.android.multitouch.gesturedetectors.TwoFingerGestureDetector;
import com.mapbox.mapboxsdk.constants.MapboxConstants;
-import com.mapbox.mapboxsdk.telemetry.MapboxEvent;
-import com.mapbox.mapboxsdk.utils.MathUtils;
+import com.mapbox.mapboxsdk.geometry.LatLng;
+import com.mapbox.services.android.telemetry.MapboxEvent;
+import com.mapbox.services.android.telemetry.MapboxTelemetry;
+import com.mapbox.services.android.telemetry.utils.MathUtils;
+import com.mapbox.services.android.telemetry.utils.TelemetryUtils;
/**
* Manages gestures events on a MapView.
@@ -88,6 +92,18 @@ final class MapGestureDetector {
this.focalPoint = focalPoint;
}
+ /**
+ * Given coordinates from a gesture, use the current projection to translate it into
+ * a Location object.
+ *
+ * @param x coordinate
+ * @param y coordinate
+ * @return location
+ */
+ private Location getLocationFromGesture(float x, float y) {
+ LatLng latLng = projection.fromScreenLocation(new PointF(x, y));
+ return TelemetryUtils.buildLocation(latLng.getLongitude(), latLng.getLatitude());
+ }
/**
* Called when user touches the screen, all positions are absolute.
@@ -123,8 +139,9 @@ final class MapGestureDetector {
&& uiSettings.isZoomGesturesEnabled();
if (twoTap) {
// Confirmed 2nd Finger Down
- MapboxEvent.trackGestureEvent(projection,
- MapboxEvent.GESTURE_TWO_FINGER_SINGLETAP, event.getX(), event.getY(), transform.getZoom());
+ MapboxTelemetry.getInstance().pushEvent(MapboxEvent.buildMapClickEvent(
+ getLocationFromGesture(event.getX(), event.getY()),
+ MapboxEvent.GESTURE_TWO_FINGER_SINGLETAP, transform.getZoom()));
}
break;
@@ -153,7 +170,8 @@ final class MapGestureDetector {
// Scroll / Pan Has Stopped
if (scrollInProgress) {
- MapboxEvent.trackGestureDragEndEvent(projection, event.getX(), event.getY(), transform.getZoom());
+ MapboxTelemetry.getInstance().pushEvent(MapboxEvent.buildMapDragEndEvent(
+ getLocationFromGesture(event.getX(), event.getY()), transform.getZoom()));
scrollInProgress = false;
}
@@ -252,7 +270,9 @@ final class MapGestureDetector {
break;
}
- MapboxEvent.trackGestureEvent(projection, MapboxEvent.GESTURE_DOUBLETAP, e.getX(), e.getY(), transform.getZoom());
+ MapboxTelemetry.getInstance().pushEvent(MapboxEvent.buildMapClickEvent(
+ getLocationFromGesture(e.getX(), e.getY()),
+ MapboxEvent.GESTURE_DOUBLETAP, transform.getZoom()));
return true;
}
@@ -281,8 +301,10 @@ final class MapGestureDetector {
}
}
- MapboxEvent.trackGestureEvent(projection,
- MapboxEvent.GESTURE_SINGLETAP, motionEvent.getX(), motionEvent.getY(), transform.getZoom());
+ MapboxTelemetry.getInstance().pushEvent(MapboxEvent.buildMapClickEvent(
+ getLocationFromGesture(motionEvent.getX(), motionEvent.getY()),
+ MapboxEvent.GESTURE_SINGLETAP, transform.getZoom()));
+
return true;
}
@@ -341,8 +363,9 @@ final class MapGestureDetector {
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
if (!scrollInProgress) {
scrollInProgress = true;
- MapboxEvent.trackGestureEvent(projection,
- MapboxEvent.GESTURE_PAN_START, e1.getX(), e1.getY(), transform.getZoom());
+ MapboxTelemetry.getInstance().pushEvent(MapboxEvent.buildMapClickEvent(
+ getLocationFromGesture(e1.getX(), e1.getY()),
+ MapboxEvent.GESTURE_PAN_START, transform.getZoom()));
}
if (!trackingSettings.isScrollGestureCurrentlyEnabled()) {
return false;
@@ -384,8 +407,9 @@ final class MapGestureDetector {
scaleGestureOccurred = true;
beginTime = detector.getEventTime();
- MapboxEvent.trackGestureEvent(projection,
- MapboxEvent.GESTURE_PINCH_START, detector.getFocusX(), detector.getFocusY(), transform.getZoom());
+ MapboxTelemetry.getInstance().pushEvent(MapboxEvent.buildMapClickEvent(
+ getLocationFromGesture(detector.getFocusX(), detector.getFocusY()),
+ MapboxEvent.GESTURE_PINCH_START, transform.getZoom()));
return true;
}
@@ -475,8 +499,9 @@ final class MapGestureDetector {
}
beginTime = detector.getEventTime();
- MapboxEvent.trackGestureEvent(projection,
- MapboxEvent.GESTURE_ROTATION_START, detector.getFocusX(), detector.getFocusY(), transform.getZoom());
+ MapboxTelemetry.getInstance().pushEvent(MapboxEvent.buildMapClickEvent(
+ getLocationFromGesture(detector.getFocusX(), detector.getFocusY()),
+ MapboxEvent.GESTURE_ROTATION_START, transform.getZoom()));
return true;
}
@@ -555,8 +580,9 @@ final class MapGestureDetector {
}
beginTime = detector.getEventTime();
- MapboxEvent.trackGestureEvent(projection,
- MapboxEvent.GESTURE_PITCH_START, detector.getFocusX(), detector.getFocusY(), transform.getZoom());
+ MapboxTelemetry.getInstance().pushEvent(MapboxEvent.buildMapClickEvent(
+ getLocationFromGesture(detector.getFocusX(), detector.getFocusY()),
+ MapboxEvent.GESTURE_PITCH_START, transform.getZoom()));
return true;
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java
index 9476ba186e..fd4c8945ed 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java
@@ -45,8 +45,8 @@ import com.mapbox.mapboxsdk.constants.Style;
import com.mapbox.mapboxsdk.maps.widgets.CompassView;
import com.mapbox.mapboxsdk.maps.widgets.MyLocationView;
import com.mapbox.mapboxsdk.maps.widgets.MyLocationViewSettings;
-import com.mapbox.mapboxsdk.telemetry.MapboxEvent;
-import com.mapbox.mapboxsdk.telemetry.MapboxEventManager;
+import com.mapbox.services.android.telemetry.MapboxEvent;
+import com.mapbox.services.android.telemetry.MapboxTelemetry;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -205,7 +205,7 @@ public class MapView extends FrameLayout {
nativeMapView.setAccessToken(Mapbox.getAccessToken());
if (savedInstanceState == null) {
- MapboxEvent.trackMapLoadEvent();
+ MapboxTelemetry.getInstance().pushEvent(MapboxEvent.buildMapLoadEvent());
} else if (savedInstanceState.getBoolean(MapboxConstants.STATE_HAS_SAVED_STATE)) {
mapboxMap.onRestoreInstanceState(savedInstanceState);
}
@@ -666,7 +666,7 @@ public class MapView extends FrameLayout {
builder.setPositiveButton(R.string.mapbox_attributionTelemetryPositive, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
- MapboxEventManager.getMapboxEventManager().setTelemetryEnabled(true);
+ MapboxTelemetry.getInstance().setTelemetryEnabled(true);
dialog.cancel();
}
});
@@ -683,7 +683,7 @@ public class MapView extends FrameLayout {
builder.setNegativeButton(R.string.mapbox_attributionTelemetryNegative, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
- MapboxEventManager.getMapboxEventManager().setTelemetryEnabled(false);
+ MapboxTelemetry.getInstance().setTelemetryEnabled(false);
dialog.cancel();
}
});
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/TrackingSettings.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/TrackingSettings.java
index 16214731c6..38f307f149 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/TrackingSettings.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/TrackingSettings.java
@@ -1,21 +1,19 @@
package com.mapbox.mapboxsdk.maps;
-import android.Manifest;
-import android.content.pm.PackageManager;
import android.location.Location;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.UiThread;
-import android.support.v4.content.ContextCompat;
import com.mapbox.mapboxsdk.camera.CameraPosition;
import com.mapbox.mapboxsdk.constants.MapboxConstants;
import com.mapbox.mapboxsdk.constants.MyBearingTracking;
import com.mapbox.mapboxsdk.constants.MyLocationTracking;
-import com.mapbox.mapboxsdk.location.LocationListener;
-import com.mapbox.mapboxsdk.location.LocationServices;
+import com.mapbox.mapboxsdk.location.LocationSource;
import com.mapbox.mapboxsdk.maps.widgets.MyLocationView;
+import com.mapbox.services.android.telemetry.location.LocationEngineListener;
+import com.mapbox.services.android.telemetry.permissions.PermissionsManager;
import timber.log.Timber;
@@ -28,7 +26,7 @@ public final class TrackingSettings {
private final UiSettings uiSettings;
private final FocalPointChangeListener focalPointChangedListener;
private final CameraZoomInvalidator zoomInvalidator;
- private LocationListener myLocationListener;
+ private LocationEngineListener myLocationListener;
private boolean myLocationEnabled;
private boolean dismissLocationTrackingOnGesture = true;
@@ -317,7 +315,12 @@ public final class TrackingSettings {
void setOnMyLocationChangeListener(@Nullable final MapboxMap.OnMyLocationChangeListener listener) {
if (listener != null) {
- myLocationListener = new LocationListener() {
+ myLocationListener = new LocationEngineListener() {
+ @Override
+ public void onConnected() {
+ // Nothing
+ }
+
@Override
public void onLocationChanged(Location location) {
if (listener != null) {
@@ -325,20 +328,13 @@ public final class TrackingSettings {
}
}
};
- LocationServices.getLocationServices(myLocationView.getContext()).addLocationListener(myLocationListener);
+ LocationSource.getLocationEngine(myLocationView.getContext()).addLocationEngineListener(myLocationListener);
} else {
- LocationServices.getLocationServices(myLocationView.getContext()).removeLocationListener(myLocationListener);
+ LocationSource.getLocationEngine(myLocationView.getContext()).removeLocationEngineListener(myLocationListener);
myLocationListener = null;
}
}
- boolean isPermissionsAccepted() {
- return (ContextCompat.checkSelfPermission(myLocationView.getContext(),
- Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED)
- || ContextCompat.checkSelfPermission(myLocationView.getContext(),
- Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED;
- }
-
void setOnMyLocationTrackingModeChangeListener(MapboxMap.OnMyLocationTrackingModeChangeListener listener) {
this.onMyLocationTrackingModeChangeListener = listener;
}
@@ -357,7 +353,7 @@ public final class TrackingSettings {
}
void setMyLocationEnabled(boolean locationEnabled) {
- if (!isPermissionsAccepted()) {
+ if (!PermissionsManager.areLocationPermissionsGranted(myLocationView.getContext())) {
Timber.e("Could not activate user location tracking: "
+ "user did not accept the permission or permissions were not requested.");
return;
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationView.java
index c1f06cabc5..c9888c36d2 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationView.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationView.java
@@ -31,10 +31,12 @@ import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
import com.mapbox.mapboxsdk.constants.MyBearingTracking;
import com.mapbox.mapboxsdk.constants.MyLocationTracking;
import com.mapbox.mapboxsdk.geometry.LatLng;
-import com.mapbox.mapboxsdk.location.LocationListener;
-import com.mapbox.mapboxsdk.location.LocationServices;
+import com.mapbox.mapboxsdk.location.LocationSource;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.maps.Projection;
+import com.mapbox.services.android.telemetry.location.LocationEngine;
+import com.mapbox.services.android.telemetry.location.LocationEngineListener;
+import com.mapbox.services.android.telemetry.location.LocationEnginePriority;
import java.lang.ref.WeakReference;
@@ -367,8 +369,7 @@ public class MyLocationView extends View {
}
if (userLocationListener != null) {
- LocationServices services = LocationServices.getLocationServices(getContext());
- services.removeLocationListener(userLocationListener);
+ LocationSource.getLocationEngine(getContext()).removeLocationEngineListener(userLocationListener);
userLocationListener = null;
}
}
@@ -418,10 +419,10 @@ public class MyLocationView extends View {
* @param enableGps true if GPS is to be enabled, false if GPS is to be disabled
*/
private void toggleGps(boolean enableGps) {
- LocationServices locationServices = LocationServices.getLocationServices(getContext());
+ LocationEngine locationEngine = LocationSource.getLocationEngine(getContext());
if (enableGps) {
// Set an initial location if one available
- Location lastLocation = locationServices.getLastLocation();
+ Location lastLocation = locationEngine.getLastLocation();
if (lastLocation != null) {
setLocation(lastLocation);
@@ -431,14 +432,14 @@ public class MyLocationView extends View {
userLocationListener = new GpsLocationListener(this);
}
- locationServices.addLocationListener(userLocationListener);
+ locationEngine.addLocationEngineListener(userLocationListener);
} else {
// Disable location and user dot
location = null;
- locationServices.removeLocationListener(userLocationListener);
+ locationEngine.removeLocationEngineListener(userLocationListener);
}
- locationServices.toggleGPS(enableGps);
+ locationEngine.setPriority(LocationEnginePriority.HIGH_ACCURACY);
}
public Location getLocation() {
@@ -557,7 +558,7 @@ public class MyLocationView extends View {
contentPaddingY = (padding[1] - padding[3]) / 2;
}
- private static class GpsLocationListener implements LocationListener {
+ private static class GpsLocationListener implements LocationEngineListener {
private WeakReference<MyLocationView> userLocationView;
@@ -565,6 +566,15 @@ public class MyLocationView extends View {
userLocationView = new WeakReference<>(myLocationView);
}
+ @Override
+ public void onConnected() {
+ MyLocationView locationView = userLocationView.get();
+ if (locationView != null) {
+ Location location = LocationSource.getLocationEngine(locationView.getContext()).getLastLocation();
+ locationView.setLocation(location);
+ }
+ }
+
/**
* Callback method for receiving location updates from LocationServices.
*
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/GzipRequestInterceptor.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/GzipRequestInterceptor.java
deleted file mode 100644
index 8457d24ff2..0000000000
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/GzipRequestInterceptor.java
+++ /dev/null
@@ -1,58 +0,0 @@
-package com.mapbox.mapboxsdk.telemetry;
-
-import timber.log.Timber;
-
-import java.io.IOException;
-
-import okhttp3.Interceptor;
-import okhttp3.MediaType;
-import okhttp3.Request;
-import okhttp3.RequestBody;
-import okhttp3.Response;
-import okio.BufferedSink;
-import okio.GzipSink;
-import okio.Okio;
-
-/**
- * OkHttp Interceptor for Gzipping Telemetry Data requests to the server.
- * Based on: https://github.com/square/okhttp/wiki/Interceptors
- */
-public final class GzipRequestInterceptor implements Interceptor {
-
- @Override
- public Response intercept(Interceptor.Chain chain) throws IOException {
- Request originalRequest = chain.request();
- if (originalRequest.body() == null || originalRequest.header("Content-Encoding") != null) {
- Timber.d("Not compressing");
- return chain.proceed(originalRequest);
- }
-
- Timber.d("Compressing");
- Request compressedRequest = originalRequest.newBuilder()
- .header("Content-Encoding", "gzip")
- .method(originalRequest.method(), gzip(originalRequest.body()))
- .build();
- return chain.proceed(compressedRequest);
- }
-
- private RequestBody gzip(final RequestBody body) {
- return new RequestBody() {
- @Override
- public MediaType contentType() {
- return body.contentType();
- }
-
- @Override
- public long contentLength() {
- return -1; // We don't know the compressed length in advance!
- }
-
- @Override
- public void writeTo(BufferedSink sink) throws IOException {
- BufferedSink gzipSink = Okio.buffer(new GzipSink(sink));
- body.writeTo(gzipSink);
- gzipSink.close();
- }
- };
- }
-}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/MapboxEvent.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/MapboxEvent.java
deleted file mode 100644
index b5203bc02a..0000000000
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/MapboxEvent.java
+++ /dev/null
@@ -1,161 +0,0 @@
-package com.mapbox.mapboxsdk.telemetry;
-
-import android.graphics.PointF;
-import android.support.annotation.NonNull;
-
-import com.mapbox.mapboxsdk.geometry.LatLng;
-import com.mapbox.mapboxsdk.maps.Projection;
-
-import java.io.Serializable;
-import java.util.Hashtable;
-
-import timber.log.Timber;
-
-/**
- * Constants for Telemetry Metadata
- */
-public class MapboxEvent implements Serializable {
- public static final int VERSION_NUMBER = 2;
- public static final String MAPBOX_EVENTS_BASE_URL = "https://events.mapbox.com";
- public static final String SOURCE_MAPBOX = "mapbox";
-
- // Event Types
- public static final String TYPE_TURNSTILE = "appUserTurnstile";
- public static final String TYPE_MAP_LOAD = "map.load";
- public static final String TYPE_MAP_CLICK = "map.click";
- public static final String TYPE_MAP_DRAGEND = "map.dragend";
- public static final String TYPE_LOCATION = "location";
- public static final String TYPE_VISIT = "visit";
-
- // Event Keys
- public static final String KEY_LATITUDE = "lat";
- public static final String KEY_LONGITUDE = "lng";
- public static final String KEY_SPEED = "speed";
- public static final String KEY_COURSE = "course";
- public static final String KEY_ALTITUDE = "altitude";
- public static final String KEY_HORIZONTAL_ACCURACY = "horizontalAccuracy";
- public static final String KEY_ZOOM = "zoom";
-
- public static final String KEY_PUSH_ENABLED = "enabled.push";
- public static final String KEY_EMAIL_ENABLED = "enabled.email";
- public static final String KEY_GESTURE_ID = "gesture";
- public static final String KEY_ARRIVAL_DATE = "arrivalDate";
- public static final String KEY_DEPARTURE_DATE = "departureDate";
-
- public static final String GESTURE_SINGLETAP = "SingleTap";
- public static final String GESTURE_DOUBLETAP = "DoubleTap";
- public static final String GESTURE_TWO_FINGER_SINGLETAP = "TwoFingerTap";
- public static final String GESTURE_QUICK_ZOOM = "QuickZoom";
- public static final String GESTURE_PAN_START = "Pan";
- public static final String GESTURE_PINCH_START = "Pinch";
- public static final String GESTURE_ROTATION_START = "Rotation";
- public static final String GESTURE_PITCH_START = "Pitch";
-
- // Event Attributes
- public static final String ATTRIBUTE_EVENT = "event";
- public static final String ATTRIBUTE_USERID = "userId";
- public static final String ATTRIBUTE_SOURCE = "source";
- public static final String ATTRIBUTE_ENABLED_TELEMETRY = "enabled.telemetry";
- public static final String ATTRIBUTE_SESSION_ID = "sessionId";
- public static final String ATTRIBUTE_VERSION = "version";
- public static final String ATTRIBUTE_CREATED = "created";
- public static final String ATTRIBUTE_VENDOR_ID = "vendorId";
- public static final String ATTRIBUTE_APP_BUNDLE_ID = "appBundleId";
- public static final String ATTRIBUTE_MODEL = "model";
- public static final String ATTRIBUTE_OPERATING_SYSTEM = "operatingSystem";
- public static final String ATTRIBUTE_ORIENTATION = "orientation";
- public static final String ATTRIBUTE_BATTERY_LEVEL = "batteryLevel";
- public static final String ATTRIBUTE_PLUGGED_IN = "pluggedIn";
- public static final String ATTRIBUTE_APPLICATION_STATE = "applicationState";
- public static final String ATTRIBUTE_RESOLUTION = "resolution";
- public static final String ATTRIBUTE_ACCESSIBILITY_FONT_SCALE = "accessibilityFontScale";
- public static final String ATTRIBUTE_CARRIER = "carrier";
- public static final String ATTRIBUTE_CELLULAR_NETWORK_TYPE = "cellularNetworkType";
- public static final String ATTRIBUTE_WIFI = "wifi";
-
- /**
- * Helper method for tracking gesture events
- *
- * @param projection Projection of the Map object
- * @param gestureId Type of Gesture See {@see MapboxEvent#GESTURE_SINGLETAP
- * MapboxEvent#GESTURE_DOUBLETAP
- * MapboxEvent#GESTURE_TWO_FINGER_SINGLETAP
- * MapboxEvent#GESTURE_QUICK_ZOOM
- * MapboxEvent#GESTURE_PAN_START
- * MapboxEvent#GESTURE_PINCH_START
- * MapboxEvent#GESTURE_ROTATION_START
- * MapboxEvent#GESTURE_PITCH_START}
- * @param xCoordinate Original x screen coordinate at start of gesture
- * @param yCoordinate Original y screen cooridnate at start of gesture
- * @param zoom Zoom level to be registered
- */
- public static void trackGestureEvent(@NonNull Projection projection, @NonNull String gestureId, float xCoordinate,
- float yCoordinate, double zoom) {
- LatLng tapLatLng = projection.fromScreenLocation(new PointF(xCoordinate, yCoordinate));
-
- // NaN and Infinite checks to prevent JSON errors at send to server time
- if (Double.isNaN(tapLatLng.getLatitude()) || Double.isNaN(tapLatLng.getLongitude())) {
- Timber.d("trackGestureEvent() has a NaN lat or lon. Returning.");
- return;
- }
-
- if (Double.isInfinite(tapLatLng.getLatitude()) || Double.isInfinite(tapLatLng.getLongitude())) {
- Timber.d("trackGestureEvent() has an Infinite lat or lon. Returning.");
- return;
- }
-
- Hashtable<String, Object> evt = new Hashtable<>();
- evt.put(MapboxEvent.ATTRIBUTE_EVENT, MapboxEvent.TYPE_MAP_CLICK);
- evt.put(MapboxEvent.ATTRIBUTE_CREATED, MapboxEventManager.generateCreateDate());
- evt.put(MapboxEvent.KEY_GESTURE_ID, gestureId);
- evt.put(MapboxEvent.KEY_LATITUDE, tapLatLng.getLatitude());
- evt.put(MapboxEvent.KEY_LONGITUDE, tapLatLng.getLongitude());
- evt.put(MapboxEvent.KEY_ZOOM, zoom);
-
- MapboxEventManager.getMapboxEventManager().pushEvent(evt);
- }
-
- /**
- * Helper method for tracking DragEnd gesture event
- * See {@see MapboxEvent#TYPE_MAP_DRAGEND}
- *
- * @param projection projection of the Map object.
- * @param xCoordinate Original x screen coordinate at end of drag
- * @param yCoordinate Orginal y screen coordinate at end of drag
- * @param zoom Zoom level to be registered
- */
- public static void trackGestureDragEndEvent(@NonNull Projection projection, float xCoordinate, float yCoordinate,
- double zoom) {
- LatLng tapLatLng = projection.fromScreenLocation(new PointF(xCoordinate, yCoordinate));
-
- // NaN and Infinite checks to prevent JSON errors at send to server time
- if (Double.isNaN(tapLatLng.getLatitude()) || Double.isNaN(tapLatLng.getLongitude())) {
- Timber.d("trackGestureDragEndEvent() has a NaN lat or lon. Returning.");
- return;
- }
-
- if (Double.isInfinite(tapLatLng.getLatitude()) || Double.isInfinite(tapLatLng.getLongitude())) {
- Timber.d("trackGestureDragEndEvent() has an Infinite lat or lon. Returning.");
- return;
- }
-
- Hashtable<String, Object> evt = new Hashtable<>();
- evt.put(MapboxEvent.ATTRIBUTE_EVENT, MapboxEvent.TYPE_MAP_DRAGEND);
- evt.put(MapboxEvent.ATTRIBUTE_CREATED, MapboxEventManager.generateCreateDate());
- evt.put(MapboxEvent.KEY_LATITUDE, tapLatLng.getLatitude());
- evt.put(MapboxEvent.KEY_LONGITUDE, tapLatLng.getLongitude());
- evt.put(MapboxEvent.KEY_ZOOM, zoom);
-
- MapboxEventManager.getMapboxEventManager().pushEvent(evt);
- }
-
- /**
- * Helper method for tracking map load event
- */
- public static void trackMapLoadEvent() {
- Hashtable<String, Object> evt = new Hashtable<>();
- evt.put(MapboxEvent.ATTRIBUTE_EVENT, MapboxEvent.TYPE_MAP_LOAD);
- evt.put(MapboxEvent.ATTRIBUTE_CREATED, MapboxEventManager.generateCreateDate());
- MapboxEventManager.getMapboxEventManager().pushEvent(evt);
- }
-}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/MapboxEventManager.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/MapboxEventManager.java
deleted file mode 100644
index 89413f26f0..0000000000
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/MapboxEventManager.java
+++ /dev/null
@@ -1,828 +0,0 @@
-package com.mapbox.mapboxsdk.telemetry;
-
-import android.app.ActivityManager;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.SharedPreferences;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.ServiceInfo;
-import android.content.res.Configuration;
-import android.location.Location;
-import android.net.wifi.WifiInfo;
-import android.net.wifi.WifiManager;
-import android.os.AsyncTask;
-import android.os.BatteryManager;
-import android.os.Build;
-import android.os.Handler;
-import android.support.annotation.NonNull;
-import android.telephony.TelephonyManager;
-import android.text.TextUtils;
-import android.util.DisplayMetrics;
-import android.view.WindowManager;
-
-import com.mapbox.mapboxsdk.BuildConfig;
-import com.mapbox.mapboxsdk.Mapbox;
-import com.mapbox.mapboxsdk.constants.GeoConstants;
-import com.mapbox.mapboxsdk.constants.MapboxConstants;
-import com.mapbox.mapboxsdk.exceptions.TelemetryServiceNotConfiguredException;
-import com.mapbox.mapboxsdk.location.LocationServices;
-import com.mapbox.mapboxsdk.utils.MathUtils;
-
-import org.json.JSONArray;
-import org.json.JSONObject;
-
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.Hashtable;
-import java.util.List;
-import java.util.Timer;
-import java.util.TimerTask;
-import java.util.UUID;
-import java.util.Vector;
-
-import okhttp3.CertificatePinner;
-import okhttp3.MediaType;
-import okhttp3.OkHttpClient;
-import okhttp3.Request;
-import okhttp3.RequestBody;
-import okhttp3.Response;
-import okhttp3.internal.Util;
-import timber.log.Timber;
-
-/**
- * Singleton control center for managing Telemetry Data.
- * Primary access is via MapboxEventManager.getMapboxEventManager()
- */
-public class MapboxEventManager {
-
- private static MapboxEventManager mapboxEventManager = null;
-
- private boolean initialized = false;
- private boolean stagingEnv;
- private boolean telemetryEnabled;
-
- private final Vector<Hashtable<String, Object>> events = new Vector<>();
- private static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
- private static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ",
- MapboxConstants.MAPBOX_LOCALE);
-
- private Context context = null;
- private String accessToken = null;
- private String eventsURL = MapboxEvent.MAPBOX_EVENTS_BASE_URL;
-
- private String userAgent = BuildConfig.MAPBOX_EVENTS_USER_AGENT_BASE;
-
- private Intent batteryStatus = null;
- private final String operatingSystem = "Android - " + Build.VERSION.RELEASE;
-
- private DisplayMetrics displayMetrics = null;
-
- private String mapboxVendorId = null;
-
- private String mapboxSessionId = null;
- private long mapboxSessionIdLastSet = 0;
- private static long hourInMillis = 1000 * 60 * 60;
- private static long flushDelayInitialInMillis = 1000 * 10; // 10 Seconds
- private static long flushDelayInMillis = 1000 * 60 * 3; // 3 Minutes
- private static final int SESSION_ID_ROTATION_HOURS = 24;
-
- private static final int FLUSH_EVENTS_CAP = 1000;
-
- private static MessageDigest messageDigest = null;
-
- private static final double locationEventAccuracy = 10000000;
-
- private Timer timer = null;
-
- /**
- * Private Constructor for configuring the single instance per app.
- */
- private MapboxEventManager() {
- super();
- }
-
- /**
- * Internal setup of MapboxEventsManager. It needs to be called once before @link
- * MapboxEventManager#getMapboxEventManager
- * <p>
- * This allows for a cleaner getMapboxEventManager() that doesn't require context and accessToken
- *
- * @param context The context associated with MapView
- * @param accessToken The accessToken to load MapView
- */
- public void initialize(@NonNull Context context, @NonNull String accessToken) {
-
- // Timber.i("Telemetry initialize() called...");
-
- if (initialized) {
- // Timber.i("Mapbox Telemetry has already been initialized.");
- return;
- }
-
- this.context = context.getApplicationContext();
- this.accessToken = accessToken;
-
- validateTelemetryServiceConfigured();
-
- // Setup Message Digest
- try {
- messageDigest = MessageDigest.getInstance("SHA-1");
- } catch (NoSuchAlgorithmException exception) {
- Timber.w("Error getting Encryption Algorithm: ", exception);
- }
-
- // Create Initial Session Id
- rotateSessionId();
-
- SharedPreferences prefs = context.getSharedPreferences(MapboxConstants.MAPBOX_SHARED_PREFERENCES_FILE,
- Context.MODE_PRIVATE);
-
- // Determine if Telemetry Should Be Enabled
- /// Timber.i("Right before Telemetry set enabled in initialized()");
- setTelemetryEnabled(prefs.getBoolean(MapboxConstants.MAPBOX_SHARED_PREFERENCE_KEY_TELEMETRY_ENABLED, true));
-
- // Load / Create Vendor Id
- if (prefs.contains(MapboxConstants.MAPBOX_SHARED_PREFERENCE_KEY_VENDORID)) {
- mapboxVendorId = prefs.getString(MapboxConstants.MAPBOX_SHARED_PREFERENCE_KEY_VENDORID, "");
- }
- if (TextUtils.isEmpty(mapboxVendorId)) {
- String vendorId = UUID.randomUUID().toString();
- mapboxVendorId = encodeString(vendorId);
- SharedPreferences.Editor editor = prefs.edit();
- editor.putString(MapboxConstants.MAPBOX_SHARED_PREFERENCE_KEY_VENDORID, mapboxVendorId);
- editor.apply();
- editor.commit();
- }
-
- // Get DisplayMetrics Setup
- displayMetrics = new DisplayMetrics();
- ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getMetrics(displayMetrics);
-
- // Check for Staging Server Information
- try {
- ApplicationInfo appInfo = context.getPackageManager().getApplicationInfo(context.getPackageName(),
- PackageManager.GET_META_DATA);
- String stagingURL = appInfo.metaData.getString(MapboxConstants.KEY_META_DATA_STAGING_SERVER);
- String stagingAccessToken = appInfo.metaData.getString(MapboxConstants.KEY_META_DATA_STAGING_ACCESS_TOKEN);
-
- if (TextUtils.isEmpty(stagingURL) || TextUtils.isEmpty(stagingAccessToken)) {
- // Timber.d("Looking in SharedPreferences for Staging Credentials");
- stagingURL = prefs.getString(MapboxConstants.MAPBOX_SHARED_PREFERENCE_KEY_TELEMETRY_STAGING_URL, null);
- stagingAccessToken = prefs.getString(
- MapboxConstants.MAPBOX_SHARED_PREFERENCE_KEY_TELEMETRY_STAGING_ACCESS_TOKEN, null);
- }
-
- if (!TextUtils.isEmpty(stagingURL) && !TextUtils.isEmpty(stagingAccessToken)) {
- eventsURL = stagingURL;
- this.accessToken = accessToken;
- stagingEnv = true;
- }
-
- // Build User Agent
- String appIdentifier = getApplicationIdentifier();
- if (TextUtils.equals(userAgent, BuildConfig.MAPBOX_EVENTS_USER_AGENT_BASE) && !TextUtils.isEmpty(appIdentifier)) {
- userAgent = Util
- .toHumanReadableAscii(String.format(MapboxConstants.MAPBOX_LOCALE, "%s %s", appIdentifier, userAgent));
- }
-
- } catch (Exception exception) {
- // Timber.e("Error Trying to load Staging Credentials: ", exception);
- }
-
- // Register for battery updates
- IntentFilter iFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
- batteryStatus = context.registerReceiver(null, iFilter);
-
- initialized = true;
- }
-
- /**
- * Primary Access method using Singleton pattern
- *
- * @return MapboxEventManager
- */
- public static MapboxEventManager getMapboxEventManager() {
- if (mapboxEventManager == null) {
- mapboxEventManager = new MapboxEventManager();
- }
- return mapboxEventManager;
- }
-
- // Checks that TelemetryService has been configured by developer
- private void validateTelemetryServiceConfigured() {
- try {
- // Check Implementing app's AndroidManifest.xml
- PackageInfo packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(),
- PackageManager.GET_SERVICES);
- if (packageInfo.services != null) {
- for (ServiceInfo service : packageInfo.services) {
- if (TextUtils.equals("com.mapbox.mapboxsdk.telemetry.TelemetryService", service.name)) {
- return;
- }
- }
- }
- } catch (Exception exception) {
- // Timber.w("Error checking for Telemetry Service Config: ", exception);
- }
- throw new TelemetryServiceNotConfiguredException();
- }
-
- public static String generateCreateDate() {
- return dateFormat.format(new Date());
- }
-
- public boolean isTelemetryEnabled() {
- return telemetryEnabled;
- }
-
- /**
- * Enables / Disables Telemetry
- *
- * @param telemetryEnabled True to start telemetry, false to stop it
- */
- public void setTelemetryEnabled(boolean telemetryEnabled) {
- // Timber.i("this.telemetryEnabled = " + this.telemetryEnabled + "; telemetryEnabled = " + telemetryEnabled);
- if (this.telemetryEnabled == telemetryEnabled) {
- // Timber.d("No need to start / stop telemetry as it's already in that state.");
- return;
- }
-
- if (telemetryEnabled) {
- // Timber.d("Starting Telemetry Up!");
- // Start It Up
- context.startService(new Intent(context, TelemetryService.class));
-
- // Make sure Ambient Mode is started at a minimum
- if (LocationServices.getLocationServices(context).areLocationPermissionsGranted()) {
- // Timber.i("Permissions are good, see if GPS is enabled and if not then setup Ambient.");
- if (LocationServices.getLocationServices(context).isGpsEnabled()) {
- LocationServices.getLocationServices(context).toggleGPS(false);
- }
- } else {
- // Start timer that checks for Permissions
- // Timber.i("Permissions are not good. Need to do some looping to check on stuff.");
-
- final Handler permsHandler = new Handler();
- Runnable runnable = new Runnable() {
-
- private final ExponentialBackoffCounter exponentialBackoffCounter = new ExponentialBackoffCounter();
-
- @Override
- public void run() {
- if (LocationServices.getLocationServices(context).areLocationPermissionsGranted()) {
- // Timber.i("Permissions finally granted, so starting Ambient if GPS isn't already enabled");
- // Start Ambient
- if (LocationServices.getLocationServices(context).isGpsEnabled()) {
- LocationServices.getLocationServices(context).toggleGPS(false);
- }
- } else {
- // Restart Handler
- long nextWaitTime = exponentialBackoffCounter.getNextCount();
- // Timber.i("Permissions not granted yet... let's try again in " + nextWaitTime/1000 + " seconds");
- permsHandler.postDelayed(this, nextWaitTime);
- }
- }
- };
- permsHandler.postDelayed(runnable, 1000 * 10);
- }
-
- // Manage Timer Flush
- timer = new Timer();
- timer.schedule(new FlushEventsTimerTask(), flushDelayInitialInMillis, flushDelayInMillis);
- } else {
- // Timber.d("Shutting Telemetry Down");
- // Shut It Down
- events.removeAllElements();
- context.stopService(new Intent(context, TelemetryService.class));
-
- if (timer != null) {
- timer.cancel();
- timer = null;
- }
- }
-
- // Persist
- this.telemetryEnabled = telemetryEnabled;
- SharedPreferences prefs = context.getSharedPreferences(MapboxConstants.MAPBOX_SHARED_PREFERENCES_FILE,
- Context.MODE_PRIVATE);
- SharedPreferences.Editor editor = prefs.edit();
- editor.putBoolean(MapboxConstants.MAPBOX_SHARED_PREFERENCE_KEY_TELEMETRY_ENABLED, telemetryEnabled);
- editor.apply();
- editor.commit();
- }
-
- /**
- * Immediately attempt to send all events data in the queue to the server.
- * <p>
- * NOTE: Permission set to package private to enable only telemetry code to use this.
- */
- void flushEventsQueueImmediately() {
- // Timber.i("flushEventsQueueImmediately() called...");
- new FlushTheEventsTask().execute();
- }
-
- /**
- * Centralized method for adding populated event to the queue allowing for cap size checking
- *
- * @param event Event to add to the Events Queue
- */
- private void putEventOnQueue(@NonNull Hashtable<String, Object> event) {
- if (event == null) {
- return;
- }
- events.add(event);
- if (events.size() == FLUSH_EVENTS_CAP) {
- // Timber.d("eventsSize == flushCap so send data.");
- flushEventsQueueImmediately();
- }
- }
-
- /**
- * Adds a Location Event to the system for processing
- *
- * @param location Location event
- */
- public void addLocationEvent(Location location) {
-
- // NaN and Infinite checks to prevent JSON errors at send to server time
- if (Double.isNaN(location.getLatitude()) || Double.isNaN(location.getLongitude())
- || Double.isNaN(location.getAltitude()) || Float.isNaN(location.getAccuracy())) {
- return;
- }
-
- if (Double.isInfinite(location.getLatitude()) || Double.isInfinite(location.getLongitude())
- || Double.isInfinite(location.getAltitude()) || Float.isInfinite(location.getAccuracy())) {
- return;
- }
-
- // Add Location even to queue
- Hashtable<String, Object> event = new Hashtable<>();
- event.put(MapboxEvent.ATTRIBUTE_EVENT, MapboxEvent.TYPE_LOCATION);
- event.put(MapboxEvent.ATTRIBUTE_CREATED, generateCreateDate());
- event.put(MapboxEvent.ATTRIBUTE_SOURCE, MapboxEvent.SOURCE_MAPBOX);
- event.put(MapboxEvent.ATTRIBUTE_SESSION_ID, encodeString(mapboxSessionId));
- event.put(MapboxEvent.KEY_LATITUDE,
- Math.floor(location.getLatitude() * locationEventAccuracy) / locationEventAccuracy);
- event.put(MapboxEvent.KEY_LONGITUDE,
- Math.floor(location.getLongitude() * locationEventAccuracy) / locationEventAccuracy);
- event.put(MapboxEvent.KEY_ALTITUDE, location.getAltitude());
- event.put(MapboxEvent.KEY_HORIZONTAL_ACCURACY, Math.round(location.getAccuracy()));
- event.put(MapboxEvent.ATTRIBUTE_OPERATING_SYSTEM, operatingSystem);
- event.put(MapboxEvent.ATTRIBUTE_APPLICATION_STATE, getApplicationState());
-
- putEventOnQueue(event);
-
- rotateSessionId();
- }
-
- /**
- * Push Interactive Events to the system for processing
- *
- * @param eventWithAttributes Event with attributes
- */
- public void pushEvent(Hashtable<String, Object> eventWithAttributes) {
- if (context == null || accessToken == null) {
- return;
- }
-
- if (eventWithAttributes == null) {
- return;
- }
-
- String eventType = (String) eventWithAttributes.get(MapboxEvent.ATTRIBUTE_EVENT);
- if (TextUtils.isEmpty(eventType)) {
- return;
- }
-
- if (eventType.equalsIgnoreCase(MapboxEvent.TYPE_MAP_LOAD)) {
- // Map Load Data Model
- eventWithAttributes.put(MapboxEvent.ATTRIBUTE_USERID, mapboxVendorId);
- eventWithAttributes.put(MapboxEvent.ATTRIBUTE_MODEL, Build.MODEL);
- eventWithAttributes.put(MapboxEvent.ATTRIBUTE_OPERATING_SYSTEM, operatingSystem);
- eventWithAttributes.put(MapboxEvent.ATTRIBUTE_RESOLUTION, displayMetrics.density);
- eventWithAttributes.put(MapboxEvent.ATTRIBUTE_ACCESSIBILITY_FONT_SCALE, getAccesibilityFontScaleSize());
- eventWithAttributes.put(MapboxEvent.ATTRIBUTE_ORIENTATION, getOrientation());
- eventWithAttributes.put(MapboxEvent.ATTRIBUTE_BATTERY_LEVEL, getBatteryLevel());
- eventWithAttributes.put(MapboxEvent.ATTRIBUTE_PLUGGED_IN, isPluggedIn());
- eventWithAttributes.put(MapboxEvent.ATTRIBUTE_CARRIER, getCellularCarrier());
- eventWithAttributes.put(MapboxEvent.ATTRIBUTE_CELLULAR_NETWORK_TYPE, getCellularNetworkType());
- eventWithAttributes.put(MapboxEvent.ATTRIBUTE_WIFI, getConnectedToWifi());
-
- // Put Map Load on events before Turnstile clears it
- putEventOnQueue(eventWithAttributes);
-
- // Turnstile
- pushTurnstileEvent();
-
- // Return immediately to avoid double adding of event
- return;
-
- } else if (eventType.equalsIgnoreCase(MapboxEvent.TYPE_MAP_CLICK)) {
- eventWithAttributes.put(MapboxEvent.ATTRIBUTE_ORIENTATION, getOrientation());
- eventWithAttributes.put(MapboxEvent.ATTRIBUTE_BATTERY_LEVEL, getBatteryLevel());
- eventWithAttributes.put(MapboxEvent.ATTRIBUTE_PLUGGED_IN, isPluggedIn());
- eventWithAttributes.put(MapboxEvent.ATTRIBUTE_CARRIER, getCellularCarrier());
- eventWithAttributes.put(MapboxEvent.ATTRIBUTE_CELLULAR_NETWORK_TYPE, getCellularNetworkType());
- eventWithAttributes.put(MapboxEvent.ATTRIBUTE_WIFI, getConnectedToWifi());
- } else if (eventType.equalsIgnoreCase(MapboxEvent.TYPE_MAP_DRAGEND)) {
- eventWithAttributes.put(MapboxEvent.ATTRIBUTE_ORIENTATION, getOrientation());
- eventWithAttributes.put(MapboxEvent.ATTRIBUTE_BATTERY_LEVEL, getBatteryLevel());
- eventWithAttributes.put(MapboxEvent.ATTRIBUTE_PLUGGED_IN, isPluggedIn());
- eventWithAttributes.put(MapboxEvent.ATTRIBUTE_CARRIER, getCellularCarrier());
- eventWithAttributes.put(MapboxEvent.ATTRIBUTE_CELLULAR_NETWORK_TYPE, getCellularNetworkType());
- eventWithAttributes.put(MapboxEvent.ATTRIBUTE_WIFI, getConnectedToWifi());
- } else {
- // Timber.w("This is not an event type in the Events Data Model.");
- return;
- }
-
- putEventOnQueue(eventWithAttributes);
- }
-
- /**
- * Pushes turnstile event for internal billing purposes
- */
- private void pushTurnstileEvent() {
-
- Hashtable<String, Object> event = new Hashtable<>();
- event.put(MapboxEvent.ATTRIBUTE_EVENT, MapboxEvent.TYPE_TURNSTILE);
- event.put(MapboxEvent.ATTRIBUTE_CREATED, generateCreateDate());
- event.put(MapboxEvent.ATTRIBUTE_USERID, mapboxVendorId);
- event.put(MapboxEvent.ATTRIBUTE_ENABLED_TELEMETRY, telemetryEnabled);
-
- events.add(event);
-
- // Send to Server Immediately
- flushEventsQueueImmediately();
- // Timber.d("turnstile event pushed.");
- }
-
- /**
- * SHA-1 Encoding for strings
- *
- * @param string String to encode
- * @return String encoded if no error, original string if error
- */
- private String encodeString(String string) {
- try {
- if (messageDigest != null) {
- messageDigest.reset();
- messageDigest.update(string.getBytes("UTF-8"));
- byte[] bytes = messageDigest.digest();
-
- // Get the Hex version of the digest
- StringBuilder sb = new StringBuilder();
- for (byte b : bytes) {
- sb.append(String.format("%02X", b));
- }
- String hex = sb.toString();
-
- return hex;
- }
- } catch (Exception exception) {
- // Timber.w("Error encoding string, will return in original form.", exception);
- }
- return string;
- }
-
- /**
- * Changes Session Id based on time boundary
- */
- private void rotateSessionId() {
- long now = System.currentTimeMillis();
- if ((TextUtils.isEmpty(mapboxSessionId))
- || (now - mapboxSessionIdLastSet > (SESSION_ID_ROTATION_HOURS * hourInMillis))) {
- mapboxSessionId = UUID.randomUUID().toString();
- mapboxSessionIdLastSet = System.currentTimeMillis();
- }
- }
-
- private String getOrientation() {
- switch (context.getResources().getConfiguration().orientation) {
- case Configuration.ORIENTATION_LANDSCAPE:
- return "Landscape";
- case Configuration.ORIENTATION_PORTRAIT:
- return "Portrait";
- default:
- return "";
- }
- }
-
- private int getBatteryLevel() {
- int level = batteryStatus.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
- int scale = batteryStatus.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
-
- return Math.round((level / (float) scale) * 100);
- }
-
- /**
- * Determine if device is plugged in to power via USB or AC or not.
- * <p>
- * http://developer.android.com/reference/android/os/BatteryManager.html#EXTRA_PLUGGED
- *
- * @return true if plugged in, false if not
- */
- private boolean isPluggedIn() {
-
- int chargePlug = batteryStatus.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
- if (chargePlug == BatteryManager.BATTERY_PLUGGED_USB || chargePlug == BatteryManager.BATTERY_PLUGGED_AC) {
- return true;
- }
-
- return false;
- }
-
- private String getApplicationState() {
-
- ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
- List<ActivityManager.RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses();
- if (appProcesses == null) {
- return "";
- }
- final String packageName = context.getPackageName();
- for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) {
- if (appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND
- && appProcess.processName.equals(packageName)) {
- return "Foreground";
- }
- }
- return "Background";
- }
-
- private float getAccesibilityFontScaleSize() {
- // Values
- // Small = 0.85
- // Normal = 1.0
- // Large = 1.15
- // Huge = 1.3
-
- return context.getResources().getConfiguration().fontScale;
- }
-
- private String getCellularCarrier() {
- TelephonyManager manager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
- String carrierName = manager.getNetworkOperatorName();
- if (TextUtils.isEmpty(carrierName)) {
- carrierName = "";
- }
- return carrierName;
- }
-
- private String getCellularNetworkType() {
- TelephonyManager manager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
- switch (manager.getNetworkType()) {
- case TelephonyManager.NETWORK_TYPE_1xRTT:
- return "1xRTT";
- case TelephonyManager.NETWORK_TYPE_CDMA:
- return "CDMA";
- case TelephonyManager.NETWORK_TYPE_EDGE:
- return "EDGE";
- case TelephonyManager.NETWORK_TYPE_EHRPD:
- return "EHRPD";
- case TelephonyManager.NETWORK_TYPE_EVDO_0:
- return "EVDO_0";
- case TelephonyManager.NETWORK_TYPE_EVDO_A:
- return "EVDO_A";
- case TelephonyManager.NETWORK_TYPE_EVDO_B:
- return "EVDO_B";
- case TelephonyManager.NETWORK_TYPE_GPRS:
- return "GPRS";
- case TelephonyManager.NETWORK_TYPE_HSDPA:
- return "HSDPA";
- case TelephonyManager.NETWORK_TYPE_HSPA:
- return "HSPA";
- case TelephonyManager.NETWORK_TYPE_HSPAP:
- return "HSPAP";
- case TelephonyManager.NETWORK_TYPE_HSUPA:
- return "HSUPA";
- case TelephonyManager.NETWORK_TYPE_IDEN:
- return "IDEN";
- case TelephonyManager.NETWORK_TYPE_LTE:
- return "LTE";
- case TelephonyManager.NETWORK_TYPE_UMTS:
- return "UMTS";
- case TelephonyManager.NETWORK_TYPE_UNKNOWN:
- return "Unknown";
- default:
- return "";
- }
- }
-
- public Boolean getConnectedToWifi() {
-
- Boolean status = false;
- WifiManager wifiMgr = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
- if (wifiMgr.isWifiEnabled()) {
- try {
- WifiInfo wifiInfo = wifiMgr.getConnectionInfo();
- if (wifiInfo.getNetworkId() != -1) {
- status = true;
- }
- } catch (Exception exception) {
- // Timber.w("Error getting Wifi Connection Status: ", exception);
- status = false;
- }
- }
-
- return status;
- }
-
-
- /**
- * Task responsible for converting stored events and sending them to the server
- */
- private class FlushTheEventsTask extends AsyncTask<Void, Void, Void> {
-
- @Override
- protected Void doInBackground(Void... voids) {
-
- if (events.isEmpty()) {
- // Timber.d("No events in the queue to send so returning.");
- return null;
- }
-
- // Check for NetworkConnectivity
- if (!Mapbox.isConnected()) {
- // Timber.w("Not connected to network, so empty events cache and return without attempting to send events");
- // Make sure that events don't pile up when Offline
- // and thus impact available memory over time.
- events.removeAllElements();
- return null;
- }
-
- Response response = null;
-
- try {
- // Send data
- // =========
- JSONArray jsonArray = new JSONArray();
-
- Vector<Hashtable<String, Object>> eventsClone = (Vector<Hashtable<String, Object>>) events.clone();
-
- for (Hashtable<String, Object> evt : eventsClone) {
- JSONObject jsonObject = new JSONObject();
-
- // Build the JSON but only if there's a value for it in the evt
- jsonObject.putOpt(MapboxEvent.ATTRIBUTE_EVENT, evt.get(MapboxEvent.ATTRIBUTE_EVENT));
- jsonObject.putOpt(MapboxEvent.ATTRIBUTE_CREATED, evt.get(MapboxEvent.ATTRIBUTE_CREATED));
- jsonObject.putOpt(MapboxEvent.ATTRIBUTE_USERID, evt.get(MapboxEvent.ATTRIBUTE_USERID));
- jsonObject.putOpt(MapboxEvent.ATTRIBUTE_ENABLED_TELEMETRY, evt.get(MapboxEvent.ATTRIBUTE_ENABLED_TELEMETRY));
- jsonObject.putOpt(MapboxEvent.ATTRIBUTE_SOURCE, evt.get(MapboxEvent.ATTRIBUTE_SOURCE));
- jsonObject.putOpt(MapboxEvent.ATTRIBUTE_SESSION_ID, evt.get(MapboxEvent.ATTRIBUTE_SESSION_ID));
- jsonObject.putOpt(MapboxEvent.KEY_LATITUDE, evt.get(MapboxEvent.KEY_LATITUDE));
-
- // Make sure Longitude Is Wrapped
- if (evt.containsKey(MapboxEvent.KEY_LONGITUDE)) {
- double lon = (double) evt.get(MapboxEvent.KEY_LONGITUDE);
- if ((lon < GeoConstants.MIN_LONGITUDE) || (lon > GeoConstants.MAX_LONGITUDE)) {
- lon = MathUtils.wrap(lon, GeoConstants.MIN_LONGITUDE, GeoConstants.MAX_LONGITUDE);
- }
- jsonObject.put(MapboxEvent.KEY_LONGITUDE, lon);
- }
-
- jsonObject.putOpt(MapboxEvent.KEY_ALTITUDE, evt.get(MapboxEvent.KEY_ALTITUDE));
- jsonObject.putOpt(MapboxEvent.KEY_ZOOM, evt.get(MapboxEvent.KEY_ZOOM));
- jsonObject.putOpt(MapboxEvent.ATTRIBUTE_OPERATING_SYSTEM, evt.get(MapboxEvent.ATTRIBUTE_OPERATING_SYSTEM));
- jsonObject.putOpt(MapboxEvent.ATTRIBUTE_USERID, evt.get(MapboxEvent.ATTRIBUTE_USERID));
- jsonObject.putOpt(MapboxEvent.ATTRIBUTE_MODEL, evt.get(MapboxEvent.ATTRIBUTE_MODEL));
- jsonObject.putOpt(MapboxEvent.ATTRIBUTE_RESOLUTION, evt.get(MapboxEvent.ATTRIBUTE_RESOLUTION));
- jsonObject.putOpt(MapboxEvent.ATTRIBUTE_ACCESSIBILITY_FONT_SCALE,
- evt.get(MapboxEvent.ATTRIBUTE_ACCESSIBILITY_FONT_SCALE));
- jsonObject.putOpt(MapboxEvent.ATTRIBUTE_BATTERY_LEVEL, evt.get(MapboxEvent.ATTRIBUTE_BATTERY_LEVEL));
- jsonObject.putOpt(MapboxEvent.ATTRIBUTE_PLUGGED_IN, evt.get(MapboxEvent.ATTRIBUTE_PLUGGED_IN));
- jsonObject.putOpt(MapboxEvent.ATTRIBUTE_WIFI, evt.get(MapboxEvent.ATTRIBUTE_WIFI));
-
- // Special Cases where empty string is denoting null and therefore should not be sent at all
- // This arises as thread safe Hashtable does not accept null values (nor keys)
- if (evt.containsKey(MapboxEvent.ATTRIBUTE_ORIENTATION)) {
- String orientation = (String) evt.get(MapboxEvent.ATTRIBUTE_ORIENTATION);
- if (!TextUtils.isEmpty(orientation)) {
- jsonObject.putOpt(MapboxEvent.ATTRIBUTE_ORIENTATION, orientation);
- }
- }
- if (evt.containsKey(MapboxEvent.ATTRIBUTE_CARRIER)) {
- String carrier = (String) evt.get(MapboxEvent.ATTRIBUTE_CARRIER);
- if (!TextUtils.isEmpty(carrier)) {
- jsonObject.putOpt(MapboxEvent.ATTRIBUTE_CARRIER, carrier);
- }
- }
- if (evt.containsKey(MapboxEvent.ATTRIBUTE_APPLICATION_STATE)) {
- String appState = (String) evt.get(MapboxEvent.ATTRIBUTE_APPLICATION_STATE);
- if (!TextUtils.isEmpty(appState)) {
- jsonObject.putOpt(MapboxEvent.ATTRIBUTE_APPLICATION_STATE,
- evt.get(MapboxEvent.ATTRIBUTE_APPLICATION_STATE));
- }
- }
-
- // Special Cases where null has to be passed if no value exists
- // Requires using put() instead of putOpt()
- String eventType = (String) evt.get(MapboxEvent.ATTRIBUTE_EVENT);
- if (!TextUtils.isEmpty(eventType) && eventType.equalsIgnoreCase(MapboxEvent.TYPE_MAP_CLICK)) {
- jsonObject.put(MapboxEvent.KEY_GESTURE_ID, evt.get(MapboxEvent.KEY_GESTURE_ID));
- }
- if (evt.containsKey(MapboxEvent.ATTRIBUTE_CELLULAR_NETWORK_TYPE)) {
- String cellularNetworkType = (String) evt.get(MapboxEvent.ATTRIBUTE_CELLULAR_NETWORK_TYPE);
- if (TextUtils.isEmpty(cellularNetworkType)) {
- jsonObject.put(MapboxEvent.ATTRIBUTE_CELLULAR_NETWORK_TYPE, null);
- } else {
- jsonObject.put(MapboxEvent.ATTRIBUTE_CELLULAR_NETWORK_TYPE,
- evt.get(MapboxEvent.ATTRIBUTE_CELLULAR_NETWORK_TYPE));
- }
- }
-
- jsonArray.put(jsonObject);
- }
-
- // Based on http://square.github.io/okhttp/3.x/okhttp/okhttp3/CertificatePinner.html
- CertificatePinner.Builder certificatePinnerBuilder = new CertificatePinner.Builder();
- if (stagingEnv) {
- // Staging - Geotrust
- certificatePinnerBuilder
- .add("cloudfront-staging.tilestream.net", "sha256/3euxrJOrEZI15R4104UsiAkDqe007EPyZ6eTL/XxdAY=")
- .add("cloudfront-staging.tilestream.net", "sha256/5kJvNEMw0KjrCAu7eXY5HZdvyCS13BbA0VJG1RSP91w=")
- .add("cloudfront-staging.tilestream.net", "sha256/r/mIkG3eEpVdm+u/ko/cwxzOMo1bk4TyHIlByibiA5E=");
- } else {
- certificatePinnerBuilder
- // Prod - Geotrust
- .add("events.mapbox.com", "sha256/BhynraKizavqoC5U26qgYuxLZst6pCu9J5stfL6RSYY=")
- .add("events.mapbox.com", "sha256/owrR9U9FWDWtrFF+myoRIu75JwU4sJwzvhCNLZoY37g=")
- .add("events.mapbox.com", "sha256/SQVGZiOrQXi+kqxcvWWE96HhfydlLVqFr4lQTqI5qqo=")
- // Prod - DigiCert
- .add("events.mapbox.com", "sha256/Tb0uHZ/KQjWh8N9+CZFLc4zx36LONQ55l6laDi1qtT4=")
- .add("events.mapbox.com", "sha256/RRM1dGqnDFsCJXBTHky16vi1obOlCgFFn/yOhI/y+ho=")
- .add("events.mapbox.com", "sha256/WoiWRyIOVNa9ihaBciRSC7XHjliYS9VwUGOIud4PB18=");
- }
-
- OkHttpClient client = new OkHttpClient.Builder()
- .certificatePinner(certificatePinnerBuilder.build())
- .addInterceptor(new GzipRequestInterceptor())
- .build();
- RequestBody body = RequestBody.create(JSON, jsonArray.toString());
-
- String url = eventsURL + "/events/v2?access_token=" + accessToken;
-
- Request request = new Request.Builder()
- .url(url)
- .header("User-Agent", userAgent)
- .post(body)
- .build();
- response = client.newCall(request).execute();
- // Timber.d("response code = " + response.code() + " for events " + events.size());
-
- } catch (Exception exception) {
- Timber.e("FlushTheEventsTask borked: ", exception);
- } finally {
- if (response != null && response.body() != null) {
- response.body().close();
- }
- // Reset Events
- // ============
- events.removeAllElements();
- }
-
- return null;
- }
-
- }
-
-
- /**
- * TimerTask responsible for sending event data to server
- */
- private class FlushEventsTimerTask extends TimerTask {
- /**
- * The task to run should be specified in the implementation of the {@code run()}
- * method.
- */
- @Override
- public void run() {
- new FlushTheEventsTask().execute();
- }
- }
-
- private String getApplicationIdentifier() {
- try {
- PackageInfo packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
- return String.format(MapboxConstants.MAPBOX_LOCALE, "%s/%s/%s", context.getPackageName(),
- packageInfo.versionName, packageInfo.versionCode);
- } catch (Exception exception) {
- return "";
- }
- }
-
- static class ExponentialBackoffCounter {
-
- private static final long BASE_TIME = 30000 /*30 seconds*/;
- private int attempt;
-
- long getNextCount() {
- attempt++;
- return attempt * BASE_TIME;
- }
- }
-}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/TelemetryLocationReceiver.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/TelemetryLocationReceiver.java
deleted file mode 100644
index 2274fb2b82..0000000000
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/TelemetryLocationReceiver.java
+++ /dev/null
@@ -1,70 +0,0 @@
-package com.mapbox.mapboxsdk.telemetry;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.location.Location;
-import android.location.LocationManager;
-
-/**
- * Listener for Location updates generated by implementing app.
- */
-public class TelemetryLocationReceiver extends BroadcastReceiver {
-
- public static final String INTENT_STRING = "com.mapbox.mapboxsdk.telemetry.TelemetryLocationReceiver";
-
- /**
- * Default Constructor
- */
- public TelemetryLocationReceiver() {
- super();
- }
-
- /**
- * This method is called when the BroadcastReceiver is receiving an Intent
- * broadcast. During this time you can use the other methods on
- * BroadcastReceiver to view/modify the current result values. This method
- * is always called within the main thread of its process, unless you
- * explicitly asked for it to be scheduled on a different thread using
- * {@link Context#registerReceiver(BroadcastReceiver,
- * android.content.IntentFilter, String, android.os.Handler)}. When it runs on the main
- * thread you should
- * never perform long-running operations in it (there is a timeout of
- * 10 seconds that the system allows before considering the receiver to
- * be blocked and a candidate to be killed). You cannot launch a popup dialog
- * in your implementation of onReceive().
- * <p>
- * <p><b>If this BroadcastReceiver was launched through a &lt;receiver&gt; tag,
- * then the object is no longer alive after returning from this
- * function.</b> This means you should not perform any operations that
- * return a result to you asynchronously -- in particular, for interacting
- * with services, you should use
- * {@link Context#startService(Intent)} instead of
- * {@link Context#bindService(Intent, android.content.ServiceConnection, int)}. If you wish
- * to interact with a service that is already running, you can use
- * {@link #peekService}.
- * <p>
- * <p>The Intent filters used in {@link Context#registerReceiver}
- * and in application manifests are <em>not</em> guaranteed to be exclusive. They
- * are hints to the operating system about how to find suitable recipients. It is
- * possible for senders to force delivery to specific recipients, bypassing filter
- * resolution. For this reason, {@link #onReceive(Context, Intent) onReceive()}
- * implementations should respond only to known actions, ignoring any unexpected
- * Intents that they may receive.
- *
- * @param context The Context in which the receiver is running.
- * @param intent The Intent being received.
- */
- @Override
- public void onReceive(Context context, Intent intent) {
- if (intent == null || intent.getExtras() == null) {
- // see https://github.com/mapbox/mapbox-gl-native/issues/6934
- return;
- }
-
- Location location = (Location) intent.getExtras().get(LocationManager.KEY_LOCATION_CHANGED);
- if (location != null) {
- MapboxEventManager.getMapboxEventManager().addLocationEvent(location);
- }
- }
-}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/TelemetryService.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/TelemetryService.java
deleted file mode 100644
index c667c1199d..0000000000
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/TelemetryService.java
+++ /dev/null
@@ -1,156 +0,0 @@
-package com.mapbox.mapboxsdk.telemetry;
-
-import android.app.Service;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.ServiceInfo;
-import android.os.AsyncTask;
-import android.os.IBinder;
-import android.support.annotation.Nullable;
-import android.support.v4.content.LocalBroadcastManager;
-
-import timber.log.Timber;
-
-/**
- * Manages Startup and Shutdown of Telemetry resources
- */
-public class TelemetryService extends Service {
-
- private TelemetryLocationReceiver telemetryLocationReceiver = null;
-
- /**
- * Return the communication channel to the service. May return null if
- * clients can not bind to the service. The returned
- * {@link IBinder} is usually for a complex interface
- * that has been <a href="{@docRoot}guide/components/aidl.html">described using
- * aidl</a>.
- * <p>
- * <p><em>Note that unlike other application components, calls on to the
- * IBinder interface returned here may not happen on the main thread
- * of the process</em>. More information about the main thread can be found in
- * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html">Processes and
- * Threads</a>.</p>
- *
- * @param intent The Intent that was used to bind to this service,
- * as given to {@link Context#bindService
- * Context.bindService}. Note that any extras that were included with
- * the Intent at that point will <em>not</em> be seen here.
- * @return Return an IBinder through which clients can call on to the
- * service.
- */
- @Nullable
- @Override
- public IBinder onBind(Intent intent) {
- return null;
- }
-
-
- /**
- * Called by the system when the service is first created. Do not call this method directly.
- */
- @Override
- public void onCreate() {
- super.onCreate();
-
- Timber.i("onCreate() called");
-
- // Enable Location Listening for lifecycle of app
- LocalBroadcastManager.getInstance(getApplicationContext()).registerReceiver(
- new TelemetryLocationReceiver(),
- new IntentFilter(TelemetryLocationReceiver.INTENT_STRING)
- );
- }
-
- /**
- * Called by the system to notify a Service that it is no longer used and is being removed. The
- * service should clean up any resources it holds (threads, registered
- * receivers, etc) at this point. Upon return, there will be no more calls
- * in to this Service object and it is effectively dead. Do not call this method directly.
- */
- @Override
- public void onDestroy() {
- shutdownTelemetry();
- super.onDestroy();
- }
-
- /**
- * This is called if the service is currently running and the user has
- * removed a task that comes from the service's application. If you have
- * set {@link ServiceInfo#FLAG_STOP_WITH_TASK ServiceInfo.FLAG_STOP_WITH_TASK}
- * then you will not receive this callback; instead, the service will simply
- * be stopped.
- *
- * @param rootIntent The original root Intent that was used to launch
- * the task that is being removed.
- */
- @Override
- public void onTaskRemoved(Intent rootIntent) {
- shutdownTelemetry();
- super.onTaskRemoved(rootIntent);
- }
-
- /**
- * Called by the system every time a client explicitly starts the service by calling
- * {@link Context#startService}, providing the arguments it supplied and a
- * unique integer token representing the start request. Do not call this method directly.
- * <p>
- * <p>For backwards compatibility, the default implementation calls
- * {@link #onStart} and returns either {@link #START_STICKY}
- * or {@link #START_STICKY_COMPATIBILITY}.
- * </p>
- * <p>If you need your application to run on platform versions prior to API
- * level 5, you can use the following model to handle the older {@link #onStart}
- * callback in that case. The <code>handleCommand</code> method is implemented by
- * you as appropriate:
- * </p>
- * <p>
- * <p class="caution">Note that the system calls this on your
- * service's main thread. A service's main thread is the same
- * thread where UI operations take place for Activities running in the
- * same process. You should always avoid stalling the main
- * thread's event loop. When doing long-running operations,
- * network calls, or heavy disk I/O, you should kick off a new
- * thread, or use {@link AsyncTask}.</p>
- *
- * @param intent The Intent supplied to {@link Context#startService},
- * as given. This may be null if the service is being restarted after
- * its process has gone away, and it had previously returned anything
- * except {@link #START_STICKY_COMPATIBILITY}.
- * @param flags Additional data about this start request. Currently either
- * 0, {@link #START_FLAG_REDELIVERY}, or {@link #START_FLAG_RETRY}.
- * @param startId A unique integer representing this specific request to
- * start. Use with {@link #stopSelfResult(int)}.
- * @return The return value indicates what semantics the system should
- * use for the service's current started state. It may be one of the
- * constants associated with the {@link #START_CONTINUATION_MASK} bits.
- * @see #stopSelfResult(int)
- */
- @Override
- public int onStartCommand(Intent intent, int flags, int startId) {
-
- Timber.i("onStartCommand() called");
-
- return START_NOT_STICKY;
- }
-
- private void shutdownTelemetry() {
-
- // Send Any Remaining events to the server
- MapboxEventManager.getMapboxEventManager().flushEventsQueueImmediately();
-
- // Undesired, but needed trick to keep app alive long enough for data to get to server
- try {
- Thread.sleep(1000);
- } catch (Exception exception) {
- Timber.e("Error while trying to sleep for 1 second: " + exception);
- }
-
- try {
- unregisterReceiver(telemetryLocationReceiver);
- } catch (IllegalArgumentException illegalArgumentException) {
- Timber.e("Error when unregisterReceiver: " + illegalArgumentException);
- }
-
- }
-}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/package-info.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/package-info.java
deleted file mode 100644
index 725cf016be..0000000000
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/package-info.java
+++ /dev/null
@@ -1,4 +0,0 @@
-/**
- * Contains the Mapbox Maps Android Telemetry API classes.
- */
-package com.mapbox.mapboxsdk.telemetry;
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/utils/MathUtils.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/utils/MathUtils.java
deleted file mode 100644
index 30ec214798..0000000000
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/utils/MathUtils.java
+++ /dev/null
@@ -1,66 +0,0 @@
-package com.mapbox.mapboxsdk.utils;
-
-public class MathUtils {
-
- /**
- * Test a value in specified range, returning minimum if it's below, and maximum if it's above
- *
- * @param value Value to test
- * @param min Minimum value of range
- * @param max Maximum value of range
- * @return value if it's between min and max, min if it's below, max if it's above
- */
- public static double clamp(double value, double min, double max) {
- return Math.max(min, Math.min(max, value));
- }
-
- /**
- * Test a value in specified range, returning minimum if it's below, and maximum if it's above
- *
- * @param value Value to test
- * @param min Minimum value of range
- * @param max Maximum value of range
- * @return value if it's between min and max, min if it's below, max if it's above
- */
- public static float clamp(float value, float min, float max) {
- return Math.max(min, Math.min(max, value));
- }
-
- /**
- * Constrains value to the given range (including min, excluding max) via modular arithmetic.
- * <p>
- * Same formula as used in Core GL (wrap.hpp)
- * std::fmod((std::fmod((value - min), d) + d), d) + min;
- *
- * @param value Value to wrap
- * @param min Minimum value
- * @param max Maximum value
- * @return Wrapped value
- */
- public static double wrap(double value, double min, double max) {
- double delta = max - min;
-
- double firstMod = (value - min) % delta;
- double secondMod = (firstMod + delta) % delta;
-
- return secondMod + min;
- }
-
- /**
- * Convert bearing from core to match Android SDK value.
- *
- * @param nativeBearing bearing value coming from core
- * @return bearing in degrees starting from 0 rotating clockwise
- */
- public static double convertNativeBearing(double nativeBearing) {
- double direction = -nativeBearing;
-
- while (direction > 360) {
- direction -= 360;
- }
- while (direction < 0) {
- direction += 360;
- }
- return direction;
- }
-}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/maps/widgets/MyLocationViewTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/maps/widgets/MyLocationViewTest.java
index ac10d11922..c8a983351b 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/maps/widgets/MyLocationViewTest.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/maps/widgets/MyLocationViewTest.java
@@ -16,7 +16,7 @@ import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
import com.mapbox.mapboxsdk.constants.MyBearingTracking;
import com.mapbox.mapboxsdk.constants.MyLocationTracking;
import com.mapbox.mapboxsdk.geometry.LatLng;
-import com.mapbox.mapboxsdk.location.LocationServices;
+import com.mapbox.mapboxsdk.location.LocationSource;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.maps.widgets.MyLocationView;
import com.mapbox.mapboxsdk.testapp.R;
@@ -123,7 +123,7 @@ public class MyLocationViewTest {
mapboxMap.moveCamera(
CameraUpdateFactory.newCameraPosition(
new CameraPosition.Builder()
- .target(new LatLng(LocationServices.getLocationServices(view.getContext()).getLastLocation()))
+ .target(new LatLng(LocationSource.getLocationEngine(view.getContext()).getLastLocation()))
.build()
)
);
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml
index eabd8d5c9d..23372b49e3 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml
@@ -596,7 +596,7 @@
<!-- android:name="com.mapbox.SetStorageExternal" -->
<!-- android:value="true" /> -->
- <service android:name="com.mapbox.mapboxsdk.telemetry.TelemetryService"/>
+ <service android:name="com.mapbox.services.android.telemetry.service.TelemetryService"/>
</application>
</manifest>
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MyLocationDrawableActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MyLocationDrawableActivity.java
index 3984e765e1..c15e3b6058 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MyLocationDrawableActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MyLocationDrawableActivity.java
@@ -16,15 +16,15 @@ import android.view.ViewGroup;
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
import com.mapbox.mapboxsdk.constants.Style;
import com.mapbox.mapboxsdk.geometry.LatLng;
-import com.mapbox.mapboxsdk.location.LocationListener;
-import com.mapbox.mapboxsdk.location.LocationServices;
+import com.mapbox.mapboxsdk.location.LocationSource;
import com.mapbox.mapboxsdk.maps.MapView;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.maps.MapboxMapOptions;
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
import com.mapbox.mapboxsdk.testapp.R;
+import com.mapbox.services.android.telemetry.location.LocationEngineListener;
-public class MyLocationDrawableActivity extends AppCompatActivity implements LocationListener {
+public class MyLocationDrawableActivity extends AppCompatActivity implements LocationEngineListener {
private static final int PERMISSIONS_LOCATION = 0;
@@ -92,7 +92,7 @@ public class MyLocationDrawableActivity extends AppCompatActivity implements Loc
if (location != null) {
onLocationChanged(location);
} else {
- LocationServices.getLocationServices(this).addLocationListener(this);
+ LocationSource.getLocationEngine(this).addLocationEngineListener(this);
}
} else {
mapboxMap.setMyLocationEnabled(false);
@@ -109,6 +109,11 @@ public class MyLocationDrawableActivity extends AppCompatActivity implements Loc
}
@Override
+ public void onConnected() {
+ // Nothing
+ }
+
+ @Override
public void onLocationChanged(Location location) {
if (mapboxMap != null) {
mapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(location), 14));
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MyLocationTintActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MyLocationTintActivity.java
index f5dfc90247..332dea2963 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MyLocationTintActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MyLocationTintActivity.java
@@ -18,16 +18,16 @@ import android.view.View;
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
import com.mapbox.mapboxsdk.constants.MyLocationTracking;
import com.mapbox.mapboxsdk.geometry.LatLng;
-import com.mapbox.mapboxsdk.location.LocationListener;
-import com.mapbox.mapboxsdk.location.LocationServices;
+import com.mapbox.mapboxsdk.location.LocationSource;
import com.mapbox.mapboxsdk.maps.MapView;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
import com.mapbox.mapboxsdk.maps.TrackingSettings;
import com.mapbox.mapboxsdk.maps.widgets.MyLocationViewSettings;
import com.mapbox.mapboxsdk.testapp.R;
+import com.mapbox.services.android.telemetry.location.LocationEngineListener;
-public class MyLocationTintActivity extends AppCompatActivity implements LocationListener {
+public class MyLocationTintActivity extends AppCompatActivity implements LocationEngineListener {
private MapView mapView;
private MapboxMap mapboxMap;
@@ -121,6 +121,11 @@ public class MyLocationTintActivity extends AppCompatActivity implements Locatio
}
@Override
+ public void onConnected() {
+ // Nothing
+ }
+
+ @Override
public void onLocationChanged(Location location) {
if (mapboxMap != null && firstRun) {
mapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(location), 15));
@@ -132,7 +137,7 @@ public class MyLocationTintActivity extends AppCompatActivity implements Locatio
protected void onStart() {
super.onStart();
mapView.onStart();
- LocationServices.getLocationServices(this).addLocationListener(this);
+ LocationSource.getLocationEngine(this).addLocationEngineListener(this);
}
@Override
@@ -150,7 +155,7 @@ public class MyLocationTintActivity extends AppCompatActivity implements Locatio
@Override
protected void onStop() {
super.onStop();
- LocationServices.getLocationServices(this).removeLocationListener(this);
+ LocationSource.getLocationEngine(this).removeLocationEngineListener(this);
mapView.onStop();
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MyLocationToggleActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MyLocationToggleActivity.java
index e6991c201f..8bf40e3cf5 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MyLocationToggleActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MyLocationToggleActivity.java
@@ -13,12 +13,14 @@ import android.view.View;
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
import com.mapbox.mapboxsdk.geometry.LatLng;
-import com.mapbox.mapboxsdk.location.LocationListener;
-import com.mapbox.mapboxsdk.location.LocationServices;
+import com.mapbox.mapboxsdk.location.LocationSource;
import com.mapbox.mapboxsdk.maps.MapView;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
import com.mapbox.mapboxsdk.testapp.R;
+import com.mapbox.services.android.telemetry.location.LocationEngine;
+import com.mapbox.services.android.telemetry.location.LocationEngineListener;
+import com.mapbox.services.android.telemetry.permissions.PermissionsManager;
public class MyLocationToggleActivity extends AppCompatActivity {
@@ -26,8 +28,8 @@ public class MyLocationToggleActivity extends AppCompatActivity {
private MapboxMap mapboxMap;
private FloatingActionButton locationToggleFab;
- private LocationServices locationServices;
- private LocationListener locationListener;
+ private LocationEngine locationServices;
+ private LocationEngineListener locationListener;
private static final int PERMISSIONS_LOCATION = 0;
@@ -36,7 +38,7 @@ public class MyLocationToggleActivity extends AppCompatActivity {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my_location_toggle);
- locationServices = LocationServices.getLocationServices(MyLocationToggleActivity.this);
+ locationServices = LocationSource.getLocationEngine(this);
mapView = (MapView) findViewById(R.id.mapView);
mapView.onCreate(savedInstanceState);
@@ -95,7 +97,7 @@ public class MyLocationToggleActivity extends AppCompatActivity {
// Ensure no memory leak occurs if we register the location listener but the call hasn't
// been made yet.
if (locationListener != null) {
- locationServices.removeLocationListener(locationListener);
+ locationServices.removeLocationEngineListener(locationListener);
}
}
@@ -108,7 +110,7 @@ public class MyLocationToggleActivity extends AppCompatActivity {
@UiThread
public void toggleGps(boolean enableGps) {
if (enableGps) {
- if (!LocationServices.getLocationServices(MyLocationToggleActivity.this).areLocationPermissionsGranted()) {
+ if (!PermissionsManager.areLocationPermissionsGranted(this)) {
ActivityCompat.requestPermissions(this, new String[] {Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION}, PERMISSIONS_LOCATION);
} else {
@@ -123,7 +125,7 @@ public class MyLocationToggleActivity extends AppCompatActivity {
if (enabled) {
// To move the camera instantly, we attempt to get the last known location and either
// ease or animate the camera to that position depending on the zoom level.
- Location lastLocation = LocationServices.getLocationServices(this).getLastLocation();
+ Location lastLocation = LocationSource.getLocationEngine(this).getLastLocation();
if (lastLocation != null) {
if (mapboxMap.getCameraPosition().zoom > 15.99) {
@@ -132,16 +134,21 @@ public class MyLocationToggleActivity extends AppCompatActivity {
mapboxMap.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(lastLocation), 16), 1000);
}
} else {
- locationListener = new LocationListener() {
+ locationListener = new LocationEngineListener() {
+ @Override
+ public void onConnected() {
+ // Nothing
+ }
+
@Override
public void onLocationChanged(Location location) {
if (location != null) {
mapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(location), 16));
- locationServices.removeLocationListener(this);
+ locationServices.removeLocationEngineListener(this);
}
}
};
- locationServices.addLocationListener(locationListener);
+ locationServices.addLocationEngineListener(locationListener);
}
locationToggleFab.setImageResource(R.drawable.ic_location_disabled_24dp);
} else {
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/telemetry/ExponentialBackOffTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/telemetry/ExponentialBackOffTest.java
deleted file mode 100644
index fcaef9fa88..0000000000
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/telemetry/ExponentialBackOffTest.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package com.mapbox.mapboxsdk.telemetry;
-
-import org.junit.Test;
-
-import static junit.framework.Assert.assertEquals;
-
-public class ExponentialBackOffTest {
-
- @Test
- public void testExponentialBackOff() {
- MapboxEventManager.ExponentialBackoffCounter counter = new MapboxEventManager.ExponentialBackoffCounter();
- assertEquals(30000, counter.getNextCount());
- assertEquals(60000, counter.getNextCount());
- assertEquals(90000, counter.getNextCount());
- assertEquals(120000, counter.getNextCount());
- assertEquals(150000, counter.getNextCount());
- assertEquals(180000, counter.getNextCount());
- }
-}
diff --git a/platform/android/MapboxGLAndroidSDKWearTestApp/src/main/AndroidManifest.xml b/platform/android/MapboxGLAndroidSDKWearTestApp/src/main/AndroidManifest.xml
index f9beb4c05f..b75d644b0b 100644
--- a/platform/android/MapboxGLAndroidSDKWearTestApp/src/main/AndroidManifest.xml
+++ b/platform/android/MapboxGLAndroidSDKWearTestApp/src/main/AndroidManifest.xml
@@ -40,7 +40,7 @@
android:value=".activity.FeatureOverviewActivity"/>
</activity>
- <service android:name="com.mapbox.mapboxsdk.telemetry.TelemetryService"/>
+ <service android:name="com.mapbox.services.android.telemetry.service.TelemetryService"/>
</application>