[android] Use jni.hpp in http_request_android.cpp
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -22,6 +22,7 @@
|
||||
'sources': [
|
||||
'./src/native_map_view.cpp',
|
||||
'./src/jni.cpp',
|
||||
'./src/attach_env.cpp',
|
||||
],
|
||||
|
||||
'cflags_cc': [
|
||||
|
||||
22
platform/android/src/attach_env.cpp
Normal file
22
platform/android/src/attach_env.cpp
Normal file
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
31
platform/android/src/attach_env.hpp
Normal file
31
platform/android/src/attach_env.hpp
Normal file
@@ -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();
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
jni::Class<HTTPRequest> HTTPRequest::javaClass;
|
||||
|
||||
void RegisterNativeHTTPRequest(jni::JNIEnv& env) {
|
||||
HTTPRequest::javaClass = *jni::Class<HTTPRequest>::Find(env).NewGlobalRef(env).release();
|
||||
|
||||
#define METHOD(MethodPtr, name) jni::MakeNativePeerMethod<decltype(MethodPtr), (MethodPtr)>(name)
|
||||
|
||||
jni::RegisterNativePeer<HTTPRequest>(env, HTTPRequest::javaClass, "mNativePtr",
|
||||
METHOD(&HTTPRequest::onFailure, "nativeOnFailure"),
|
||||
METHOD(&HTTPRequest::onResponse, "nativeOnResponse"));
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
|
||||
HTTPAndroidContext::HTTPAndroidContext()
|
||||
: 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);
|
||||
HTTPRequestBase* HTTPContext::createRequest(const Resource& resource, HTTPRequestBase::Callback callback) {
|
||||
return new HTTPRequest(*env, resource, callback);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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()");
|
||||
jni::UniqueLocalFrame frame = jni::PushLocalFrame(env, 10);
|
||||
|
||||
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();
|
||||
}
|
||||
static auto constructor =
|
||||
javaClass.GetConstructor<jni::jlong, jni::String, jni::String, jni::String, jni::String>(env);
|
||||
|
||||
obj = env->NewGlobalRef(obj);
|
||||
if (obj == nullptr) {
|
||||
env->ExceptionDescribe();
|
||||
}
|
||||
|
||||
env->CallVoidMethod(obj, mbgl::android::httpRequestStartId);
|
||||
if (env->ExceptionCheck()) {
|
||||
env->ExceptionDescribe();
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user