summaryrefslogtreecommitdiff
path: root/platform
diff options
context:
space:
mode:
authorJohn Firebaugh <john.firebaugh@gmail.com>2016-02-28 20:30:58 -0800
committerJohn Firebaugh <john.firebaugh@gmail.com>2016-03-04 15:33:32 -0800
commit235f4ee6f679c9cdf2ab7a374782febee1db3003 (patch)
tree75239e81c6ed5b5fa570b1ecadd48c07db19975e /platform
parent9e0be736fcd00ea3275c8e1b8865a55bf72e05de (diff)
downloadqtlocation-mapboxgl-235f4ee6f679c9cdf2ab7a374782febee1db3003.tar.gz
[android] Use jni.hpp in http_request_android.cpp
Diffstat (limited to 'platform')
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/http/HTTPContext.java153
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/http/HTTPRequest.java99
-rw-r--r--platform/android/mapboxgl-app.gypi1
-rw-r--r--platform/android/src/attach_env.cpp22
-rw-r--r--platform/android/src/attach_env.hpp31
-rw-r--r--platform/android/src/http_request_android.cpp198
-rwxr-xr-xplatform/android/src/jni.cpp106
-rw-r--r--platform/android/src/jni.hpp8
8 files changed, 220 insertions, 398 deletions
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/http/HTTPContext.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/http/HTTPContext.java
deleted file mode 100644
index 7132f8ead6..0000000000
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/http/HTTPContext.java
+++ /dev/null
@@ -1,153 +0,0 @@
-package com.mapbox.mapboxsdk.http;
-
-import android.text.TextUtils;
-import android.util.Log;
-
-import com.mapbox.mapboxsdk.constants.MapboxConstants;
-
-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;
-
-import okhttp3.Call;
-import okhttp3.Callback;
-import okhttp3.Interceptor;
-import okhttp3.OkHttpClient;
-import okhttp3.Request;
-import okhttp3.Response;
-
-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 final int CANCELED_ERROR = 3;
-
- private static HTTPContext mInstance = null;
-
- private OkHttpClient mClient;
-
- private HTTPContext() {
- super();
- mClient = new OkHttpClient();
- //mClient.interceptors().add(new LoggingInterceptor());
- }
-
- 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 final String LOG_TAG = HTTPRequest.class.getName();
-
- 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 onResponse(Call call, Response response) throws IOException {
- if (response.isSuccessful()) {
- Log.v(LOG_TAG, String.format("[HTTP] Request was successful (code = %d).", response.code()));
- } else {
- // We don't want to call this unsuccessful because a 304 isn't really an error
- String message = !TextUtils.isEmpty(response.message()) ? response.message() : "No additional information";
- Log.d(LOG_TAG, String.format(
- "[HTTP] Request with response code = %d: %s",
- response.code(), message));
- }
-
- byte[] body;
- try {
- body = response.body().bytes();
- } catch (IOException e) {
- onFailure(null, e);
- //throw e;
- return;
- } finally {
- response.body().close();
- }
-
- nativeOnResponse(mNativePtr, response.code(), response.message(), response.header("ETag"), response.header("Last-Modified"), response.header("Cache-Control"), response.header("Expires"), body);
- }
-
- @Override
- public void onFailure(Call call, IOException 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)) {
- type = CONNECTION_ERROR;
- } else if ((e instanceof InterruptedIOException)) {
- type = TEMPORARY_ERROR;
- } else if (mCall.isCanceled()) {
- type = CANCELED_ERROR;
- }
-
- String errorMessage = e.getMessage() != null ? e.getMessage() : "Error processing the request";
- nativeOnFailure(mNativePtr, type, errorMessage);
- }
-
- }
-
- /*
- * Application interceptor that logs the outgoing request and the incoming response.
- * Based on https://github.com/square/okhttp/wiki/Interceptors
- */
-
- class LoggingInterceptor implements Interceptor {
-
- private final static String LOG_TAG = "LoggingInterceptor";
-
- @Override public Response intercept(Interceptor.Chain chain) throws IOException {
- Request request = chain.request();
-
- long t1 = System.nanoTime();
- Log.i(LOG_TAG, String.format("Sending request %s on %s%n%s",
- request.url(), chain.connection(), request.headers()));
-
- Response response = chain.proceed(request);
-
- long t2 = System.nanoTime();
- Log.i(LOG_TAG, String.format("Received response for %s in %.1fms%n%s",
- response.request().url(), (t2 - t1) / 1e6d, response.headers()));
-
- return response;
- }
- }
-}
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
new file mode 100644
index 0000000000..66bdc4ae77
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/http/HTTPRequest.java
@@ -0,0 +1,99 @@
+package com.mapbox.mapboxsdk.http;
+
+import android.text.TextUtils;
+import android.util.Log;
+
+import com.mapbox.mapboxsdk.constants.MapboxConstants;
+
+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;
+
+import okhttp3.Call;
+import okhttp3.Callback;
+import okhttp3.Interceptor;
+import okhttp3.OkHttpClient;
+import okhttp3.Request;
+import okhttp3.Response;
+
+class HTTPRequest implements Callback {
+ private static OkHttpClient mClient = new OkHttpClient();
+ private final String LOG_TAG = HTTPRequest.class.getName();
+
+ private static final int CONNECTION_ERROR = 0;
+ private static final int TEMPORARY_ERROR = 1;
+ private static final int PERMANENT_ERROR = 2;
+ private static final int CANCELED_ERROR = 3;
+
+ private long mNativePtr = 0;
+
+ private Call mCall;
+ private Request mRequest;
+
+ private native void nativeOnFailure(int type, String message);
+ private native void nativeOnResponse(int code, 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();
+ mCall = mClient.newCall(mRequest);
+ mCall.enqueue(this);
+ }
+
+ public void cancel() {
+ mCall.cancel();
+ }
+
+ @Override
+ public void onResponse(Call call, Response response) throws IOException {
+ if (response.isSuccessful()) {
+ Log.v(LOG_TAG, String.format("[HTTP] Request was successful (code = %d).", response.code()));
+ } else {
+ // We don't want to call this unsuccessful because a 304 isn't really an error
+ String message = !TextUtils.isEmpty(response.message()) ? response.message() : "No additional information";
+ Log.d(LOG_TAG, String.format(
+ "[HTTP] Request with response code = %d: %s",
+ response.code(), message));
+ }
+
+ byte[] body;
+ try {
+ body = response.body().bytes();
+ } catch (IOException e) {
+ onFailure(null, e);
+ //throw e;
+ return;
+ } finally {
+ response.body().close();
+ }
+
+ nativeOnResponse(response.code(), response.header("ETag"), response.header("Last-Modified"), response.header("Cache-Control"), response.header("Expires"), body);
+ }
+
+ @Override
+ public void onFailure(Call call, IOException 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)) {
+ type = CONNECTION_ERROR;
+ } else if ((e instanceof InterruptedIOException)) {
+ type = TEMPORARY_ERROR;
+ } else if (mCall.isCanceled()) {
+ type = CANCELED_ERROR;
+ }
+
+ String errorMessage = e.getMessage() != null ? e.getMessage() : "Error processing the request";
+ nativeOnFailure(type, errorMessage);
+ }
+}
diff --git a/platform/android/mapboxgl-app.gypi b/platform/android/mapboxgl-app.gypi
index e372f3b536..5e0e653a6f 100644
--- a/platform/android/mapboxgl-app.gypi
+++ b/platform/android/mapboxgl-app.gypi
@@ -22,6 +22,7 @@
'sources': [
'./src/native_map_view.cpp',
'./src/jni.cpp',
+ './src/attach_env.cpp',
],
'cflags_cc': [
diff --git a/platform/android/src/attach_env.cpp b/platform/android/src/attach_env.cpp
new file mode 100644
index 0000000000..6da075ee3e
--- /dev/null
+++ b/platform/android/src/attach_env.cpp
@@ -0,0 +1,22 @@
+#include "attach_env.hpp"
+#include "jni.hpp"
+
+namespace mbgl {
+namespace android {
+
+UniqueEnv AttachEnv() {
+ JNIEnv* env = nullptr;
+ jint err = theJVM->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6);
+
+ switch (err) {
+ case JNI_OK:
+ return UniqueEnv(env, JNIEnvDeleter(*theJVM, false));
+ case JNI_EDETACHED:
+ return UniqueEnv(jni::AttachCurrentThread(*theJVM).release(), JNIEnvDeleter(*theJVM, true));
+ default:
+ throw std::system_error(err, jni::ErrorCategory());
+ }
+}
+
+}
+}
diff --git a/platform/android/src/attach_env.hpp b/platform/android/src/attach_env.hpp
new file mode 100644
index 0000000000..8a9f4a7f8b
--- /dev/null
+++ b/platform/android/src/attach_env.hpp
@@ -0,0 +1,31 @@
+#pragma once
+
+#include <jni/jni.hpp>
+
+namespace mbgl {
+namespace android {
+
+class JNIEnvDeleter {
+private:
+ jni::JavaVM* vm = nullptr;
+ bool detach = false;
+
+public:
+ JNIEnvDeleter() = default;
+ JNIEnvDeleter(jni::JavaVM& v, bool d)
+ : vm(&v), detach(d) {}
+
+ void operator()(jni::JNIEnv* p) const {
+ if (p && detach) {
+ assert(vm);
+ vm->DetachCurrentThread();
+ }
+ }
+};
+
+using UniqueEnv = std::unique_ptr<jni::JNIEnv, JNIEnvDeleter>;
+
+UniqueEnv AttachEnv();
+
+}
+}
diff --git a/platform/android/src/http_request_android.cpp b/platform/android/src/http_request_android.cpp
index 2e2fd6408d..3f95567105 100644
--- a/platform/android/src/http_request_android.cpp
+++ b/platform/android/src/http_request_android.cpp
@@ -3,54 +3,48 @@
#include <mbgl/storage/resource.hpp>
#include <mbgl/storage/response.hpp>
#include <mbgl/platform/log.hpp>
-#include "jni.hpp"
#include <mbgl/util/async_task.hpp>
#include <mbgl/util/util.hpp>
#include <mbgl/util/string.hpp>
-#include <jni.h>
+#include <jni/jni.hpp>
+#include "attach_env.hpp"
namespace mbgl {
+namespace android {
-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 {
+class HTTPContext : public HTTPContextBase {
public:
- explicit HTTPAndroidContext();
- ~HTTPAndroidContext();
-
HTTPRequestBase* createRequest(const Resource&, HTTPRequestBase::Callback) final;
-
- JavaVM *vm = nullptr;
- jobject obj = nullptr;
+ UniqueEnv env { android::AttachEnv() };
};
-class HTTPAndroidRequest : public HTTPRequestBase {
+class HTTPRequest : public HTTPRequestBase {
public:
- HTTPAndroidRequest(HTTPAndroidContext*, const Resource&, Callback);
- ~HTTPAndroidRequest();
+ static constexpr auto Name() { return "com/mapbox/mapboxsdk/http/HTTPRequest"; };
+
+ HTTPRequest(jni::JNIEnv&, const Resource&, Callback);
void cancel() final;
- void onFailure(JNIEnv*, int type, jstring message);
- void onResponse(JNIEnv*, int code, jstring message, jstring etag, jstring modified, jstring cacheControl, jstring expires, jbyteArray body);
+ void onFailure(jni::JNIEnv&, int type, jni::String message);
+ void onResponse(jni::JNIEnv&, int code,
+ jni::String etag, jni::String modified,
+ jni::String cacheControl, jni::String expires,
+ jni::Array<jni::jbyte> body);
+
+ static jni::Class<HTTPRequest> javaClass;
+ jni::UniqueObject<HTTPRequest> javaRequest;
private:
void finish();
- HTTPAndroidContext *context = nullptr;
-
bool cancelled = false;
std::unique_ptr<Response> response;
const std::shared_ptr<const Response> existingResponse;
- jobject obj = nullptr;
-
util::AsyncTask async;
static const int connectionError = 0;
@@ -59,59 +53,27 @@ private:
static const int canceledError = 3;
};
-// -------------------------------------------------------------------------------------------------
-
-HTTPAndroidContext::HTTPAndroidContext()
- : vm(mbgl::android::theJVM) {
+jni::Class<HTTPRequest> HTTPRequest::javaClass;
- JNIEnv *env = nullptr;
- bool detach = mbgl::android::attach_jni_thread(vm, &env, "HTTPAndroidContext::HTTPAndroidContext()");
+void RegisterNativeHTTPRequest(jni::JNIEnv& env) {
+ HTTPRequest::javaClass = *jni::Class<HTTPRequest>::Find(env).NewGlobalRef(env).release();
- 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)}
- };
+ #define METHOD(MethodPtr, name) jni::MakeNativePeerMethod<decltype(MethodPtr), (MethodPtr)>(name)
- 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);
+ jni::RegisterNativePeer<HTTPRequest>(env, HTTPRequest::javaClass, "mNativePtr",
+ METHOD(&HTTPRequest::onFailure, "nativeOnFailure"),
+ METHOD(&HTTPRequest::onResponse, "nativeOnResponse"));
}
-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, HTTPRequestBase::Callback callback) {
- return new HTTPAndroidRequest(this, resource, callback);
+HTTPRequestBase* HTTPContext::createRequest(const Resource& resource, HTTPRequestBase::Callback callback) {
+ return new HTTPRequest(*env, resource, callback);
}
-HTTPAndroidRequest::HTTPAndroidRequest(HTTPAndroidContext* context_, const Resource& resource_, Callback callback_)
+HTTPRequest::HTTPRequest(jni::JNIEnv& env, const Resource& resource_, Callback callback_)
: HTTPRequestBase(resource_, callback_),
- context(context_),
async([this] { finish(); }) {
-
std::string etagStr;
std::string modifiedStr;
@@ -121,56 +83,30 @@ HTTPAndroidRequest::HTTPAndroidRequest(HTTPAndroidContext* context_, const Resou
modifiedStr = util::rfc1123(*resource.priorModified);
}
- 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();
- }
+ jni::UniqueLocalFrame frame = jni::PushLocalFrame(env, 10);
- env->CallVoidMethod(obj, mbgl::android::httpRequestStartId);
- if (env->ExceptionCheck()) {
- env->ExceptionDescribe();
- }
+ static auto constructor =
+ javaClass.GetConstructor<jni::jlong, jni::String, jni::String, jni::String, jni::String>(env);
- mbgl::android::detach_jni_thread(context->vm, &env, detach);
+ javaRequest = javaClass.New(env, constructor,
+ reinterpret_cast<jlong>(this),
+ jni::Make<jni::String>(env, resource.url),
+ jni::Make<jni::String>(env, "MapboxGL/1.0"),
+ jni::Make<jni::String>(env, etagStr),
+ jni::Make<jni::String>(env, modifiedStr)).NewGlobalRef(env);
}
-HTTPAndroidRequest::~HTTPAndroidRequest() {
- 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);
-}
-
-void HTTPAndroidRequest::cancel() {
+void HTTPRequest::cancel() {
cancelled = true;
- JNIEnv *env = nullptr;
- bool detach = mbgl::android::attach_jni_thread(context->vm, &env, "HTTPAndroidContext::cancel()");
+ UniqueEnv env = android::AttachEnv();
- env->CallVoidMethod(obj, mbgl::android::httpRequestCancelId);
- if (env->ExceptionCheck()) {
- env->ExceptionDescribe();
- }
+ static auto cancel = javaClass.GetMethod<void ()>(*env, "cancel");
- mbgl::android::detach_jni_thread(context->vm, &env, detach);
+ javaRequest->Call(*env, cancel);
}
-void HTTPAndroidRequest::finish() {
+void HTTPRequest::finish() {
if (!cancelled) {
assert(response);
notify(*response);
@@ -179,31 +115,33 @@ void HTTPAndroidRequest::finish() {
delete this;
}
-void HTTPAndroidRequest::onResponse(JNIEnv* env, int code, jstring /* message */, jstring etag, jstring modified, jstring cacheControl, jstring expires, jbyteArray body) {
+void HTTPRequest::onResponse(jni::JNIEnv& env, int code,
+ jni::String etag, jni::String modified, jni::String cacheControl,
+ jni::String expires, jni::Array<jni::jbyte> body) {
response = std::make_unique<Response>();
using Error = Response::Error;
- if (etag != nullptr) {
- response->etag = mbgl::android::std_string_from_jstring(env, etag);
+ if (etag) {
+ response->etag = jni::Make<std::string>(env, etag);
}
- if (modified != nullptr) {
- response->modified = util::parseTimePoint(mbgl::android::std_string_from_jstring(env, modified).c_str());
+ if (modified) {
+ response->modified = util::parseTimePoint(jni::Make<std::string>(env, modified).c_str());
}
- if (cacheControl != nullptr) {
- response->expires = parseCacheControl(mbgl::android::std_string_from_jstring(env, cacheControl).c_str());
+ if (cacheControl) {
+ response->expires = parseCacheControl(jni::Make<std::string>(env, cacheControl).c_str());
}
- if (expires != nullptr) {
- response->expires = util::parseTimePoint(mbgl::android::std_string_from_jstring(env, expires).c_str());
+ if (expires) {
+ response->expires = util::parseTimePoint(jni::Make<std::string>(env, expires).c_str());
}
if (code == 200) {
- if (body != nullptr) {
- jbyte* bodyData = env->GetByteArrayElements(body, nullptr);
- response->data = std::make_shared<std::string>(reinterpret_cast<char*>(bodyData), env->GetArrayLength(body));
- env->ReleaseByteArrayElements(body, bodyData, JNI_ABORT);
+ if (body) {
+ auto data = std::make_shared<std::string>(body.Length(env), char());
+ jni::GetArrayRegion(env, *body, 0, data->size(), reinterpret_cast<jbyte*>(&(*data)[0]));
+ response->data = data;
} else {
response->data = std::make_shared<std::string>();
}
@@ -222,8 +160,8 @@ void HTTPAndroidRequest::onResponse(JNIEnv* env, int code, jstring /* message */
async.send();
}
-void HTTPAndroidRequest::onFailure(JNIEnv* env, int type, jstring message) {
- std::string messageStr = mbgl::android::std_string_from_jstring(env, message);
+void HTTPRequest::onFailure(jni::JNIEnv& env, int type, jni::String message) {
+ std::string messageStr = jni::Make<std::string>(env, message);
response = std::make_unique<Response>();
using Error = Response::Error;
@@ -245,24 +183,14 @@ void HTTPAndroidRequest::onFailure(JNIEnv* env, int type, jstring message) {
async.send();
}
+} // namespace android
+
std::unique_ptr<HTTPContextBase> HTTPContextBase::createContext() {
- return std::make_unique<HTTPAndroidContext>();
+ return std::make_unique<android::HTTPContext>();
}
uint32_t HTTPContextBase::maximumConcurrentRequests() {
return 20;
}
-void JNICALL nativeOnFailure(JNIEnv* env, jobject, jlong nativePtr, jint type, jstring message) {
- mbgl::Log::Debug(mbgl::Event::JNI, "nativeOnFailure");
- assert(nativePtr != 0);
- return reinterpret_cast<HTTPAndroidRequest*>(nativePtr)->onFailure(env, type, message);
-}
-
-void JNICALL nativeOnResponse(JNIEnv* env, jobject, 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);
- return reinterpret_cast<HTTPAndroidRequest*>(nativePtr)->onResponse(env, code, message, etag, modified, cacheControl, expires, body);
-}
-
-}
+} // namespace mbgl
diff --git a/platform/android/src/jni.cpp b/platform/android/src/jni.cpp
index 69c0740b45..d57671ff9e 100755
--- a/platform/android/src/jni.cpp
+++ b/platform/android/src/jni.cpp
@@ -8,8 +8,6 @@
#include <array>
#include <vector>
-#include <jni.h>
-
#include <android/native_window_jni.h>
#include <sys/system_properties.h>
@@ -32,6 +30,8 @@
namespace mbgl {
namespace android {
+void RegisterNativeHTTPRequest(JNIEnv&);
+
JavaVM* theJVM;
std::string cachePath;
@@ -101,14 +101,6 @@ jfieldID rectFTopId = nullptr;
jfieldID rectFRightId = nullptr;
jfieldID rectFBottomId = nullptr;
-jclass httpContextClass = nullptr;
-jmethodID httpContextGetInstanceId = nullptr;
-jmethodID httpContextCreateRequestId = nullptr;
-
-jclass httpRequestClass = nullptr;
-jmethodID httpRequestStartId = nullptr;
-jmethodID httpRequestCancelId = nullptr;
-
jclass customLayerClass = nullptr;
jfieldID customLayerIdId = nullptr;
jfieldID customLayerContextId = nullptr;
@@ -2181,6 +2173,8 @@ extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
return JNI_ERR;
}
+ mbgl::android::RegisterNativeHTTPRequest(*env);
+
latLngClass = env->FindClass("com/mapbox/mapboxsdk/geometry/LatLng");
if (latLngClass == nullptr) {
env->ExceptionDescribe();
@@ -2487,42 +2481,6 @@ extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
return JNI_ERR;
}
- httpContextClass = env->FindClass("com/mapbox/mapboxsdk/http/HTTPContext");
- if (httpContextClass == nullptr) {
- env->ExceptionDescribe();
- return JNI_ERR;
- }
-
- httpContextGetInstanceId = env->GetStaticMethodID(httpContextClass, "getInstance", "()Lcom/mapbox/mapboxsdk/http/HTTPContext;");
- if (httpContextGetInstanceId == nullptr) {
- env->ExceptionDescribe();
- return JNI_ERR;
- }
-
- httpContextCreateRequestId = env->GetMethodID(httpContextClass, "createRequest", "(JLjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Lcom/mapbox/mapboxsdk/http/HTTPContext$HTTPRequest;");
- if (httpContextCreateRequestId == nullptr) {
- env->ExceptionDescribe();
- return JNI_ERR;
- }
-
- httpRequestClass = env->FindClass("com/mapbox/mapboxsdk/http/HTTPContext$HTTPRequest");
- if (httpRequestClass == nullptr) {
- env->ExceptionDescribe();
- return JNI_ERR;
- }
-
- httpRequestStartId = env->GetMethodID(httpRequestClass, "start", "()V");
- if (httpRequestStartId == nullptr) {
- env->ExceptionDescribe();
- return JNI_ERR;
- }
-
- httpRequestCancelId = env->GetMethodID(httpRequestClass, "cancel", "()V");
- if (httpRequestCancelId == nullptr) {
- env->ExceptionDescribe();
- return JNI_ERR;
- }
-
customLayerClass = env->FindClass("com/mapbox/mapboxsdk/layers/CustomLayer");
if (customLayerClass == nullptr) {
env->ExceptionDescribe();
@@ -3129,41 +3087,6 @@ 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(latLngBoundsClass);
- env->DeleteGlobalRef(iconClass);
- env->DeleteGlobalRef(markerClass);
- env->DeleteGlobalRef(polylineClass);
- env->DeleteGlobalRef(polygonClass);
- env->DeleteGlobalRef(runtimeExceptionClass);
- env->DeleteGlobalRef(nullPointerExceptionClass);
- env->DeleteGlobalRef(arrayListClass);
- env->DeleteGlobalRef(projectedMetersClass);
- env->DeleteGlobalRef(pointFClass);
- env->DeleteGlobalRef(rectFClass);
- }
-
- httpRequestClass = reinterpret_cast<jclass>(env->NewGlobalRef(httpRequestClass));
- if (httpRequestClass == nullptr) {
- env->ExceptionDescribe();
- env->DeleteGlobalRef(latLngClass);
- env->DeleteGlobalRef(latLngBoundsClass);
- env->DeleteGlobalRef(iconClass);
- env->DeleteGlobalRef(markerClass);
- env->DeleteGlobalRef(polylineClass);
- env->DeleteGlobalRef(polygonClass);
- env->DeleteGlobalRef(runtimeExceptionClass);
- env->DeleteGlobalRef(nullPointerExceptionClass);
- env->DeleteGlobalRef(arrayListClass);
- env->DeleteGlobalRef(projectedMetersClass);
- env->DeleteGlobalRef(pointFClass);
- env->DeleteGlobalRef(rectFClass);
- env->DeleteGlobalRef(httpContextClass);
- }
-
// Offline global definitions begin
offlineManagerClass = reinterpret_cast<jclass>(env->NewGlobalRef(offlineManagerClass));
@@ -3181,8 +3104,6 @@ extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
env->DeleteGlobalRef(projectedMetersClass);
env->DeleteGlobalRef(pointFClass);
env->DeleteGlobalRef(rectFClass);
- env->DeleteGlobalRef(httpContextClass);
- env->DeleteGlobalRef(httpRequestClass);
}
listOfflineRegionsCallbackClass = reinterpret_cast<jclass>(env->NewGlobalRef(listOfflineRegionsCallbackClass));
@@ -3200,8 +3121,6 @@ extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
env->DeleteGlobalRef(projectedMetersClass);
env->DeleteGlobalRef(pointFClass);
env->DeleteGlobalRef(rectFClass);
- env->DeleteGlobalRef(httpContextClass);
- env->DeleteGlobalRef(offlineManagerClass);
}
offlineRegionClass = reinterpret_cast<jclass>(env->NewGlobalRef(offlineRegionClass));
@@ -3219,8 +3138,6 @@ extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
env->DeleteGlobalRef(projectedMetersClass);
env->DeleteGlobalRef(pointFClass);
env->DeleteGlobalRef(rectFClass);
- env->DeleteGlobalRef(httpContextClass);
- env->DeleteGlobalRef(offlineManagerClass);
env->DeleteGlobalRef(listOfflineRegionsCallbackClass);
}
@@ -3239,7 +3156,6 @@ extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
env->DeleteGlobalRef(projectedMetersClass);
env->DeleteGlobalRef(pointFClass);
env->DeleteGlobalRef(rectFClass);
- env->DeleteGlobalRef(httpContextClass);
env->DeleteGlobalRef(offlineManagerClass);
env->DeleteGlobalRef(listOfflineRegionsCallbackClass);
env->DeleteGlobalRef(offlineRegionClass);
@@ -3260,7 +3176,6 @@ extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
env->DeleteGlobalRef(projectedMetersClass);
env->DeleteGlobalRef(pointFClass);
env->DeleteGlobalRef(rectFClass);
- env->DeleteGlobalRef(httpContextClass);
env->DeleteGlobalRef(offlineManagerClass);
env->DeleteGlobalRef(listOfflineRegionsCallbackClass);
env->DeleteGlobalRef(offlineRegionClass);
@@ -3282,7 +3197,6 @@ extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
env->DeleteGlobalRef(projectedMetersClass);
env->DeleteGlobalRef(pointFClass);
env->DeleteGlobalRef(rectFClass);
- env->DeleteGlobalRef(httpContextClass);
env->DeleteGlobalRef(offlineManagerClass);
env->DeleteGlobalRef(listOfflineRegionsCallbackClass);
env->DeleteGlobalRef(offlineRegionClass);
@@ -3305,7 +3219,6 @@ extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
env->DeleteGlobalRef(projectedMetersClass);
env->DeleteGlobalRef(pointFClass);
env->DeleteGlobalRef(rectFClass);
- env->DeleteGlobalRef(httpContextClass);
env->DeleteGlobalRef(offlineManagerClass);
env->DeleteGlobalRef(listOfflineRegionsCallbackClass);
env->DeleteGlobalRef(offlineRegionClass);
@@ -3329,7 +3242,6 @@ extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
env->DeleteGlobalRef(projectedMetersClass);
env->DeleteGlobalRef(pointFClass);
env->DeleteGlobalRef(rectFClass);
- env->DeleteGlobalRef(httpContextClass);
env->DeleteGlobalRef(offlineManagerClass);
env->DeleteGlobalRef(listOfflineRegionsCallbackClass);
env->DeleteGlobalRef(offlineRegionClass);
@@ -3354,7 +3266,6 @@ extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
env->DeleteGlobalRef(projectedMetersClass);
env->DeleteGlobalRef(pointFClass);
env->DeleteGlobalRef(rectFClass);
- env->DeleteGlobalRef(httpContextClass);
env->DeleteGlobalRef(offlineManagerClass);
env->DeleteGlobalRef(listOfflineRegionsCallbackClass);
env->DeleteGlobalRef(offlineRegionClass);
@@ -3380,7 +3291,6 @@ extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
env->DeleteGlobalRef(projectedMetersClass);
env->DeleteGlobalRef(pointFClass);
env->DeleteGlobalRef(rectFClass);
- env->DeleteGlobalRef(httpContextClass);
env->DeleteGlobalRef(offlineManagerClass);
env->DeleteGlobalRef(listOfflineRegionsCallbackClass);
env->DeleteGlobalRef(offlineRegionClass);
@@ -3488,14 +3398,6 @@ extern "C" JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *vm, void *reserved) {
rectFRightId = nullptr;
rectFBottomId = nullptr;
- env->DeleteGlobalRef(httpContextClass);
- httpContextGetInstanceId = nullptr;
- httpContextCreateRequestId = nullptr;
-
- env->DeleteGlobalRef(httpRequestClass);
- httpRequestStartId = nullptr;
- httpRequestCancelId = nullptr;
-
// Offline delete begins
env->DeleteGlobalRef(offlineManagerClass);
diff --git a/platform/android/src/jni.hpp b/platform/android/src/jni.hpp
index 6a3c248373..151ad683e0 100644
--- a/platform/android/src/jni.hpp
+++ b/platform/android/src/jni.hpp
@@ -95,14 +95,6 @@ extern jfieldID rectFTopId;
extern jfieldID rectFRightId;
extern jfieldID rectFBottomId;
-extern jclass httpContextClass;
-extern jmethodID httpContextGetInstanceId;
-extern jmethodID httpContextCreateRequestId;
-
-extern jclass httpRequestClass;
-extern jmethodID httpRequestStartId;
-extern jmethodID httpRequestCancelId;
-
// Offline declarations start
extern jclass offlineManagerClass;