From 939f8afd33e154e1cb835eebce916723123c2e90 Mon Sep 17 00:00:00 2001 From: Antonio Zugaldia Date: Tue, 23 Aug 2016 14:34:19 -0400 Subject: [PATCH 1/5] [android] #6042 - add isConnected() method to MapboxAccountManager to avoid unnecessary HTTPRequests --- .../mapboxsdk/MapboxAccountManager.java | 20 +++++++++++++++++++ .../mapbox/mapboxsdk/http/HTTPRequest.java | 10 +++++++++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/MapboxAccountManager.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/MapboxAccountManager.java index f8a83550f09..467e8e72e8c 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/MapboxAccountManager.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/MapboxAccountManager.java @@ -1,6 +1,8 @@ package com.mapbox.mapboxsdk; import android.content.Context; +import android.net.ConnectivityManager; +import android.net.NetworkInfo; import android.text.TextUtils; import com.mapbox.mapboxsdk.constants.MapboxConstants; @@ -79,4 +81,22 @@ public static void validateAccessToken(String accessToken) throws InvalidAccessT throw new InvalidAccessTokenException(); } } + + /** + * Determines whether we have an Internet connection available. + * + * @return true if there is an Internet connection, false otherwise + */ + public boolean isConnected() { + if (applicationContext == null) { + // Assume connection if MapboxAccountManager contains an empty Context + return true; + } + + // Check actual connectivity via ConnectivityManager. Code adapted from: + // https://developer.android.com/training/monitoring-device-state/connectivity-monitoring.html#DetermineConnection + ConnectivityManager cm = (ConnectivityManager) applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE); + NetworkInfo activeNetwork = cm.getActiveNetworkInfo(); + return (activeNetwork != null && activeNetwork.isConnectedOrConnecting()); + } } 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 5b87e70ef68..45c54dcda62 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 @@ -3,10 +3,12 @@ import android.text.TextUtils; import android.util.Log; +import com.mapbox.mapboxsdk.MapboxAccountManager; import com.mapbox.mapboxsdk.constants.MapboxConstants; import java.io.IOException; import java.io.InterruptedIOException; +import java.net.NoRouteToHostException; import java.net.ProtocolException; import java.net.SocketException; import java.net.UnknownHostException; @@ -47,6 +49,12 @@ private HTTPRequest(long nativePtr, String resourceUrl, String userAgent, String mNativePtr = nativePtr; try { + // Don't try a request if we aren't connected + MapboxAccountManager mapboxAccountManager = MapboxAccountManager.getInstance(); + if (mapboxAccountManager != null && !mapboxAccountManager.isConnected()) { + throw new NoRouteToHostException("No Internet connection available."); + } + HttpUrl httpUrl = HttpUrl.parse(resourceUrl); final String host = httpUrl.host().toLowerCase(MapboxConstants.MAPBOX_LOCALE); if (host.equals("mapbox.com") || host.endsWith(".mapbox.com")) { @@ -124,7 +132,7 @@ private void onFailure(Exception e) { Log.w(LOG_TAG, String.format("[HTTP] Request could not be executed: %s", e.getMessage())); int type = PERMANENT_ERROR; - if ((e instanceof UnknownHostException) || (e instanceof SocketException) || (e instanceof ProtocolException) || (e instanceof SSLException)) { + if ((e instanceof NoRouteToHostException) || (e instanceof UnknownHostException) || (e instanceof SocketException) || (e instanceof ProtocolException) || (e instanceof SSLException)) { type = CONNECTION_ERROR; } else if ((e instanceof InterruptedIOException)) { type = TEMPORARY_ERROR; From 707a7b77a9201bc20bfc6bbe414539b351e4d971 Mon Sep 17 00:00:00 2001 From: Brad Leege Date: Tue, 23 Aug 2016 16:15:49 -0500 Subject: [PATCH 2/5] [android] #6042 - Creating IOUtils for common IO functions --- .../mapboxsdk/MapboxAccountManager.java | 20 +-------- .../mapbox/mapboxsdk/http/HTTPRequest.java | 9 +--- .../telemetry/MapboxEventManager.java | 5 +-- .../com/mapbox/mapboxsdk/utils/IOUtils.java | 42 +++++++++++++++++++ 4 files changed, 48 insertions(+), 28 deletions(-) create mode 100644 platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/utils/IOUtils.java diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/MapboxAccountManager.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/MapboxAccountManager.java index 467e8e72e8c..d2a9a82061b 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/MapboxAccountManager.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/MapboxAccountManager.java @@ -9,6 +9,7 @@ import com.mapbox.mapboxsdk.exceptions.InvalidAccessTokenException; import com.mapbox.mapboxsdk.exceptions.MapboxAccountManagerNotStartedException; import com.mapbox.mapboxsdk.telemetry.MapboxEventManager; +import com.mapbox.mapboxsdk.utils.IOUtils; public class MapboxAccountManager { @@ -42,6 +43,7 @@ public static MapboxAccountManager start(Context context, String accessToken) { if (mapboxAccountManager == null) { mapboxAccountManager = new MapboxAccountManager(context, accessToken); } + IOUtils.getInstance(mapboxAccountManager.applicationContext); MapboxEventManager eventManager = MapboxEventManager.getMapboxEventManager(); eventManager.initialize(mapboxAccountManager.applicationContext, mapboxAccountManager.accessToken); return mapboxAccountManager; @@ -81,22 +83,4 @@ public static void validateAccessToken(String accessToken) throws InvalidAccessT throw new InvalidAccessTokenException(); } } - - /** - * Determines whether we have an Internet connection available. - * - * @return true if there is an Internet connection, false otherwise - */ - public boolean isConnected() { - if (applicationContext == null) { - // Assume connection if MapboxAccountManager contains an empty Context - return true; - } - - // Check actual connectivity via ConnectivityManager. Code adapted from: - // https://developer.android.com/training/monitoring-device-state/connectivity-monitoring.html#DetermineConnection - ConnectivityManager cm = (ConnectivityManager) applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE); - NetworkInfo activeNetwork = cm.getActiveNetworkInfo(); - return (activeNetwork != null && activeNetwork.isConnectedOrConnecting()); - } } 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 45c54dcda62..41d6781aadc 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 @@ -2,10 +2,8 @@ import android.text.TextUtils; import android.util.Log; - -import com.mapbox.mapboxsdk.MapboxAccountManager; import com.mapbox.mapboxsdk.constants.MapboxConstants; - +import com.mapbox.mapboxsdk.utils.IOUtils; import java.io.IOException; import java.io.InterruptedIOException; import java.net.NoRouteToHostException; @@ -13,9 +11,7 @@ import java.net.SocketException; import java.net.UnknownHostException; import java.util.concurrent.locks.ReentrantLock; - import javax.net.ssl.SSLException; - import okhttp3.Call; import okhttp3.Callback; import okhttp3.HttpUrl; @@ -50,8 +46,7 @@ private HTTPRequest(long nativePtr, String resourceUrl, String userAgent, String try { // Don't try a request if we aren't connected - MapboxAccountManager mapboxAccountManager = MapboxAccountManager.getInstance(); - if (mapboxAccountManager != null && !mapboxAccountManager.isConnected()) { + if (!IOUtils.getInstance(null).isConnected()) { throw new NoRouteToHostException("No Internet connection available."); } 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 index 84df822ce9d..5f65bfecf44 100644 --- 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 @@ -30,6 +30,7 @@ import com.mapbox.mapboxsdk.constants.MapboxConstants; import com.mapbox.mapboxsdk.exceptions.TelemetryServiceNotConfiguredException; import com.mapbox.mapboxsdk.location.LocationServices; +import com.mapbox.mapboxsdk.utils.IOUtils; import com.mapbox.mapboxsdk.utils.MathUtils; import org.json.JSONArray; import org.json.JSONObject; @@ -629,9 +630,7 @@ protected Void doInBackground(Void... voids) { } // Check for NetworkConnectivity - ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); - NetworkInfo networkInfo = cm.getActiveNetworkInfo(); - if (networkInfo == null || !networkInfo.isConnected()) { + if (!IOUtils.getInstance(null).isConnected()) { Log.w(TAG, "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. diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/utils/IOUtils.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/utils/IOUtils.java new file mode 100644 index 00000000000..839e078d64b --- /dev/null +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/utils/IOUtils.java @@ -0,0 +1,42 @@ +package com.mapbox.mapboxsdk.utils; + +import android.content.Context; +import android.net.ConnectivityManager; +import android.net.NetworkInfo; +import android.support.annotation.NonNull; +import android.util.Log; + +public class IOUtils { + + private static IOUtils instance = null; + private Context context = null; + + /** + * Private Constructor for Singleton + * @param context Context + */ + private IOUtils(@NonNull Context context) { + super(); + this.context = context; + } + + public static IOUtils getInstance(Context context) { + if (instance == null) { + instance = new IOUtils(context); + } + return instance; + } + + /** + * Determines whether we have an Internet connection available. + * + * @return true if there is an Internet connection, false otherwise + */ + public boolean isConnected() { + ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); + NetworkInfo activeNetwork = cm.getActiveNetworkInfo(); + boolean result = (activeNetwork != null && activeNetwork.isConnected()); + Log.i("IOUtils", "isConnected result = " + result); + return result; + } +} From 773776db39515e2c437d2f9861c39f3303465ef5 Mon Sep 17 00:00:00 2001 From: Antonio Zugaldia Date: Wed, 24 Aug 2016 09:03:33 -0400 Subject: [PATCH 3/5] [android] #6042 - add null check for mCall to avoid NullPointerException --- .../src/main/java/com/mapbox/mapboxsdk/http/HTTPRequest.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) 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 41d6781aadc..0ccccd049d6 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 @@ -76,7 +76,10 @@ private HTTPRequest(long nativePtr, String resourceUrl, String userAgent, String } public void cancel() { - mCall.cancel(); + // mCall can be null if the constructor gets aborted (e.g, under a NoRouteToHostException). + if (mCall != null) { + mCall.cancel(); + } // TODO: We need a lock here because we can try // to cancel at the same time the request is getting From 9e2aa93586f3f943e67278d84ca468c541ba04b9 Mon Sep 17 00:00:00 2001 From: Antonio Zugaldia Date: Wed, 24 Aug 2016 09:12:59 -0400 Subject: [PATCH 4/5] [android] #6042 - bring isConnected() to MapboxAccountManager and make its private SDK use more explicit --- .../mapboxsdk/MapboxAccountManager.java | 19 ++++++++- .../mapbox/mapboxsdk/http/HTTPRequest.java | 8 +++- .../telemetry/MapboxEventManager.java | 10 +++-- .../com/mapbox/mapboxsdk/utils/IOUtils.java | 42 ------------------- 4 files changed, 29 insertions(+), 50 deletions(-) delete mode 100644 platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/utils/IOUtils.java diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/MapboxAccountManager.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/MapboxAccountManager.java index d2a9a82061b..f26ceec6591 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/MapboxAccountManager.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/MapboxAccountManager.java @@ -4,12 +4,12 @@ import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.text.TextUtils; +import android.util.Log; import com.mapbox.mapboxsdk.constants.MapboxConstants; import com.mapbox.mapboxsdk.exceptions.InvalidAccessTokenException; import com.mapbox.mapboxsdk.exceptions.MapboxAccountManagerNotStartedException; import com.mapbox.mapboxsdk.telemetry.MapboxEventManager; -import com.mapbox.mapboxsdk.utils.IOUtils; public class MapboxAccountManager { @@ -43,7 +43,7 @@ public static MapboxAccountManager start(Context context, String accessToken) { if (mapboxAccountManager == null) { mapboxAccountManager = new MapboxAccountManager(context, accessToken); } - IOUtils.getInstance(mapboxAccountManager.applicationContext); + MapboxEventManager eventManager = MapboxEventManager.getMapboxEventManager(); eventManager.initialize(mapboxAccountManager.applicationContext, mapboxAccountManager.accessToken); return mapboxAccountManager; @@ -83,4 +83,19 @@ public static void validateAccessToken(String accessToken) throws InvalidAccessT throw new InvalidAccessTokenException(); } } + + /** + * Determines whether we have an Internet connection available. Please do not rely on this + * method in your apps, this method is used internally by the SDK. + * + * @return true if there is an Internet connection, false otherwise + */ + public boolean isConnected() { + ConnectivityManager cm = (ConnectivityManager) applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE); + NetworkInfo activeNetwork = cm.getActiveNetworkInfo(); + boolean result = (activeNetwork != null && activeNetwork.isConnected()); + Log.i("IOUtils", "isConnected result = " + result); + return result; + } + } 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 0ccccd049d6..accdbec40f7 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 @@ -2,8 +2,10 @@ import android.text.TextUtils; import android.util.Log; + +import com.mapbox.mapboxsdk.MapboxAccountManager; import com.mapbox.mapboxsdk.constants.MapboxConstants; -import com.mapbox.mapboxsdk.utils.IOUtils; + import java.io.IOException; import java.io.InterruptedIOException; import java.net.NoRouteToHostException; @@ -11,7 +13,9 @@ import java.net.SocketException; import java.net.UnknownHostException; import java.util.concurrent.locks.ReentrantLock; + import javax.net.ssl.SSLException; + import okhttp3.Call; import okhttp3.Callback; import okhttp3.HttpUrl; @@ -46,7 +50,7 @@ private HTTPRequest(long nativePtr, String resourceUrl, String userAgent, String try { // Don't try a request if we aren't connected - if (!IOUtils.getInstance(null).isConnected()) { + if (!MapboxAccountManager.getInstance().isConnected()) { throw new NoRouteToHostException("No Internet connection available."); } 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 index 5f65bfecf44..34ff31cd2f7 100644 --- 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 @@ -11,8 +11,6 @@ import android.content.pm.ServiceInfo; import android.content.res.Configuration; import android.location.Location; -import android.net.ConnectivityManager; -import android.net.NetworkInfo; import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; import android.os.AsyncTask; @@ -25,15 +23,18 @@ import android.util.DisplayMetrics; import android.util.Log; import android.view.WindowManager; + import com.mapbox.mapboxsdk.BuildConfig; +import com.mapbox.mapboxsdk.MapboxAccountManager; 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.IOUtils; 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; @@ -44,6 +45,7 @@ import java.util.TimerTask; import java.util.UUID; import java.util.Vector; + import okhttp3.CertificatePinner; import okhttp3.MediaType; import okhttp3.OkHttpClient; @@ -630,7 +632,7 @@ protected Void doInBackground(Void... voids) { } // Check for NetworkConnectivity - if (!IOUtils.getInstance(null).isConnected()) { + if (!MapboxAccountManager.getInstance().isConnected()) { Log.w(TAG, "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. diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/utils/IOUtils.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/utils/IOUtils.java deleted file mode 100644 index 839e078d64b..00000000000 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/utils/IOUtils.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.mapbox.mapboxsdk.utils; - -import android.content.Context; -import android.net.ConnectivityManager; -import android.net.NetworkInfo; -import android.support.annotation.NonNull; -import android.util.Log; - -public class IOUtils { - - private static IOUtils instance = null; - private Context context = null; - - /** - * Private Constructor for Singleton - * @param context Context - */ - private IOUtils(@NonNull Context context) { - super(); - this.context = context; - } - - public static IOUtils getInstance(Context context) { - if (instance == null) { - instance = new IOUtils(context); - } - return instance; - } - - /** - * Determines whether we have an Internet connection available. - * - * @return true if there is an Internet connection, false otherwise - */ - public boolean isConnected() { - ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); - NetworkInfo activeNetwork = cm.getActiveNetworkInfo(); - boolean result = (activeNetwork != null && activeNetwork.isConnected()); - Log.i("IOUtils", "isConnected result = " + result); - return result; - } -} From 883e0e602763dde00820daa9ef953fa7aa373e4c Mon Sep 17 00:00:00 2001 From: Antonio Zugaldia Date: Wed, 24 Aug 2016 09:13:32 -0400 Subject: [PATCH 5/5] [android] #6042 - switch debug level to verbose --- .../main/java/com/mapbox/mapboxsdk/MapboxAccountManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/MapboxAccountManager.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/MapboxAccountManager.java index f26ceec6591..4930384f5cb 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/MapboxAccountManager.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/MapboxAccountManager.java @@ -94,7 +94,7 @@ public boolean isConnected() { ConnectivityManager cm = (ConnectivityManager) applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo activeNetwork = cm.getActiveNetworkInfo(); boolean result = (activeNetwork != null && activeNetwork.isConnected()); - Log.i("IOUtils", "isConnected result = " + result); + Log.v("IOUtils", "isConnected result = " + result); return result; }