summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeith Bade <leith@mapbox.com>2015-07-31 13:00:52 +1000
committerLeith Bade <leith@mapbox.com>2015-08-11 11:59:08 +1000
commit0cbe7e07f5ada444de45b3936f7378dd4f3b9d6b (patch)
tree72e2e56f37659d9b55b2815ed9aa8a1e363c1184
parentdc11b8132ba7ccc58c280e580526425e7389df86 (diff)
downloadqtlocation-mapboxgl-0cbe7e07f5ada444de45b3936f7378dd4f3b9d6b.tar.gz
Use OkHTTP to implement HTTPContext on Android.
Closes #823
-rw-r--r--android/cpp/jni.cpp142
-rw-r--r--android/cpp/native_map_view.cpp81
-rw-r--r--android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/http/HTTPContext.java93
-rw-r--r--android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/util/JavaFileSource.java51
-rw-r--r--android/mapboxgl-app.gypi5
-rw-r--r--gyp/http-android.gypi70
-rw-r--r--include/mbgl/android/jni.hpp29
-rw-r--r--mbgl.gyp1
-rw-r--r--platform/android/http_request_android.cpp399
-rw-r--r--platform/default/http_request_curl.cpp109
-rw-r--r--scripts/android/configure.sh4
-rw-r--r--scripts/android/defaults.mk2
12 files changed, 734 insertions, 252 deletions
diff --git a/android/cpp/jni.cpp b/android/cpp/jni.cpp
index 6d7def861c..f1e9072cbd 100644
--- a/android/cpp/jni.cpp
+++ b/android/cpp/jni.cpp
@@ -28,6 +28,8 @@
namespace mbgl {
namespace android {
+JavaVM* theJVM;
+
std::string cachePath;
std::string dataPath;
std::string apkPath;
@@ -90,7 +92,15 @@ jmethodID pointFConstructorId = nullptr;
jfieldID pointFXId = nullptr;
jfieldID pointFYId = nullptr;
-bool throw_error(JNIEnv *env, const char *msg) {
+jclass httpContextClass = nullptr;
+jmethodID httpContextGetInstanceId = nullptr;
+jmethodID httpContextCreateRequestId = nullptr;
+
+jclass httpRequestClass = nullptr;
+jmethodID httpRequestStartId = nullptr;
+jmethodID httpRequestCancelId = nullptr;
+
+bool throw_jni_error(JNIEnv *env, const char *msg) {
if (env->ThrowNew(runtimeExceptionClass, msg) < 0) {
env->ExceptionDescribe();
return false;
@@ -99,6 +109,41 @@ bool throw_error(JNIEnv *env, const char *msg) {
return true;
}
+bool attach_jni_thread(JavaVM* vm, JNIEnv** env, std::string threadName) {
+ JavaVMAttachArgs args = {JNI_VERSION_1_2, threadName.c_str(), NULL};
+
+ jint ret;
+ *env = nullptr;
+ bool detach = false;
+ ret = vm->GetEnv(reinterpret_cast<void **>(env), JNI_VERSION_1_6);
+ if (ret != JNI_OK) {
+ if (ret != JNI_EDETACHED) {
+ mbgl::Log::Error(mbgl::Event::JNI, "GetEnv() failed with %i", ret);
+ throw new std::runtime_error("GetEnv() failed");
+ } else {
+ ret = vm->AttachCurrentThread(env, &args);
+ if (ret != JNI_OK) {
+ mbgl::Log::Error(mbgl::Event::JNI, "AttachCurrentThread() failed with %i", ret);
+ throw new std::runtime_error("AttachCurrentThread() failed");
+ }
+ detach = true;
+ }
+ }
+
+ return detach;
+}
+
+void detach_jni_thread(JavaVM* vm, JNIEnv** env, bool detach) {
+ if (detach) {
+ jint ret;
+ if ((ret = vm->DetachCurrentThread()) != JNI_OK) {
+ mbgl::Log::Error(mbgl::Event::JNI, "DetachCurrentThread() failed with %i", ret);
+ throw new std::runtime_error("DetachCurrentThread() failed");
+ }
+ }
+ *env = nullptr;
+}
+
std::string std_string_from_jstring(JNIEnv *env, jstring jstr) {
std::string str;
@@ -342,7 +387,7 @@ void JNICALL nativeInitializeDisplay(JNIEnv *env, jobject obj, jlong nativeMapVi
{
nativeMapView->initializeDisplay();
} catch(const std::exception& e) {
- throw_error(env, "Unable to initialize GL display.");
+ throw_jni_error(env, "Unable to initialize GL display.");
}
}
@@ -361,7 +406,7 @@ void JNICALL nativeInitializeContext(JNIEnv *env, jobject obj, jlong nativeMapVi
try {
nativeMapView->initializeContext();
} catch(const std::exception& e) {
- throw_error(env, "Unable to initialize GL context.");
+ throw_jni_error(env, "Unable to initialize GL context.");
}
}
@@ -380,7 +425,7 @@ void JNICALL nativeCreateSurface(JNIEnv *env, jobject obj, jlong nativeMapViewPt
try {
nativeMapView->createSurface(ANativeWindow_fromSurface(env, surface));
} catch(const std::exception& e) {
- throw_error(env, "Unable to create GL surface.");
+ throw_jni_error(env, "Unable to create GL surface.");
}
}
@@ -1131,6 +1176,8 @@ extern "C" {
extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
mbgl::Log::Debug(mbgl::Event::JNI, "JNI_OnLoad");
+ theJVM = vm;
+
JNIEnv *env = nullptr;
jint ret = vm->GetEnv(reinterpret_cast<void **>(&env), JNI_VERSION_1_6);
if (ret != JNI_OK) {
@@ -1426,6 +1473,36 @@ extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
return JNI_ERR;
}
+ httpContextClass = env->FindClass("com/mapbox/mapboxgl/http/HTTPContext");
+ if (httpContextClass == nullptr) {
+ env->ExceptionDescribe();
+ }
+
+ httpContextGetInstanceId = env->GetStaticMethodID(httpContextClass, "getInstance", "()Lcom/mapbox/mapboxgl/http/HTTPContext;");
+ if (httpContextGetInstanceId == nullptr) {
+ env->ExceptionDescribe();
+ }
+
+ httpContextCreateRequestId = env->GetMethodID(httpContextClass, "createRequest", "(JLjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Lcom/mapbox/mapboxgl/http/HTTPContext$HTTPRequest;");
+ if (httpContextCreateRequestId == nullptr) {
+ env->ExceptionDescribe();
+ }
+
+ httpRequestClass = env->FindClass("com/mapbox/mapboxgl/http/HTTPContext$HTTPRequest");
+ if (httpRequestClass == nullptr) {
+ env->ExceptionDescribe();
+ }
+
+ httpRequestStartId = env->GetMethodID(httpRequestClass, "start", "()V");
+ if (httpRequestStartId == nullptr) {
+ env->ExceptionDescribe();
+ }
+
+ httpRequestCancelId = env->GetMethodID(httpRequestClass, "cancel", "()V");
+ if (httpRequestCancelId == nullptr) {
+ env->ExceptionDescribe();
+ }
+
const std::vector<JNINativeMethod> methods = {
{"nativeCreate", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;FIJ)J",
reinterpret_cast<void *>(&nativeCreate)},
@@ -1524,10 +1601,16 @@ extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
//{"nativeGetWorldBoundsMeters", "(J)V", reinterpret_cast<void *>(&nativeGetWorldBoundsMeters)},
//{"nativeGetWorldBoundsLatLng", "(J)V", reinterpret_cast<void *>(&nativeGetWorldBoundsLatLng)},
{"nativeGetMetersPerPixelAtLatitude", "(JDD)D", reinterpret_cast<void *>(&nativeGetMetersPerPixelAtLatitude)},
- {"nativeProjectedMetersForLatLng", "(JLcom/mapbox/mapboxgl/geometry/LatLng;)Lcom/mapbox/mapboxgl/geometry/ProjectedMeters;", reinterpret_cast<void *>(&nativeProjectedMetersForLatLng)},
- {"nativeLatLngForProjectedMeters", "(JLcom/mapbox/mapboxgl/geometry/ProjectedMeters;)Lcom/mapbox/mapboxgl/geometry/LatLng;", reinterpret_cast<void *>(&nativeLatLngForProjectedMeters)},
- {"nativePixelForLatLng", "(JLcom/mapbox/mapboxgl/geometry/LatLng;)Landroid/graphics/PointF;", reinterpret_cast<void *>(&nativePixelForLatLng)},
- {"nativeLatLngForPixel", "(JLandroid/graphics/PointF;)Lcom/mapbox/mapboxgl/geometry/LatLng;", reinterpret_cast<void *>(&nativeLatLngForPixel)},
+ {"nativeProjectedMetersForLatLng",
+ "(JLcom/mapbox/mapboxgl/geometry/LatLng;)Lcom/mapbox/mapboxgl/geometry/ProjectedMeters;",
+ reinterpret_cast<void *>(&nativeProjectedMetersForLatLng)},
+ {"nativeLatLngForProjectedMeters",
+ "(JLcom/mapbox/mapboxgl/geometry/ProjectedMeters;)Lcom/mapbox/mapboxgl/geometry/LatLng;",
+ reinterpret_cast<void *>(&nativeLatLngForProjectedMeters)},
+ {"nativePixelForLatLng", "(JLcom/mapbox/mapboxgl/geometry/LatLng;)Landroid/graphics/PointF;",
+ reinterpret_cast<void *>(&nativePixelForLatLng)},
+ {"nativeLatLngForPixel", "(JLandroid/graphics/PointF;)Lcom/mapbox/mapboxgl/geometry/LatLng;",
+ reinterpret_cast<void *>(&nativeLatLngForPixel)},
};
if (env->RegisterNatives(nativeMapViewClass, methods.data(), methods.size()) < 0) {
@@ -1641,6 +1724,37 @@ extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
return JNI_ERR;
}
+ httpContextClass = reinterpret_cast<jclass>(env->NewGlobalRef(httpContextClass));
+ if (httpContextClass == nullptr) {
+ env->ExceptionDescribe();
+ env->DeleteGlobalRef(latLngClass);
+ env->DeleteGlobalRef(markerClass);
+ env->DeleteGlobalRef(latLngZoomClass);
+ env->DeleteGlobalRef(polylineClass);
+ env->DeleteGlobalRef(polygonClass);
+ env->DeleteGlobalRef(runtimeExceptionClass);
+ env->DeleteGlobalRef(nullPointerExceptionClass);
+ env->DeleteGlobalRef(arrayListClass);
+ env->DeleteGlobalRef(projectedMetersClass);
+ env->DeleteGlobalRef(pointFClass);
+ }
+
+ httpRequestClass = reinterpret_cast<jclass>(env->NewGlobalRef(httpRequestClass));
+ if (httpRequestClass == nullptr) {
+ env->ExceptionDescribe();
+ env->DeleteGlobalRef(latLngClass);
+ env->DeleteGlobalRef(markerClass);
+ env->DeleteGlobalRef(latLngZoomClass);
+ env->DeleteGlobalRef(polylineClass);
+ env->DeleteGlobalRef(polygonClass);
+ env->DeleteGlobalRef(runtimeExceptionClass);
+ env->DeleteGlobalRef(nullPointerExceptionClass);
+ env->DeleteGlobalRef(arrayListClass);
+ env->DeleteGlobalRef(projectedMetersClass);
+ env->DeleteGlobalRef(pointFClass);
+ env->DeleteGlobalRef(httpContextClass);
+ }
+
char release[PROP_VALUE_MAX] = "";
__system_property_get("ro.build.version.release", release);
androidRelease = std::string(release);
@@ -1651,6 +1765,8 @@ extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
extern "C" JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *vm, void *reserved) {
mbgl::Log::Debug(mbgl::Event::JNI, "JNI_OnUnload");
+ theJVM = vm;
+
JNIEnv *env = nullptr;
jint ret = vm->GetEnv(reinterpret_cast<void **>(&env), JNI_VERSION_1_6);
if (ret != JNI_OK) {
@@ -1725,5 +1841,15 @@ extern "C" JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *vm, void *reserved) {
pointFConstructorId = nullptr;
pointFXId = nullptr;
pointFYId = nullptr;
+
+ env->DeleteGlobalRef(httpContextClass);
+ httpContextGetInstanceId = nullptr;
+ httpContextCreateRequestId = nullptr;
+
+ env->DeleteGlobalRef(httpRequestClass);
+ httpRequestStartId = nullptr;
+ httpRequestCancelId = nullptr;
+
+ theJVM = nullptr;
}
}
diff --git a/android/cpp/native_map_view.cpp b/android/cpp/native_map_view.cpp
index d0581212df..d7c40ba5a1 100644
--- a/android/cpp/native_map_view.cpp
+++ b/android/cpp/native_map_view.cpp
@@ -148,38 +148,15 @@ void NativeMapView::invalidate() {
assert(vm != nullptr);
assert(obj != nullptr);
- JavaVMAttachArgs args = {JNI_VERSION_1_2, "NativeMapView::invalidate()", NULL};
-
- jint ret;
JNIEnv *env = nullptr;
- bool detach = false;
- ret = vm->GetEnv(reinterpret_cast<void **>(&env), JNI_VERSION_1_6);
- if (ret != JNI_OK) {
- if (ret != JNI_EDETACHED) {
- mbgl::Log::Error(mbgl::Event::JNI, "GetEnv() failed with %i", ret);
- throw new std::runtime_error("GetEnv() failed");
- } else {
- ret = vm->AttachCurrentThread(&env, &args);
- if (ret != JNI_OK) {
- mbgl::Log::Error(mbgl::Event::JNI, "AttachCurrentThread() failed with %i", ret);
- throw new std::runtime_error("AttachCurrentThread() failed");
- }
- detach = true;
- }
- }
+ bool detach = attach_jni_thread(vm, &env, "NativeMapView::invalidate()");
env->CallVoidMethod(obj, onInvalidateId);
if (env->ExceptionCheck()) {
env->ExceptionDescribe();
}
- if (detach) {
- if ((ret = vm->DetachCurrentThread()) != JNI_OK) {
- mbgl::Log::Error(mbgl::Event::JNI, "DetachCurrentThread() failed with %i", ret);
- throw new std::runtime_error("DetachCurrentThread() failed");
- }
- }
- env = nullptr;
+ detach_jni_thread(vm, &env, detach);
}
void NativeMapView::swap() {
@@ -662,38 +639,15 @@ void NativeMapView::notifyMapChange(mbgl::MapChange) {
assert(vm != nullptr);
assert(obj != nullptr);
- JavaVMAttachArgs args = {JNI_VERSION_1_2, "NativeMapView::notifyMapChange()", NULL};
-
- jint ret;
JNIEnv *env = nullptr;
- bool detach = false;
- ret = vm->GetEnv(reinterpret_cast<void **>(&env), JNI_VERSION_1_6);
- if (ret != JNI_OK) {
- if (ret != JNI_EDETACHED) {
- mbgl::Log::Error(mbgl::Event::JNI, "GetEnv() failed with %i", ret);
- throw new std::runtime_error("GetEnv() failed");
- } else {
- ret = vm->AttachCurrentThread(&env, &args);
- if (ret != JNI_OK) {
- mbgl::Log::Error(mbgl::Event::JNI, "AttachCurrentThread() failed with %i", ret);
- throw new std::runtime_error("AttachCurrentThread() failed");
- }
- detach = true;
- }
- }
+ bool detach = attach_jni_thread(vm, &env, "NativeMapView::notifyMapChange()");
env->CallVoidMethod(obj, onMapChangedId);
if (env->ExceptionCheck()) {
env->ExceptionDescribe();
}
- if (detach) {
- if ((ret = vm->DetachCurrentThread()) != JNI_OK) {
- mbgl::Log::Error(mbgl::Event::JNI, "DetachCurrentThread() failed with %i", ret);
- throw new std::runtime_error("DetachCurrentThread() failed");
- }
- }
- env = nullptr;
+ detach_jni_thread(vm, &env, detach);
}
void NativeMapView::enableFps(bool enable) {
@@ -727,38 +681,15 @@ void NativeMapView::updateFps() {
assert(vm != nullptr);
assert(obj != nullptr);
- JavaVMAttachArgs args = {JNI_VERSION_1_2, "NativeMapView::updateFps()", NULL};
-
- jint ret;
JNIEnv *env = nullptr;
- bool detach = false;
- ret = vm->GetEnv(reinterpret_cast<void **>(&env), JNI_VERSION_1_6);
- if (ret != JNI_OK) {
- if (ret != JNI_EDETACHED) {
- mbgl::Log::Error(mbgl::Event::JNI, "GetEnv() failed with %i", ret);
- throw new std::runtime_error("GetEnv() failed");
- } else {
- ret = vm->AttachCurrentThread(&env, &args);
- if (ret != JNI_OK) {
- mbgl::Log::Error(mbgl::Event::JNI, "AttachCurrentThread() failed with %i", ret);
- throw new std::runtime_error("AttachCurrentThread() failed");
- }
- detach = true;
- }
- }
+ bool detach = attach_jni_thread(vm, &env, "NativeMapView::updateFps()");
env->CallVoidMethod(obj, onFpsChangedId, fps);
if (env->ExceptionCheck()) {
env->ExceptionDescribe();
}
- if (detach) {
- if ((ret = vm->DetachCurrentThread()) != JNI_OK) {
- mbgl::Log::Error(mbgl::Event::JNI, "DetachCurrentThread() failed with %i", ret);
- throw new std::runtime_error("DetachCurrentThread() failed");
- }
- }
- env = nullptr;
+ detach_jni_thread(vm, &env, detach);
}
void NativeMapView::onInvalidate() {
diff --git a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/http/HTTPContext.java b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/http/HTTPContext.java
new file mode 100644
index 0000000000..509c79a4a5
--- /dev/null
+++ b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/http/HTTPContext.java
@@ -0,0 +1,93 @@
+package com.mapbox.mapboxgl.http;
+
+import com.mapbox.mapboxgl.constants.MapboxConstants;
+import com.squareup.okhttp.Call;
+import com.squareup.okhttp.Callback;
+import com.squareup.okhttp.OkHttpClient;
+import com.squareup.okhttp.Request;
+import com.squareup.okhttp.Response;
+
+import java.io.IOException;
+import java.io.InterruptedIOException;
+import java.net.ProtocolException;
+import java.net.SocketException;
+import java.net.UnknownHostException;
+
+import javax.net.ssl.SSLException;
+
+class HTTPContext {
+
+ private static final int CONNECTION_ERROR = 0;
+ private static final int TEMPORARY_ERROR = 1;
+ private static final int PERMANENT_ERROR = 2;
+
+ private static HTTPContext mInstance = null;
+
+ private OkHttpClient mClient;
+
+ private HTTPContext() {
+ super();
+ mClient = new OkHttpClient();
+ }
+
+ public static HTTPContext getInstance() {
+ if (mInstance == null) {
+ mInstance = new HTTPContext();
+ }
+
+ return mInstance;
+ }
+
+ public HTTPRequest createRequest(long nativePtr, String resourceUrl, String userAgent, String etag, String modified) {
+ return new HTTPRequest(nativePtr, resourceUrl, userAgent, etag, modified);
+ }
+
+ public class HTTPRequest implements Callback {
+ private long mNativePtr = 0;
+
+ private Call mCall;
+ private Request mRequest;
+
+ private native void nativeOnFailure(long nativePtr, int type, String message);
+ private native void nativeOnResponse(long nativePtr, int code, String message, String etag, String modified, String cacheControl, String expires, byte[] body);
+
+ private HTTPRequest(long nativePtr, String resourceUrl, String userAgent, String etag, String modified) {
+ mNativePtr = nativePtr;
+ Request.Builder builder = new Request.Builder().url(resourceUrl).tag(resourceUrl.toLowerCase(MapboxConstants.MAPBOX_LOCALE)).addHeader("User-Agent", userAgent);
+ if (etag.length() > 0) {
+ builder = builder.addHeader("If-None-Match", etag);
+ } else if (modified.length() > 0) {
+ builder = builder.addHeader("If-Modified-Since", modified);
+ }
+ mRequest = builder.build();
+ }
+
+ public void start() {
+ mCall = HTTPContext.getInstance().mClient.newCall(mRequest);
+ mCall.enqueue(this);
+ }
+
+ public void cancel() {
+ mCall.cancel();
+ }
+
+ @Override
+ public void onFailure(Request request, IOException e) {
+ int type = PERMANENT_ERROR;
+ if ((e instanceof UnknownHostException) || (e instanceof SocketException) || (e instanceof ProtocolException) || (e instanceof SSLException)) {
+ type = CONNECTION_ERROR;
+ } else if ((e instanceof InterruptedIOException)) {
+ type = TEMPORARY_ERROR;
+ }
+ nativeOnFailure(mNativePtr, type, e.getMessage());
+ }
+
+ @Override
+ public void onResponse(Response response) throws IOException {
+ byte[] body = response.body().bytes();
+ response.body().close();
+
+ nativeOnResponse(mNativePtr, response.code(), response.message(), response.header("ETag"), response.header("Last-Modified"), response.header("Cache-Control"), response.header("Expires"), body);
+ }
+ }
+}
diff --git a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/util/JavaFileSource.java b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/util/JavaFileSource.java
deleted file mode 100644
index bd86241888..0000000000
--- a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/util/JavaFileSource.java
+++ /dev/null
@@ -1,51 +0,0 @@
-package com.mapbox.mapboxgl.util;
-
-import com.mapbox.mapboxgl.constants.MapboxConstants;
-import com.squareup.okhttp.Callback;
-import com.squareup.okhttp.OkHttpClient;
-import com.squareup.okhttp.Request;
-
-public class JavaFileSource {
-
- private static JavaFileSource instance = null;
-
- // Single reference to OkHttp for performance gains
- private OkHttpClient client;
-
- /**
- * Private Constructor to support Singleton pattern
- */
- private JavaFileSource() {
- super();
- client = new OkHttpClient();
- }
-
- /**
- * Get the singleton instance of JavaFileSource
- * @return Reference to the Singleton Instance of JavaFileSource
- */
- public static JavaFileSource getInstance() {
- if (instance == null) {
- instance = new JavaFileSource();
- }
- return instance;
- }
-
- /**
- * Make an HTTP Request
- * @param resourceUrl URL to resource
- * @param callback Callback class
- */
- public void request(final String resourceUrl, final Callback callback) {
- Request request = new Request.Builder().url(resourceUrl).tag(resourceUrl.toLowerCase(MapboxConstants.MAPBOX_LOCALE)).build();
- client.newCall(request).enqueue(callback);
- }
-
- /**
- * Attempt to cancel HTTP Request made
- * @param resourceUrl URL of request to cancel
- */
- public void cancel(final String resourceUrl) {
- client.cancel(resourceUrl.toLowerCase(MapboxConstants.MAPBOX_LOCALE));
- }
-}
diff --git a/android/mapboxgl-app.gypi b/android/mapboxgl-app.gypi
index e32775ff72..e3db1269d6 100644
--- a/android/mapboxgl-app.gypi
+++ b/android/mapboxgl-app.gypi
@@ -25,8 +25,6 @@
'<@(boost_cflags)',
],
'libraries': [
- '<@(openssl_static_libs)',
- '<@(libcurl_static_libs)',
'<@(libpng_static_libs)',
'<@(jpeg_static_libs)',
'<@(sqlite_static_libs)',
@@ -45,8 +43,6 @@
'<@(libpng_ldflags)',
'<@(jpeg_ldflags)',
'<@(sqlite_ldflags)',
- '<@(openssl_ldflags)',
- '<@(libcurl_ldflags)',
'<@(zlib_ldflags)',
'<@(libzip_ldflags)',
],
@@ -74,7 +70,6 @@
'copies': [
{
'files': [
- '../common/ca-bundle.crt',
'../styles/styles'
],
'destination': '<(pwd)/../android/java/MapboxGLAndroidSDK/src/main/assets'
diff --git a/gyp/http-android.gypi b/gyp/http-android.gypi
new file mode 100644
index 0000000000..c210db0fb6
--- /dev/null
+++ b/gyp/http-android.gypi
@@ -0,0 +1,70 @@
+{
+ 'targets': [
+ { 'target_name': 'http-android',
+ 'product_name': 'mbgl-http-android',
+ 'type': 'static_library',
+ 'standalone_static_library': 1,
+ 'hard_dependency': 1,
+
+ 'sources': [
+ '../platform/android/http_request_android.cpp',
+ ],
+
+ 'include_dirs': [
+ '../include',
+ '../src',
+ ],
+
+ 'variables': {
+ 'cflags_cc': [
+ '<@(libuv_cflags)',
+ '<@(boost_cflags)',
+ ],
+ 'ldflags': [
+ '<@(libuv_ldflags)',
+ ],
+ 'libraries': [
+ '<@(libuv_static_libs)',
+ ],
+ 'defines': [
+ '-DMBGL_HTTP_ANDROID'
+ ],
+ },
+
+ 'conditions': [
+ ['OS == "mac"', {
+ 'xcode_settings': {
+ 'OTHER_CPLUSPLUSFLAGS': [ '<@(cflags_cc)' ],
+ },
+ }, {
+ 'cflags_cc': [ '<@(cflags_cc)' ],
+ }],
+ ],
+
+ 'direct_dependent_settings': {
+ 'conditions': [
+ ['OS == "mac"', {
+ 'xcode_settings': {
+ 'OTHER_CFLAGS': [ '<@(defines)' ],
+ 'OTHER_CPLUSPLUSFLAGS': [ '<@(defines)' ],
+ }
+ }, {
+ 'cflags': [ '<@(defines)' ],
+ 'cflags_cc': [ '<@(defines)' ],
+ }]
+ ],
+ },
+
+ 'link_settings': {
+ 'conditions': [
+ ['OS == "mac"', {
+ 'libraries': [ '<@(libraries)' ],
+ 'xcode_settings': { 'OTHER_LDFLAGS': [ '<@(ldflags)' ] }
+ }, {
+ 'libraries': [ '<@(libraries)', '<@(ldflags)' ],
+ }]
+ ],
+ },
+ },
+ ],
+}
diff --git a/include/mbgl/android/jni.hpp b/include/mbgl/android/jni.hpp
index f27c8c8449..62cb399d3f 100644
--- a/include/mbgl/android/jni.hpp
+++ b/include/mbgl/android/jni.hpp
@@ -2,15 +2,27 @@
#define MBGL_ANDROID_JNI
#include <string>
+#include <vector>
// Forward definition of JNI types
typedef class _jclass* jclass;
+typedef class _jstring* jstring;
+typedef class _jobject* jobject;
+typedef class _jlongArray* jlongArray;
typedef struct _jmethodID* jmethodID;
typedef struct _jfieldID* jfieldID;
+struct _JavaVM;
+typedef _JavaVM JavaVM;
+
+struct _JNIEnv;
+typedef _JNIEnv JNIEnv;
+
namespace mbgl {
namespace android {
+extern JavaVM* theJVM;
+
extern std::string cachePath;
extern std::string dataPath;
extern std::string apkPath;
@@ -73,6 +85,23 @@ extern jmethodID pointFConstructorId;
extern jfieldID pointFXId;
extern jfieldID pointFYId;
+extern jclass httpContextClass;
+extern jmethodID httpContextGetInstanceId;
+extern jmethodID httpContextCreateRequestId;
+
+extern jclass httpRequestClass;
+extern jmethodID httpRequestStartId;
+extern jmethodID httpRequestCancelId;
+
+extern bool throw_jni_error(JNIEnv *env, const char *msg);
+extern bool attach_jni_thread(JavaVM* vm, JNIEnv** env, std::string threadName);
+extern void detach_jni_thread(JavaVM* vm, JNIEnv** env, bool detach);
+extern std::string std_string_from_jstring(JNIEnv *env, jstring jstr);
+extern jstring std_string_to_jstring(JNIEnv *env, std::string str);
+extern std::vector<std::string> std_vector_string_from_jobject(JNIEnv *env, jobject jlist);
+extern jobject std_vector_string_to_jobject(JNIEnv *env, std::vector<std::string> vector);
+extern jlongArray std_vector_uint_to_jobject(JNIEnv *env, std::vector<uint32_t> vector);
+
}
}
diff --git a/mbgl.gyp b/mbgl.gyp
index c5ede28233..959a9729d6 100644
--- a/mbgl.gyp
+++ b/mbgl.gyp
@@ -18,6 +18,7 @@
['platform_lib == "android" and host == "android"', { 'includes': [ './gyp/platform-android.gypi' ] } ],
['http_lib == "curl"', { 'includes': [ './gyp/http-curl.gypi' ] } ],
['http_lib == "nsurl" and (host == "osx" or host == "ios")', { 'includes': [ './gyp/http-nsurl.gypi' ] } ],
+ ['http_lib == "android" and host == "android"', { 'includes': [ './gyp/http-android.gypi' ] } ],
['asset_lib == "fs"', { 'includes': [ './gyp/asset-fs.gypi' ] } ],
['asset_lib == "zip"', { 'includes': [ './gyp/asset-zip.gypi' ] } ],
['cache_lib == "sqlite"', { 'includes': [ './gyp/cache-sqlite.gypi' ] } ],
diff --git a/platform/android/http_request_android.cpp b/platform/android/http_request_android.cpp
new file mode 100644
index 0000000000..044f772628
--- /dev/null
+++ b/platform/android/http_request_android.cpp
@@ -0,0 +1,399 @@
+#include <mbgl/storage/http_context_base.hpp>
+#include <mbgl/storage/http_request_base.hpp>
+#include <mbgl/storage/resource.hpp>
+#include <mbgl/storage/response.hpp>
+#include <mbgl/util/chrono.hpp>
+#include <mbgl/platform/log.hpp>
+#include <mbgl/android/jni.hpp>
+
+#include <mbgl/util/time.hpp>
+#include <mbgl/util/util.hpp>
+#include <mbgl/util/string.hpp>
+#include <mbgl/util/parsedate.h>
+
+#include <jni.h>
+
+namespace mbgl {
+
+void JNICALL nativeOnFailure(JNIEnv *env, jobject obj, jlong nativePtr, jint type, jstring message);
+void JNICALL nativeOnResponse(JNIEnv *env, jobject obj, jlong nativePtr, jint code, jstring message, jstring etag, jstring modified, jstring cacheControl, jstring expires, jbyteArray body);
+
+class HTTPAndroidRequest;
+
+class HTTPAndroidContext : public HTTPContextBase {
+public:
+ explicit HTTPAndroidContext(uv_loop_t *loop);
+ ~HTTPAndroidContext();
+
+ HTTPRequestBase* createRequest(const Resource&,
+ RequestBase::Callback,
+ uv_loop_t*,
+ std::shared_ptr<const Response>) final;
+
+ uv_loop_t *loop = nullptr;
+
+ JavaVM *vm = nullptr;
+ jobject obj = nullptr;
+};
+
+class HTTPAndroidRequest : public HTTPRequestBase {
+public:
+ HTTPAndroidRequest(HTTPAndroidContext*,
+ const Resource&,
+ Callback,
+ uv_loop_t*,
+ std::shared_ptr<const Response>);
+ ~HTTPAndroidRequest();
+
+ void cancel() final;
+ void retry() final;
+
+ void onFailure(int type, std::string message);
+ void onResponse(int code, std::string message, std::string etag, std::string modified, std::string cacheControl, std::string expires, std::string body);
+
+private:
+ void retry(uint64_t timeout) final;
+#if UV_VERSION_MAJOR == 0 && UV_VERSION_MINOR <= 10
+ static void restart(uv_timer_t *timer, int);
+#else
+ static void restart(uv_timer_t *timer);
+#endif
+ void finish(ResponseStatus status);
+ void start();
+
+ HTTPAndroidContext *context = nullptr;
+
+ bool cancelled = false;
+
+ std::unique_ptr<Response> response;
+ const std::shared_ptr<const Response> existingResponse;
+
+ jobject obj = nullptr;
+
+ uv_timer_t *timer = nullptr;
+ enum : bool { PreemptImmediately, ExponentialBackoff } strategy = PreemptImmediately;
+ int attempts = 0;
+
+ static const int maxAttempts = 4;
+
+ static const int connectionError = 0;
+ static const int temporaryError = 1;
+ static const int permanentError = 1;
+};
+
+// -------------------------------------------------------------------------------------------------
+
+HTTPAndroidContext::HTTPAndroidContext(uv_loop_t *loop_)
+ : HTTPContextBase(loop_),
+ loop(loop_),
+ vm(mbgl::android::theJVM) {
+
+ JNIEnv *env = nullptr;
+ bool detach = mbgl::android::attach_jni_thread(vm, &env, "HTTPAndroidContext::HTTPAndroidContext()");
+
+ const std::vector<JNINativeMethod> methods = {
+ {"nativeOnFailure", "(JILjava/lang/String;)V", reinterpret_cast<void *>(&nativeOnFailure)},
+ {"nativeOnResponse",
+ "(JILjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;[B)V",
+ reinterpret_cast<void *>(&nativeOnResponse)}
+ };
+
+ if (env->RegisterNatives(mbgl::android::httpRequestClass, methods.data(), methods.size()) < 0) {
+ env->ExceptionDescribe();
+ }
+
+ obj = env->CallStaticObjectMethod(mbgl::android::httpContextClass, mbgl::android::httpContextGetInstanceId);
+ if (env->ExceptionCheck() || (obj == nullptr)) {
+ env->ExceptionDescribe();
+ }
+
+ obj = env->NewGlobalRef(obj);
+ if (obj == nullptr) {
+ env->ExceptionDescribe();
+ }
+
+ mbgl::android::detach_jni_thread(vm, &env, detach);
+}
+
+HTTPAndroidContext::~HTTPAndroidContext() {
+ JNIEnv *env = nullptr;
+ bool detach = mbgl::android::attach_jni_thread(vm, &env, "HTTPAndroidContext::~HTTPAndroidContext()");
+
+ env->DeleteGlobalRef(obj);
+ obj = nullptr;
+
+ mbgl::android::detach_jni_thread(vm, &env, detach);
+
+ vm = nullptr;
+}
+
+HTTPRequestBase* HTTPAndroidContext::createRequest(const Resource& resource,
+ RequestBase::Callback callback,
+ uv_loop_t* loop_,
+ std::shared_ptr<const Response> response) {
+ return new HTTPAndroidRequest(this, resource, callback, loop_, response);
+}
+
+HTTPAndroidRequest::HTTPAndroidRequest(HTTPAndroidContext* context_, const Resource& resource_, Callback callback_, uv_loop_t*, std::shared_ptr<const Response> response_)
+ : HTTPRequestBase(resource_, callback_),
+ context(context_),
+ existingResponse(response_) {
+
+ std::string etagStr;
+ std::string modifiedStr;
+ if (existingResponse) {
+ if (!existingResponse->etag.empty()) {
+ etagStr = existingResponse->etag;
+ } else if (existingResponse->modified) {
+ modifiedStr = util::rfc1123(existingResponse->modified);
+ }
+ }
+
+ JNIEnv *env = nullptr;
+ bool detach = mbgl::android::attach_jni_thread(context->vm, &env, "HTTPAndroidContext::HTTPAndroidRequest()");
+
+ jstring resourceUrl = mbgl::android::std_string_to_jstring(env, resource.url);
+ jstring userAgent = mbgl::android::std_string_to_jstring(env, "MapboxGL/1.0");
+ jstring etag = mbgl::android::std_string_to_jstring(env, etagStr);
+ jstring modified = mbgl::android::std_string_to_jstring(env, modifiedStr);
+ obj = env->CallObjectMethod(context->obj, mbgl::android::httpContextCreateRequestId, reinterpret_cast<jlong>(this), resourceUrl, userAgent, etag, modified);
+ if (env->ExceptionCheck() || (obj == nullptr)) {
+ env->ExceptionDescribe();
+ }
+
+ obj = env->NewGlobalRef(obj);
+ if (obj == nullptr) {
+ env->ExceptionDescribe();
+ }
+
+ mbgl::android::detach_jni_thread(context->vm, &env, detach);
+
+ context->addRequest(this);
+ start();
+}
+
+HTTPAndroidRequest::~HTTPAndroidRequest() {
+ context->removeRequest(this);
+
+ JNIEnv *env = nullptr;
+ bool detach = mbgl::android::attach_jni_thread(context->vm, &env, "HTTPAndroidContext::~HTTPAndroidRequest()");
+
+ env->DeleteGlobalRef(obj);
+ obj = nullptr;
+
+ mbgl::android::detach_jni_thread(context->vm, &env, detach);
+
+ if (timer) {
+ uv_timer_stop(timer);
+ uv::close(timer);
+ timer = nullptr;
+ }
+}
+
+void HTTPAndroidRequest::cancel() {
+ cancelled = true;
+
+ JNIEnv *env = nullptr;
+ bool detach = mbgl::android::attach_jni_thread(context->vm, &env, "HTTPAndroidContext::cancel()");
+
+ env->CallVoidMethod(obj, mbgl::android::httpRequestCancelId);
+ if (env->ExceptionCheck()) {
+ env->ExceptionDescribe();
+ }
+
+ mbgl::android::detach_jni_thread(context->vm, &env, detach);
+}
+
+void HTTPAndroidRequest::start() {
+ attempts++;
+
+ JNIEnv *env = nullptr;
+ bool detach = mbgl::android::attach_jni_thread(context->vm, &env, "HTTPAndroidContext::start()");
+
+ env->CallVoidMethod(obj, mbgl::android::httpRequestStartId);
+ if (env->ExceptionCheck()) {
+ env->ExceptionDescribe();
+ }
+
+ mbgl::android::detach_jni_thread(context->vm, &env, detach);
+}
+
+void HTTPAndroidRequest::retry(uint64_t timeout) {
+ response.reset();
+
+ assert(!timer);
+ timer = new uv_timer_t;
+ timer->data = this;
+ uv_timer_init(context->loop, timer);
+ uv_timer_start(timer, restart, timeout, 0);
+}
+
+void HTTPAndroidRequest::retry() {
+ if (timer && strategy == PreemptImmediately) {
+ uv_timer_stop(timer);
+ uv_timer_start(timer, restart, 0, 0);
+ }
+}
+
+#if UV_VERSION_MAJOR == 0 && UV_VERSION_MINOR <= 10
+void HTTPAndroidRequest::restart(uv_timer_t *timer, int) {
+#else
+void HTTPAndroidRequest::restart(uv_timer_t *timer) {
+#endif
+ auto baton = reinterpret_cast<HTTPAndroidRequest *>(timer->data);
+
+ baton->timer = nullptr;
+ uv::close(timer);
+
+ baton->start();
+}
+
+void HTTPAndroidRequest::finish(ResponseStatus status) {
+ if (status == ResponseStatus::TemporaryError && attempts < maxAttempts) {
+ strategy = ExponentialBackoff;
+ return retry((1 << (attempts - 1)) * 1000);
+ } else if (status == ResponseStatus::ConnectionError && attempts < maxAttempts) {
+ strategy = PreemptImmediately;
+ return retry(30000);
+ }
+
+ if (status == ResponseStatus::NotModified) {
+ notify(std::move(response), FileCache::Hint::Refresh);
+ } else {
+ notify(std::move(response), FileCache::Hint::Full);
+ }
+
+ delete this;
+}
+
+int64_t parseCacheControl(const char *value) {
+ if (value) {
+ unsigned long long seconds = 0;
+ // TODO: cache-control may contain other information as well:
+ // http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9
+ if (std::sscanf(value, "max-age=%llu", &seconds) == 1) {
+ return std::chrono::duration_cast<std::chrono::seconds>(
+ std::chrono::system_clock::now().time_since_epoch()).count() +
+ seconds;
+ }
+ }
+
+ return 0;
+}
+
+void HTTPAndroidRequest::onResponse(int code, std::string message, std::string etag, std::string modified, std::string cacheControl, std::string expires, std::string body) {
+ if (cancelled) {
+ delete this;
+ return;
+ }
+
+ if (!response) {
+ response = std::make_unique<Response>();
+ }
+
+ response->message = message;
+ response->modified = parse_date(modified.c_str());
+ response->etag = etag;
+ response->expires = parseCacheControl(cacheControl.c_str());
+ if (!expires.empty()) {
+ response->expires = parse_date(expires.c_str());
+ }
+ response->data = body;
+
+ if (code == 304) {
+ if (existingResponse) {
+ response->status = existingResponse->status;
+ response->message = existingResponse->message;
+ response->modified = existingResponse->modified;
+ response->etag = existingResponse->etag;
+ response->data = existingResponse->data;
+ return finish(ResponseStatus::NotModified);
+ } else {
+ response->status = Response::Successful;
+ return finish(ResponseStatus::Successful);
+ }
+ } else if (code == 200) {
+ response->status = Response::Successful;
+ return finish(ResponseStatus::Successful);
+ } else if (code >= 500 && code < 600) {
+ response->status = Response::Error;
+ response->message = "HTTP status code " + util::toString(code);
+ return finish(ResponseStatus::TemporaryError);
+ } else {
+ response->status = Response::Error;
+ response->message = "HTTP status code " + util::toString(code);
+ return finish(ResponseStatus::PermanentError);
+ }
+
+ throw std::runtime_error("Response hasn't been handled");
+}
+
+void HTTPAndroidRequest::onFailure(int type, std::string message) {
+ if (cancelled) {
+ delete this;
+ return;
+ }
+
+ if (!response) {
+ response = std::make_unique<Response>();
+ }
+
+ response->status = Response::Error;
+ response->message = message;
+
+ switch (type) {
+ case connectionError:
+ return finish(ResponseStatus::ConnectionError);
+
+ case temporaryError:
+ return finish(ResponseStatus::TemporaryError);
+
+ default:
+ return finish(ResponseStatus::PermanentError);
+ }
+
+ throw std::runtime_error("Response hasn't been handled");
+}
+
+std::unique_ptr<HTTPContextBase> HTTPContextBase::createContext(uv_loop_t* loop) {
+ return std::make_unique<HTTPAndroidContext>(loop);
+}
+
+#pragma clang diagnostic ignored "-Wunused-parameter"
+
+void JNICALL nativeOnFailure(JNIEnv *env, jobject obj, jlong nativePtr, jint type, jstring message) {
+ mbgl::Log::Debug(mbgl::Event::JNI, "nativeOnFailure");
+ assert(nativePtr != 0);
+ HTTPAndroidRequest *request = reinterpret_cast<HTTPAndroidRequest *>(nativePtr);
+ std::string messageStr = mbgl::android::std_string_from_jstring(env, message);
+ return request->onFailure(type, messageStr);
+}
+
+void JNICALL nativeOnResponse(JNIEnv *env, jobject obj, jlong nativePtr, jint code, jstring message, jstring etag, jstring modified, jstring cacheControl, jstring expires, jbyteArray body) {
+ mbgl::Log::Debug(mbgl::Event::JNI, "nativeOnResponse");
+ assert(nativePtr != 0);
+ HTTPAndroidRequest *request = reinterpret_cast<HTTPAndroidRequest *>(nativePtr);
+ std::string messageStr = mbgl::android::std_string_from_jstring(env, message);
+ std::string etagStr;
+ if (etag != nullptr) {
+ etagStr = mbgl::android::std_string_from_jstring(env, etag);
+ }
+ std::string modifiedStr;
+ if (modified != nullptr) {
+ modifiedStr = mbgl::android::std_string_from_jstring(env, modified);
+ }
+ std::string cacheControlStr;
+ if (cacheControl != nullptr) {
+ cacheControlStr = mbgl::android::std_string_from_jstring(env, cacheControl);
+ }
+ std::string expiresStr;
+ if (expires != nullptr) {
+ expiresStr = mbgl::android::std_string_from_jstring(env, expires);
+ }
+ jbyte* bodyData = env->GetByteArrayElements(body, nullptr);
+ std::string bodyStr(reinterpret_cast<char*>(bodyData), env->GetArrayLength(body));
+ env->ReleaseByteArrayElements(body, bodyData, JNI_ABORT);
+ return request->onResponse(code, messageStr, etagStr, modifiedStr, cacheControlStr, expiresStr, bodyStr);
+}
+
+}
diff --git a/platform/default/http_request_curl.cpp b/platform/default/http_request_curl.cpp
index 0f7f8c0ac5..e416034b40 100644
--- a/platform/default/http_request_curl.cpp
+++ b/platform/default/http_request_curl.cpp
@@ -11,12 +11,6 @@
#include <curl/curl.h>
-#ifdef __ANDROID__
-#include <mbgl/android/jni.hpp>
-#include <zip.h>
-#include <openssl/ssl.h>
-#endif
-
#include <queue>
#include <map>
#include <cassert>
@@ -331,104 +325,6 @@ int HTTPCURLContext::startTimeout(CURLM * /* multi */, long timeout_ms, void *us
// -------------------------------------------------------------------------------------------------
-#ifdef __ANDROID__
-
-// This function is called to load the CA bundle
-// from http://curl.haxx.se/libcurl/c/cacertinmem.html¯
-static CURLcode sslctx_function(CURL * /* curl */, void *sslctx, void * /* parm */) {
-
- int error = 0;
- struct zip *apk = zip_open(mbgl::android::apkPath.c_str(), 0, &error);
- if (apk == nullptr) {
- return CURLE_SSL_CACERT_BADFILE;
- }
-
- struct zip_file *apkFile = zip_fopen(apk, "assets/ca-bundle.crt", ZIP_FL_NOCASE);
- if (apkFile == nullptr) {
- zip_close(apk);
- apk = nullptr;
- return CURLE_SSL_CACERT_BADFILE;
- }
-
- struct zip_stat stat;
- if (zip_stat(apk, "assets/ca-bundle.crt", ZIP_FL_NOCASE, &stat) != 0) {
- zip_fclose(apkFile);
- apkFile = nullptr;
- zip_close(apk);
- apk = nullptr;
- return CURLE_SSL_CACERT_BADFILE;
- }
-
- if (stat.size > std::numeric_limits<int>::max()) {
- zip_fclose(apkFile);
- apkFile = nullptr;
- zip_close(apk);
- apk = nullptr;
- return CURLE_SSL_CACERT_BADFILE;
- }
-
- const auto pem = std::make_unique<char[]>(stat.size);
-
- if (static_cast<zip_uint64_t>(zip_fread(apkFile, reinterpret_cast<void *>(pem.get()), stat.size)) != stat.size) {
- zip_fclose(apkFile);
- apkFile = nullptr;
- zip_close(apk);
- apk = nullptr;
- return CURLE_SSL_CACERT_BADFILE;
- }
-
- // get a pointer to the X509 certificate store (which may be empty!)
- X509_STORE *store = SSL_CTX_get_cert_store((SSL_CTX *)sslctx);
- if (store == nullptr) {
- return CURLE_SSL_CACERT_BADFILE;
- }
-
- // get a BIO
- BIO *bio = BIO_new_mem_buf(pem.get(), static_cast<int>(stat.size));
- if (bio == nullptr) {
- store = nullptr;
- return CURLE_SSL_CACERT_BADFILE;
- }
-
- // use it to read the PEM formatted certificate from memory into an X509
- // structure that SSL can use
- X509 *cert = nullptr;
- while (PEM_read_bio_X509(bio, &cert, 0, nullptr) != nullptr) {
- if (cert == nullptr) {
- BIO_free(bio);
- bio = nullptr;
- store = nullptr;
- return CURLE_SSL_CACERT_BADFILE;
- }
-
- // add our certificate to this store
- if (X509_STORE_add_cert(store, cert) == 0) {
- X509_free(cert);
- cert = nullptr;
- BIO_free(bio);
- bio = nullptr;
- store = nullptr;
- return CURLE_SSL_CACERT_BADFILE;
- }
-
- X509_free(cert);
- cert = nullptr;
- }
-
- // decrease reference counts
- BIO_free(bio);
- bio = nullptr;
-
- zip_fclose(apkFile);
- apkFile = nullptr;
- zip_close(apk);
- apk = nullptr;
-
- // all set to go
- return CURLE_OK;
-}
-#endif
-
HTTPCURLRequest::HTTPCURLRequest(HTTPCURLContext* context_, const Resource& resource_, Callback callback_, uv_loop_t*, std::shared_ptr<const Response> response_)
: HTTPRequestBase(resource_, callback_),
context(context_),
@@ -458,12 +354,7 @@ HTTPCURLRequest::HTTPCURLRequest(HTTPCURLContext* context_, const Resource& reso
handleError(curl_easy_setopt(handle, CURLOPT_PRIVATE, this));
handleError(curl_easy_setopt(handle, CURLOPT_ERRORBUFFER, error));
-#ifdef __ANDROID__
- handleError(curl_easy_setopt(handle, CURLOPT_SSLCERTTYPE, "PEM"));
- handleError(curl_easy_setopt(handle, CURLOPT_SSL_CTX_FUNCTION, sslctx_function));
-#else
handleError(curl_easy_setopt(handle, CURLOPT_CAINFO, "ca-bundle.crt"));
-#endif
handleError(curl_easy_setopt(handle, CURLOPT_FOLLOWLOCATION, 1));
handleError(curl_easy_setopt(handle, CURLOPT_URL, resource.url.c_str()));
handleError(curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, writeCallback));
diff --git a/scripts/android/configure.sh b/scripts/android/configure.sh
index 667ea68911..70c8973a8b 100644
--- a/scripts/android/configure.sh
+++ b/scripts/android/configure.sh
@@ -1,8 +1,6 @@
#!/usr/bin/env bash
BOOST_VERSION=1.57.0
-LIBCURL_VERSION=7.40.0
-OPENSSL_VERSION=1.0.1l
LIBPNG_VERSION=1.6.16
JPEG_VERSION=v9a
SQLITE_VERSION=3.8.8.1
@@ -11,4 +9,4 @@ ZLIB_VERSION=system
NUNICODE_VERSION=1.5.1
LIBZIP_VERSION=0.11.2
-export MASON_ANDROID_ABI=${MASON_PLATFORM_VERSION} \ No newline at end of file
+export MASON_ANDROID_ABI=${MASON_PLATFORM_VERSION}
diff --git a/scripts/android/defaults.mk b/scripts/android/defaults.mk
index 436f9db710..29f047c887 100644
--- a/scripts/android/defaults.mk
+++ b/scripts/android/defaults.mk
@@ -1,7 +1,7 @@
HEADLESS ?= none
PLATFORM ?= android
ASSET ?= zip
-HTTP ?= curl
+HTTP ?= android
CACHE ?= sqlite
GYP_FLAVOR_SUFFIX=-android