From dbffe1dfabea5c6e71ac9f61d6dc45cfa5458775 Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Thu, 3 Mar 2016 15:41:56 -0800 Subject: [PATCH] [android] Use jni.hpp low-level wrappers --- .../mapbox/mapboxsdk/maps/NativeMapView.java | 6 +- platform/android/src/jni.cpp | 2762 +++++------------ 2 files changed, 718 insertions(+), 2050 deletions(-) diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java index 7948097ec77..20b881cbe63 100755 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java @@ -360,7 +360,7 @@ public void setBearing(double degrees, long duration) { } public void setBearing(double degrees, double cx, double cy) { - nativeSetBearing(mNativeMapViewPtr, degrees, cx, cy); + nativeSetBearingXY(mNativeMapViewPtr, degrees, cx, cy); } public double getBearing() { @@ -618,8 +618,8 @@ private native void nativeRotateBy(long nativeMapViewPtr, double sx, private native void nativeSetBearing(long nativeMapViewPtr, double degrees, long duration); - private native void nativeSetBearing(long nativeMapViewPtr, double degrees, - double cx, double cy); + private native void nativeSetBearingXY(long nativeMapViewPtr, double degrees, + double cx, double cy); private native double nativeGetBearing(long nativeMapViewPtr); diff --git a/platform/android/src/jni.cpp b/platform/android/src/jni.cpp index c929a1d42b2..f90422ecdd9 100755 --- a/platform/android/src/jni.cpp +++ b/platform/android/src/jni.cpp @@ -1,10 +1,7 @@ #include #include #include - #include -#include -#include #include #include @@ -41,141 +38,123 @@ std::string dataPath; std::string apkPath; std::string androidRelease; -jmethodID onInvalidateId = nullptr; -jmethodID onMapChangedId = nullptr; -jmethodID onFpsChangedId = nullptr; - -jclass latLngClass = nullptr; -jmethodID latLngConstructorId = nullptr; -jfieldID latLngLatitudeId = nullptr; -jfieldID latLngLongitudeId = nullptr; - -jclass latLngBoundsClass = nullptr; -jmethodID latLngBoundsConstructorId = nullptr; -jfieldID latLngBoundsLatNorthId = nullptr; -jfieldID latLngBoundsLatSouthId = nullptr; -jfieldID latLngBoundsLonEastId = nullptr; -jfieldID latLngBoundsLonWestId = nullptr; - -jclass iconClass = nullptr; -jfieldID iconIdId = nullptr; - -jclass markerClass = nullptr; -jfieldID markerPositionId = nullptr; -jfieldID markerIconId = nullptr; -jfieldID markerIdId = nullptr; - -jclass polylineClass = nullptr; -jfieldID polylineAlphaId = nullptr; -jfieldID polylineColorId = nullptr; -jfieldID polylineWidthId = nullptr; -jfieldID polylinePointsId = nullptr; - -jclass polygonClass = nullptr; -jfieldID polygonAlphaId = nullptr; -jfieldID polygonFillColorId = nullptr; -jfieldID polygonStrokeColorId = nullptr; -jfieldID polygonPointsId = nullptr; - -jclass runtimeExceptionClass = nullptr; -jclass nullPointerExceptionClass = nullptr; - -jmethodID listToArrayId = nullptr; - -jclass arrayListClass = nullptr; -jmethodID arrayListConstructorId = nullptr; -jmethodID arrayListAddId = nullptr; - -jclass projectedMetersClass = nullptr; -jmethodID projectedMetersConstructorId = nullptr; -jfieldID projectedMetersNorthingId = nullptr; -jfieldID projectedMetersEastingId = nullptr; - -jclass pointFClass = nullptr; -jmethodID pointFConstructorId = nullptr; -jfieldID pointFXId = nullptr; -jfieldID pointFYId = nullptr; - -jclass rectFClass = nullptr; -jmethodID rectFConstructorId = nullptr; -jfieldID rectFLeftId = nullptr; -jfieldID rectFTopId = nullptr; -jfieldID rectFRightId = nullptr; -jfieldID rectFBottomId = nullptr; - -jclass customLayerClass = nullptr; -jfieldID customLayerIdId = nullptr; -jfieldID customLayerContextId = nullptr; -jfieldID customLayerInitializeFunctionId = nullptr; -jfieldID customLayerRenderFunctionId = nullptr; -jfieldID customLayerDeinitializeFunctionId = nullptr; +jni::jmethodID* onInvalidateId = nullptr; +jni::jmethodID* onMapChangedId = nullptr; +jni::jmethodID* onFpsChangedId = nullptr; + +jni::jclass* latLngClass = nullptr; +jni::jmethodID* latLngConstructorId = nullptr; +jni::jfieldID* latLngLatitudeId = nullptr; +jni::jfieldID* latLngLongitudeId = nullptr; + +jni::jclass* latLngBoundsClass = nullptr; +jni::jmethodID* latLngBoundsConstructorId = nullptr; +jni::jfieldID* latLngBoundsLatNorthId = nullptr; +jni::jfieldID* latLngBoundsLatSouthId = nullptr; +jni::jfieldID* latLngBoundsLonEastId = nullptr; +jni::jfieldID* latLngBoundsLonWestId = nullptr; + +jni::jclass* iconClass = nullptr; +jni::jfieldID* iconIdId = nullptr; + +jni::jclass* markerClass = nullptr; +jni::jfieldID* markerPositionId = nullptr; +jni::jfieldID* markerIconId = nullptr; +jni::jfieldID* markerIdId = nullptr; + +jni::jclass* polylineClass = nullptr; +jni::jfieldID* polylineAlphaId = nullptr; +jni::jfieldID* polylineColorId = nullptr; +jni::jfieldID* polylineWidthId = nullptr; +jni::jfieldID* polylinePointsId = nullptr; + +jni::jclass* polygonClass = nullptr; +jni::jfieldID* polygonAlphaId = nullptr; +jni::jfieldID* polygonFillColorId = nullptr; +jni::jfieldID* polygonStrokeColorId = nullptr; +jni::jfieldID* polygonPointsId = nullptr; + +jni::jmethodID* listToArrayId = nullptr; + +jni::jclass* arrayListClass = nullptr; +jni::jmethodID* arrayListConstructorId = nullptr; +jni::jmethodID* arrayListAddId = nullptr; + +jni::jclass* projectedMetersClass = nullptr; +jni::jmethodID* projectedMetersConstructorId = nullptr; +jni::jfieldID* projectedMetersNorthingId = nullptr; +jni::jfieldID* projectedMetersEastingId = nullptr; + +jni::jclass* pointFClass = nullptr; +jni::jmethodID* pointFConstructorId = nullptr; +jni::jfieldID* pointFXId = nullptr; +jni::jfieldID* pointFYId = nullptr; + +jni::jclass* rectFClass = nullptr; +jni::jmethodID* rectFConstructorId = nullptr; +jni::jfieldID* rectFLeftId = nullptr; +jni::jfieldID* rectFTopId = nullptr; +jni::jfieldID* rectFRightId = nullptr; +jni::jfieldID* rectFBottomId = nullptr; + +jni::jclass* customLayerClass = nullptr; +jni::jfieldID* customLayerIdId = nullptr; +jni::jfieldID* customLayerContextId = nullptr; +jni::jfieldID* customLayerInitializeFunctionId = nullptr; +jni::jfieldID* customLayerRenderFunctionId = nullptr; +jni::jfieldID* customLayerDeinitializeFunctionId = nullptr; // Offline declarations start -jclass offlineManagerClass = nullptr; -jfieldID offlineManagerClassPtrId = nullptr; - -jclass listOfflineRegionsCallbackClass = nullptr; -jmethodID listOnListMethodId = nullptr; -jmethodID listOnErrorMethodId = nullptr; - -jclass offlineRegionClass = nullptr; -jmethodID offlineRegionConstructorId = nullptr; -jfieldID offlineRegionOfflineManagerId = nullptr; -jfieldID offlineRegionIdId = nullptr; -jfieldID offlineRegionDefinitionId = nullptr; -jfieldID offlineRegionMetadataId = nullptr; -jfieldID offlineRegionPtrId = nullptr; - -jclass offlineRegionDefinitionClass = nullptr; -jmethodID offlineRegionDefinitionConstructorId = nullptr; -jfieldID offlineRegionDefinitionStyleURLId = nullptr; -jfieldID offlineRegionDefinitionBoundsId = nullptr; -jfieldID offlineRegionDefinitionMinZoomId = nullptr; -jfieldID offlineRegionDefinitionMaxZoomId = nullptr; -jfieldID offlineRegionDefinitionPixelRatioId = nullptr; - -jclass createOfflineRegionCallbackClass = nullptr; -jmethodID createOnCreateMethodId = nullptr; -jmethodID createOnErrorMethodId = nullptr; - -jclass offlineRegionObserverClass = nullptr; -jmethodID offlineRegionObserveronStatusChangedId = nullptr; -jmethodID offlineRegionObserveronErrorId = nullptr; -jmethodID offlineRegionObserveronLimitId = nullptr; - -jclass offlineRegionStatusClass = nullptr; -jmethodID offlineRegionStatusConstructorId = nullptr; -jfieldID offlineRegionStatusDownloadStateId = nullptr; -jfieldID offlineRegionStatusCompletedResourceCountId = nullptr; -jfieldID offlineRegionStatusCompletedResourceSizeId = nullptr; -jfieldID offlineRegionStatusRequiredResourceCountId = nullptr; -jfieldID offlineRegionStatusRequiredResourceCountIsPreciseId = nullptr; - -jclass offlineRegionErrorClass = nullptr; -jmethodID offlineRegionErrorConstructorId = nullptr; -jfieldID offlineRegionErrorReasonId = nullptr; -jfieldID offlineRegionErrorMessageId = nullptr; - -jclass offlineRegionStatusCallbackClass = nullptr; -jmethodID offlineRegionStatusOnStatusId = nullptr; -jmethodID offlineRegionStatusOnErrorId = nullptr; - -jclass offlineRegionDeleteCallbackClass = nullptr; -jmethodID offlineRegionDeleteOnDeleteId = nullptr; -jmethodID offlineRegionDeleteOnErrorId = nullptr; +jni::jfieldID* offlineManagerClassPtrId = nullptr; + +jni::jmethodID* listOnListMethodId = nullptr; +jni::jmethodID* listOnErrorMethodId = nullptr; + +jni::jclass* offlineRegionClass = nullptr; +jni::jmethodID* offlineRegionConstructorId = nullptr; +jni::jfieldID* offlineRegionOfflineManagerId = nullptr; +jni::jfieldID* offlineRegionIdId = nullptr; +jni::jfieldID* offlineRegionDefinitionId = nullptr; +jni::jfieldID* offlineRegionMetadataId = nullptr; +jni::jfieldID* offlineRegionPtrId = nullptr; + +jni::jclass* offlineRegionDefinitionClass = nullptr; +jni::jmethodID* offlineRegionDefinitionConstructorId = nullptr; +jni::jfieldID* offlineRegionDefinitionStyleURLId = nullptr; +jni::jfieldID* offlineRegionDefinitionBoundsId = nullptr; +jni::jfieldID* offlineRegionDefinitionMinZoomId = nullptr; +jni::jfieldID* offlineRegionDefinitionMaxZoomId = nullptr; +jni::jfieldID* offlineRegionDefinitionPixelRatioId = nullptr; + +jni::jmethodID* createOnCreateMethodId = nullptr; +jni::jmethodID* createOnErrorMethodId = nullptr; + +jni::jmethodID* offlineRegionObserveronStatusChangedId = nullptr; +jni::jmethodID* offlineRegionObserveronErrorId = nullptr; +jni::jmethodID* offlineRegionObserveronLimitId = nullptr; + +jni::jclass* offlineRegionStatusClass = nullptr; +jni::jmethodID* offlineRegionStatusConstructorId = nullptr; +jni::jfieldID* offlineRegionStatusDownloadStateId = nullptr; +jni::jfieldID* offlineRegionStatusCompletedResourceCountId = nullptr; +jni::jfieldID* offlineRegionStatusCompletedResourceSizeId = nullptr; +jni::jfieldID* offlineRegionStatusRequiredResourceCountId = nullptr; +jni::jfieldID* offlineRegionStatusRequiredResourceCountIsPreciseId = nullptr; + +jni::jclass* offlineRegionErrorClass = nullptr; +jni::jmethodID* offlineRegionErrorConstructorId = nullptr; +jni::jfieldID* offlineRegionErrorReasonId = nullptr; +jni::jfieldID* offlineRegionErrorMessageId = nullptr; + +jni::jmethodID* offlineRegionStatusOnStatusId = nullptr; +jni::jmethodID* offlineRegionStatusOnErrorId = nullptr; + +jni::jmethodID* offlineRegionDeleteOnDeleteId = nullptr; +jni::jmethodID* offlineRegionDeleteOnErrorId = nullptr; // Offline declarations end -bool throw_jni_error(JNIEnv *env, const char *msg) { - if (env->ThrowNew(runtimeExceptionClass, msg) < 0) { - env->ExceptionDescribe(); - return false; - } - - return true; -} - bool attach_jni_thread(JavaVM* vm, JNIEnv** env, std::string threadName) { assert(vm != nullptr); assert(env != nullptr); @@ -217,189 +196,88 @@ void detach_jni_thread(JavaVM* vm, JNIEnv** env, bool detach) { *env = nullptr; } -std::string std_string_from_jstring(JNIEnv *env, jstring jstr) { - std::string str; - - if (jstr == nullptr) { - if (env->ThrowNew(nullPointerExceptionClass, "String cannot be null.") < 0) { - env->ExceptionDescribe(); - return str; - } - - return str; - } - - jsize len = env->GetStringLength(jstr); - if (len < 0) { - env->ExceptionDescribe(); - return str; - } - - const jchar *chars = env->GetStringChars(jstr, nullptr); - if (chars == nullptr) { - env->ExceptionDescribe(); - return str; - } - - std::u16string ustr(reinterpret_cast(chars), len); - env->ReleaseStringChars(jstr, chars); - chars = nullptr; - str = std::wstring_convert, char16_t>().to_bytes(ustr); - return str; +std::string std_string_from_jstring(JNIEnv *env, jni::jstring* jstr) { + return jni::Make(*env, jni::String(jstr)); } -jstring std_string_to_jstring(JNIEnv *env, std::string str) { - std::u16string ustr = - std::wstring_convert, char16_t>().from_bytes(str); - - jstring jstr = env->NewString(reinterpret_cast(ustr.c_str()), ustr.size()); - if (jstr == nullptr) { - env->ExceptionDescribe(); - return nullptr; - } - - return jstr; +jni::jstring* std_string_to_jstring(JNIEnv *env, std::string str) { + return jni::Make(*env, str).Get(); } -std::vector std_vector_string_from_jobject(JNIEnv *env, jobject jlist) { +std::vector std_vector_string_from_jobject(JNIEnv *env, jni::jobject* jlist) { std::vector vector; - if (jlist == nullptr) { - if (env->ThrowNew(nullPointerExceptionClass, "List cannot be null.") < 0) { - env->ExceptionDescribe(); - return vector; - } - - return vector; - } + jni::NullCheck(*env, jlist); + jni::jarray* jarray = + reinterpret_cast*>(jni::CallMethod(*env, jlist, *listToArrayId)); - jobjectArray jarray = - reinterpret_cast(env->CallObjectMethod(jlist, listToArrayId)); - if (env->ExceptionCheck() || (jarray == nullptr)) { - env->ExceptionDescribe(); - return vector; - } - - jsize len = env->GetArrayLength(jarray); - if (len < 0) { - env->ExceptionDescribe(); - return vector; - } - - for (jsize i = 0; i < len; i++) { - jstring jstr = reinterpret_cast(env->GetObjectArrayElement(jarray, i)); - if (jstr == nullptr) { - env->ExceptionDescribe(); - return vector; - } + jni::NullCheck(*env, jarray); + std::size_t len = jni::GetArrayLength(*env, *jarray); + for (std::size_t i = 0; i < len; i++) { + jni::jstring* jstr = reinterpret_cast(jni::GetObjectArrayElement(*env, *jarray, i)); vector.push_back(std_string_from_jstring(env, jstr)); } - env->DeleteLocalRef(jarray); - jarray = nullptr; - return vector; } -jobject std_vector_string_to_jobject(JNIEnv *env, std::vector vector) { - jobject jlist = env->NewObject(arrayListClass, arrayListConstructorId); - if (jlist == nullptr) { - env->ExceptionDescribe(); - return nullptr; - } +jni::jobject* std_vector_string_to_jobject(JNIEnv *env, std::vector vector) { + jni::jobject* jlist = &jni::NewObject(*env, *arrayListClass, *arrayListConstructorId); for (const auto& str : vector) { - env->CallBooleanMethod(jlist, arrayListAddId, std_string_to_jstring(env, str)); - if (env->ExceptionCheck()) { - env->ExceptionDescribe(); - return nullptr; - } + jni::CallMethod(*env, jlist, *arrayListAddId, std_string_to_jstring(env, str)); } return jlist; } -jlongArray std_vector_uint_to_jobject(JNIEnv *env, std::vector vector) { - jlongArray jarray = env->NewLongArray(vector.size()); - if (jarray == nullptr) { - env->ExceptionDescribe(); - return nullptr; - } +jni::jarray* std_vector_uint_to_jobject(JNIEnv *env, std::vector vector) { + jni::jarray& jarray = jni::NewArray(*env, vector.size()); std::vector v; for (const uint32_t& id : vector) { - v.push_back((jlong)id); + v.push_back(id); } - env->SetLongArrayRegion(jarray, 0, v.size(), &(v[0])); - if (env->ExceptionCheck()) { - env->ExceptionDescribe(); - return nullptr; - } + jni::SetArrayRegion(*env, jarray, 0, v); - return jarray; + return &jarray; } -mbgl::AnnotationSegment annotation_segment_from_latlng_jlist(JNIEnv *env, jobject jlist) { +mbgl::AnnotationSegment annotation_segment_from_latlng_jlist(JNIEnv *env, jni::jobject* jlist) { mbgl::AnnotationSegment segment; - if (jlist == nullptr) { - if (env->ThrowNew(nullPointerExceptionClass, "List cannot be null.") < 0) { - env->ExceptionDescribe(); - return segment; - } - return segment; - } + NullCheck(*env, jlist); + jni::jarray* jarray = + reinterpret_cast*>(jni::CallMethod(*env, jlist, *listToArrayId)); - jobjectArray jarray = - reinterpret_cast(env->CallObjectMethod(jlist, listToArrayId)); - if (env->ExceptionCheck() || (jarray == nullptr)) { - env->ExceptionDescribe(); - return segment; - } - - jsize len = env->GetArrayLength(jarray); - if (len < 0) { - env->ExceptionDescribe(); - return segment; - } + NullCheck(*env, jarray); + std::size_t len = jni::GetArrayLength(*env, *jarray); segment.reserve(len); - for (jsize i = 0; i < len; i++) { - jobject latLng = reinterpret_cast(env->GetObjectArrayElement(jarray, i)); - if (latLng == nullptr) { - env->ExceptionDescribe(); - return segment; - } + for (std::size_t i = 0; i < len; i++) { + jni::jobject* latLng = reinterpret_cast(jni::GetObjectArrayElement(*env, *jarray, i)); + NullCheck(*env, latLng); - jdouble latitude = env->GetDoubleField(latLng, latLngLatitudeId); - if (env->ExceptionCheck()) { - env->ExceptionDescribe(); - return segment; - } - - jdouble longitude = env->GetDoubleField(latLng, latLngLongitudeId); - if (env->ExceptionCheck()) { - env->ExceptionDescribe(); - return segment; - } + jdouble latitude = jni::GetField(*env, latLng, *latLngLatitudeId); + jdouble longitude = jni::GetField(*env, latLng, *latLngLongitudeId); segment.push_back(mbgl::LatLng(latitude, longitude)); - env->DeleteLocalRef(latLng); + jni::DeleteLocalRef(*env, latLng); } - env->DeleteLocalRef(jarray); + jni::DeleteLocalRef(*env, jarray); jarray = nullptr; return segment; } -std::pair annotation_std_pair_from_polygon_jobject(JNIEnv *env, jobject polygon) { - jfloat alpha = env->GetFloatField(polygon, polygonAlphaId); - jint fillColor = env->GetIntField(polygon, polygonFillColorId); - jint strokeColor = env->GetIntField(polygon, polygonStrokeColorId); +std::pair annotation_std_pair_from_polygon_jobject(JNIEnv *env, jni::jobject* polygon) { + jfloat alpha = jni::GetField(*env, polygon, *polygonAlphaId); + jint fillColor = jni::GetField(*env, polygon, *polygonFillColorId); + jint strokeColor = jni::GetField(*env, polygon, *polygonStrokeColorId); int rF = (fillColor >> 16) & 0xFF; int gF = (fillColor >> 8) & 0xFF; @@ -418,73 +296,45 @@ std::pair annotation fillProperties.color = {{ static_cast(rF) / 255.0f, static_cast(gF) / 255.0f, static_cast(bF) / 255.0f, static_cast(aF) / 255.0f }}; shapeProperties.set(fillProperties); - jobject points = env->GetObjectField(polygon, polygonPointsId); + jni::jobject* points = jni::GetField(*env, polygon, *polygonPointsId); mbgl::AnnotationSegment segment = annotation_segment_from_latlng_jlist(env, points); - env->DeleteLocalRef(points); + jni::DeleteLocalRef(*env, points); return std::make_pair(segment, shapeProperties); } -static std::vector metadata_from_java(JNIEnv* env, jbyteArray j) { +static std::vector metadata_from_java(JNIEnv* env, jni::jarray& j) { mbgl::Log::Debug(mbgl::Event::JNI, "metadata_from_java"); - jsize length = env->GetArrayLength(j); + std::size_t length = jni::GetArrayLength(*env, j); std::vector c; c.resize(length); - env->GetByteArrayRegion(j, 0, length, reinterpret_cast(c.data())); + jni::GetArrayRegion(*env, j, 0, length, reinterpret_cast(c.data())); return c; } -static jbyteArray metadata_from_native(JNIEnv* env, const std::vector& c) { +static jni::jarray* metadata_from_native(JNIEnv* env, const std::vector& c) { mbgl::Log::Debug(mbgl::Event::JNI, "metadata_from_java"); - jsize length = static_cast(c.size()); - jbyteArray j = env->NewByteArray(length); - env->SetByteArrayRegion(j, 0, c.size(), reinterpret_cast(c.data())); - return j; + std::size_t length = static_cast(c.size()); + jni::jarray& j = jni::NewArray(*env, length); + jni::SetArrayRegion(*env, j, 0, c.size(), reinterpret_cast(c.data())); + return &j; } -static mbgl::LatLngBounds latlngbounds_from_java(JNIEnv *env, jobject latLngBounds) { - // Checks - if (env->ExceptionCheck() || (latLngBounds == nullptr)) { - env->ExceptionDescribe(); - return mbgl::LatLngBounds::empty(); - } - - jdouble swLat = env->GetDoubleField(latLngBounds, latLngBoundsLatSouthId); - if (env->ExceptionCheck()) { - env->ExceptionDescribe(); - return mbgl::LatLngBounds::empty(); - } - - jdouble swLon = env->GetDoubleField(latLngBounds, latLngBoundsLonWestId); - if (env->ExceptionCheck()) { - env->ExceptionDescribe(); - return mbgl::LatLngBounds::empty(); - } - - jdouble neLat = env->GetDoubleField(latLngBounds, latLngBoundsLatNorthId); - if (env->ExceptionCheck()) { - env->ExceptionDescribe(); - return mbgl::LatLngBounds::empty(); - } - - jdouble neLon = env->GetDoubleField(latLngBounds, latLngBoundsLonEastId); - if (env->ExceptionCheck()) { - env->ExceptionDescribe(); - return mbgl::LatLngBounds::empty(); - } - - // Build object - mbgl::LatLngBounds result = mbgl::LatLngBounds::hull({ swLat, swLon }, { neLat, neLon }); - return result; +static mbgl::LatLngBounds latlngbounds_from_java(JNIEnv *env, jni::jobject* latLngBounds) { + jdouble swLat = jni::GetField(*env, latLngBounds, *latLngBoundsLatSouthId); + jdouble swLon = jni::GetField(*env, latLngBounds, *latLngBoundsLonWestId); + jdouble neLat = jni::GetField(*env, latLngBounds, *latLngBoundsLatNorthId); + jdouble neLon = jni::GetField(*env, latLngBounds, *latLngBoundsLonEastId); + return mbgl::LatLngBounds::hull({ swLat, swLon }, { neLat, neLon }); } -static jobject latlngbounds_from_native(JNIEnv *env, mbgl::LatLngBounds bounds) { +static jni::jobject* latlngbounds_from_native(JNIEnv *env, mbgl::LatLngBounds bounds) { double northLatitude = bounds.north(); double eastLongitude = bounds.east(); double southLatitude = bounds.south(); double westLongitude = bounds.west(); - jobject jbounds = env->NewObject(latLngBoundsClass, latLngBoundsConstructorId, + jni::jobject* jbounds = &jni::NewObject(*env, *latLngBoundsClass, *latLngBoundsConstructorId, northLatitude, eastLongitude, southLatitude, westLongitude); return jbounds; @@ -498,118 +348,98 @@ namespace { using namespace mbgl::android; using DebugOptions = mbgl::MapDebugOptions; -jlong nativeCreate(JNIEnv *env, jobject obj, jstring cachePath_, jstring dataPath_, jstring apkPath_, jfloat pixelRatio, jint availableProcessors, jlong totalMemory) { +jlong nativeCreate(JNIEnv *env, jni::jobject* obj, jni::jstring* cachePath_, jni::jstring* dataPath_, jni::jstring* apkPath_, jfloat pixelRatio, jint availableProcessors, jlong totalMemory) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeCreate"); cachePath = std_string_from_jstring(env, cachePath_); dataPath = std_string_from_jstring(env, dataPath_); apkPath = std_string_from_jstring(env, apkPath_); - NativeMapView *nativeMapView = new NativeMapView(env, obj, pixelRatio, availableProcessors, totalMemory); - jlong mapViewPtr = reinterpret_cast(nativeMapView); - return mapViewPtr; + return reinterpret_cast(new NativeMapView(env, jni::Unwrap(obj), pixelRatio, availableProcessors, totalMemory)); } -void nativeDestroy(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) { +void nativeDestroy(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeDestroy"); assert(nativeMapViewPtr != 0); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - delete nativeMapView; - nativeMapView = nullptr; + delete reinterpret_cast(nativeMapViewPtr); } -void nativeInitializeDisplay(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) { +void nativeInitializeDisplay(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeInitializeDisplay"); assert(nativeMapViewPtr != 0); NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - - try - { - nativeMapView->initializeDisplay(); - } catch(const std::exception& e) { - throw_jni_error(env, "Unable to initialize GL display."); - } + nativeMapView->initializeDisplay(); } -void nativeTerminateDisplay(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) { +void nativeTerminateDisplay(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeTerminateDisplay"); assert(nativeMapViewPtr != 0); NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); nativeMapView->terminateDisplay(); } -void nativeInitializeContext(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) { +void nativeInitializeContext(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeInitializeContext"); assert(nativeMapViewPtr != 0); NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - - try { - nativeMapView->initializeContext(); - } catch(const std::exception& e) { - throw_jni_error(env, "Unable to initialize GL context."); - } + nativeMapView->initializeContext(); } -void nativeTerminateContext(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) { +void nativeTerminateContext(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeTerminateContext"); assert(nativeMapViewPtr != 0); NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); nativeMapView->terminateContext(); } -void nativeCreateSurface(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jobject surface) { +void nativeCreateSurface(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jni::jobject* surface) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeCreateSurface"); assert(nativeMapViewPtr != 0); NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - - try { - nativeMapView->createSurface(ANativeWindow_fromSurface(env, surface)); - } catch(const std::exception& e) { - throw_jni_error(env, "Unable to create GL surface."); - } + nativeMapView->createSurface(ANativeWindow_fromSurface(env, jni::Unwrap(surface))); } -void nativeDestroySurface(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) { +void nativeDestroySurface(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeDestroySurface"); assert(nativeMapViewPtr != 0); NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); nativeMapView->destroySurface(); } -void nativePause(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) { +void nativePause(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr) { mbgl::Log::Debug(mbgl::Event::JNI, "nativePause"); assert(nativeMapViewPtr != 0); NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); nativeMapView->pause(); } -jboolean nativeIsPaused(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) { +jboolean nativeIsPaused(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeIsPaused"); assert(nativeMapViewPtr != 0); NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); return nativeMapView->getMap().isPaused(); } -void nativeResume(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) { +void nativeResume(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeResume"); assert(nativeMapViewPtr != 0); NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); nativeMapView->resume(); } -void nativeUpdate(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) { +void nativeUpdate(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeUpdate"); assert(nativeMapViewPtr != 0); NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); nativeMapView->getMap().update(mbgl::Update::Repaint); } -void nativeRenderSync(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) { +void nativeRenderSync(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeRenderSync"); assert(nativeMapViewPtr != 0); NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); nativeMapView->getMap().renderSync(); } -void nativeViewResize(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jint width, jint height) { +void nativeViewResize(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jint width, jint height) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeViewResize"); assert(nativeMapViewPtr != 0); assert(width >= 0); @@ -620,7 +450,7 @@ void nativeViewResize(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jint wid nativeMapView->resizeView(width, height); } -void nativeFramebufferResize(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jint fbWidth, jint fbHeight) { +void nativeFramebufferResize(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jint fbWidth, jint fbHeight) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeFramebufferResize"); assert(nativeMapViewPtr != 0); assert(fbWidth >= 0); @@ -631,42 +461,42 @@ void nativeFramebufferResize(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, j nativeMapView->resizeFramebuffer(fbWidth, fbHeight); } -void nativeRemoveClass(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jstring clazz) { +void nativeRemoveClass(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jni::jstring* clazz) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeRemoveClass"); assert(nativeMapViewPtr != 0); NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); nativeMapView->getMap().removeClass(std_string_from_jstring(env, clazz)); } -jboolean nativeHasClass(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jstring clazz) { +jboolean nativeHasClass(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jni::jstring* clazz) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeHasClass"); assert(nativeMapViewPtr != 0); NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); return nativeMapView->getMap().hasClass(std_string_from_jstring(env, clazz)); } -void nativeAddClass(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jstring clazz) { +void nativeAddClass(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jni::jstring* clazz) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeAddClass"); assert(nativeMapViewPtr != 0); NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); nativeMapView->getMap().addClass(std_string_from_jstring(env, clazz)); } -void nativeSetClasses(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jobject classes) { +void nativeSetClasses(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jni::jobject* classes) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeSetClasses"); assert(nativeMapViewPtr != 0); NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); nativeMapView->getMap().setClasses(std_vector_string_from_jobject(env, classes)); } -jobject nativeGetClasses(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) { +jni::jobject* nativeGetClasses(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeGetClasses"); assert(nativeMapViewPtr != 0); NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); return std_vector_string_to_jobject(env, nativeMapView->getMap().getClasses()); } -void nativeSetDefaultTransitionDuration(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, +void nativeSetDefaultTransitionDuration(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jlong duration) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeSetDefaultTransitionDuration"); assert(nativeMapViewPtr != 0); @@ -675,22 +505,22 @@ void nativeSetDefaultTransitionDuration(JNIEnv *env, jobject obj, jlong nativeMa nativeMapView->getMap().setDefaultTransitionDuration(mbgl::Milliseconds(duration)); } -jlong nativeGetDefaultTransitionDuration(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) { +jlong nativeGetDefaultTransitionDuration(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeGetDefaultTransitionDuration"); assert(nativeMapViewPtr != 0); NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); return std::chrono::duration_cast(nativeMapView->getMap().getDefaultTransitionDuration()).count(); } -void nativeSetStyleURL(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jstring url) { +void nativeSetStyleUrl(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jni::jstring* url) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeSetStyleURL"); assert(nativeMapViewPtr != 0); NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); nativeMapView->getMap().setStyleURL(std_string_from_jstring(env, url)); } -void nativeSetStyleJSON(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, - jstring newStyleJson, jstring base) { +void nativeSetStyleJson(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, + jni::jstring* newStyleJson, jni::jstring* base) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeSetStyleJSON"); assert(nativeMapViewPtr != 0); NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); @@ -698,42 +528,42 @@ void nativeSetStyleJSON(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, std_string_from_jstring(env, base)); } -jstring nativeGetStyleJSON(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) { +jni::jstring* nativeGetStyleJson(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeGetStyleJSON"); assert(nativeMapViewPtr != 0); NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); return std_string_to_jstring(env, nativeMapView->getMap().getStyleJSON()); } -void nativeSetAccessToken(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jstring accessToken) { +void nativeSetAccessToken(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jni::jstring* accessToken) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeSetAccessToken"); assert(nativeMapViewPtr != 0); NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); nativeMapView->getFileSource().setAccessToken(std_string_from_jstring(env, accessToken)); } -jstring nativeGetAccessToken(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) { +jni::jstring* nativeGetAccessToken(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeGetAccessToken"); assert(nativeMapViewPtr != 0); NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); return std_string_to_jstring(env, nativeMapView->getFileSource().getAccessToken()); } -void nativeCancelTransitions(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) { +void nativeCancelTransitions(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeCancelTransitions"); assert(nativeMapViewPtr != 0); NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); nativeMapView->getMap().cancelTransitions(); } -void nativeSetGestureInProgress(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jboolean inProgress) { +void nativeSetGestureInProgress(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jboolean inProgress) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeSetGestureInProgress"); assert(nativeMapViewPtr != 0); NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); nativeMapView->getMap().setGestureInProgress(inProgress); } -void nativeMoveBy(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jdouble dx, jdouble dy, +void nativeMoveBy(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jdouble dx, jdouble dy, jlong duration) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeMoveBy"); assert(nativeMapViewPtr != 0); @@ -742,43 +572,27 @@ void nativeMoveBy(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jdouble dx, nativeMapView->getMap().moveBy(center, mbgl::Milliseconds(duration)); } -void nativeSetLatLng(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jobject latLng, +void nativeSetLatLng(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jni::jobject* latLng, jlong duration) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeSetLatLng"); assert(nativeMapViewPtr != 0); NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - jdouble latitude = env->GetDoubleField(latLng, latLngLatitudeId); - if (env->ExceptionCheck()) { - env->ExceptionDescribe(); - return; - } - - jdouble longitude = env->GetDoubleField(latLng, latLngLongitudeId); - if (env->ExceptionCheck()) { - env->ExceptionDescribe(); - return; - } + jdouble latitude = jni::GetField(*env, latLng, *latLngLatitudeId); + jdouble longitude = jni::GetField(*env, latLng, *latLngLongitudeId); nativeMapView->getMap().setLatLng(mbgl::LatLng(latitude, longitude), nativeMapView->getInsets(), mbgl::Duration(duration)); } -jobject nativeGetLatLng(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) { +jni::jobject* nativeGetLatLng(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeGetLatLng"); assert(nativeMapViewPtr != 0); NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); mbgl::LatLng latLng = nativeMapView->getMap().getLatLng(nativeMapView->getInsets()); - - jobject ret = env->NewObject(latLngClass, latLngConstructorId, latLng.latitude, latLng.longitude); - if (ret == nullptr) { - env->ExceptionDescribe(); - return nullptr; - } - - return ret; + return &jni::NewObject(*env, *latLngClass, *latLngConstructorId, latLng.latitude, latLng.longitude); } -jdoubleArray nativeGetCameraValues(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) { +jdoubleArray nativeGetCameraValues(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeGetCameraValues"); assert(nativeMapViewPtr != 0); NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); @@ -802,21 +616,21 @@ jdoubleArray nativeGetCameraValues(JNIEnv *env, jobject obj, jlong nativeMapView return output; } -void nativeResetPosition(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) { +void nativeResetPosition(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeResetPosition"); assert(nativeMapViewPtr != 0); NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); nativeMapView->getMap().resetPosition(); } -jdouble nativeGetPitch(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) { +jdouble nativeGetPitch(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeGetPitch"); assert(nativeMapViewPtr != 0); NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); return nativeMapView->getMap().getPitch(); } -void nativeSetPitch(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jdouble pitch, jlong milliseconds) { +void nativeSetPitch(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jdouble pitch, jlong milliseconds) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeGetPitch"); assert(nativeMapViewPtr != 0); NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); @@ -824,7 +638,7 @@ void nativeSetPitch(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jdouble pi nativeMapView->getMap().setPitch(pitch, duration); } -void nativeScaleBy(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jdouble ds, jdouble cx, +void nativeScaleBy(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jdouble ds, jdouble cx, jdouble cy, jlong duration) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeScaleBy"); assert(nativeMapViewPtr != 0); @@ -833,7 +647,7 @@ void nativeScaleBy(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jdouble ds, nativeMapView->getMap().scaleBy(ds, center, mbgl::Milliseconds(duration)); } -void nativeSetScale(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jdouble scale, +void nativeSetScale(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jdouble scale, jdouble cx, jdouble cy, jlong duration) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeSetScale"); assert(nativeMapViewPtr != 0); @@ -842,63 +656,63 @@ void nativeSetScale(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jdouble sc nativeMapView->getMap().setScale(scale, center, mbgl::Milliseconds(duration)); } -jdouble nativeGetScale(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) { +jdouble nativeGetScale(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeGetScale"); assert(nativeMapViewPtr != 0); NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); return nativeMapView->getMap().getScale(); } -void nativeSetZoom(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jdouble zoom, jlong duration) { +void nativeSetZoom(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jdouble zoom, jlong duration) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeSetZoom"); assert(nativeMapViewPtr != 0); NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); nativeMapView->getMap().setZoom(zoom, mbgl::Milliseconds(duration)); } -jdouble nativeGetZoom(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) { +jdouble nativeGetZoom(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeGetZoom"); assert(nativeMapViewPtr != 0); NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); return nativeMapView->getMap().getZoom(); } -void nativeResetZoom(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) { +void nativeResetZoom(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeResetZoom"); assert(nativeMapViewPtr != 0); NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); nativeMapView->getMap().resetZoom(); } -void nativeSetMinZoom(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jdouble zoom) { +void nativeSetMinZoom(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jdouble zoom) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeSetMinZoom"); assert(nativeMapViewPtr != 0); NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); nativeMapView->getMap().setMinZoom(zoom); } -jdouble nativeGetMinZoom(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) { +jdouble nativeGetMinZoom(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeGetMinZoom"); assert(nativeMapViewPtr != 0); NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); return nativeMapView->getMap().getMinZoom(); } -void nativeSetMaxZoom(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jdouble zoom) { +void nativeSetMaxZoom(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jdouble zoom) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeSetMaxZoom"); assert(nativeMapViewPtr != 0); NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); nativeMapView->getMap().setMaxZoom(zoom); } -jdouble nativeGetMaxZoom(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) { +jdouble nativeGetMaxZoom(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeGetMaxZoom"); assert(nativeMapViewPtr != 0); NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); return nativeMapView->getMap().getMaxZoom(); } -void nativeRotateBy(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jdouble sx, +void nativeRotateBy(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jdouble sx, jdouble sy, jdouble ex, jdouble ey, jlong duration) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeRotateBy"); assert(nativeMapViewPtr != 0); @@ -908,7 +722,7 @@ void nativeRotateBy(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jdouble sx nativeMapView->getMap().rotateBy(first, second, mbgl::Milliseconds(duration)); } -void nativeSetBearing(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jdouble degrees, +void nativeSetBearing(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jdouble degrees, jlong milliseconds) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeSetBearing"); assert(nativeMapViewPtr != 0); @@ -917,208 +731,126 @@ void nativeSetBearing(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jdouble nativeMapView->getMap().setBearing(degrees, duration); } -void nativeSetBearing(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jdouble degrees, +void nativeSetBearingXY(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jdouble degrees, jdouble cx, jdouble cy) { - mbgl::Log::Debug(mbgl::Event::JNI, "nativeSetBearing"); + mbgl::Log::Debug(mbgl::Event::JNI, "nativeSetBearingXY"); assert(nativeMapViewPtr != 0); NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); mbgl::ScreenCoordinate center(cx, cy); nativeMapView->getMap().setBearing(degrees, center); } -jdouble nativeGetBearing(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) { +jdouble nativeGetBearing(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeGetBearing"); assert(nativeMapViewPtr != 0); NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); return nativeMapView->getMap().getBearing(); } -void nativeResetNorth(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) { +void nativeResetNorth(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeResetNorth"); assert(nativeMapViewPtr != 0); NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); nativeMapView->getMap().resetNorth(); } -jlong nativeAddMarker(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jobject marker) { +jlong nativeAddMarker(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jni::jobject* marker) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeAddMarker"); assert(nativeMapViewPtr != 0); NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - jobject position = env->GetObjectField(marker, markerPositionId); - if (env->ExceptionCheck()) { - env->ExceptionDescribe(); - return -1; - } - - jobject icon = env->GetObjectField(marker, markerIconId); - if (env->ExceptionCheck()) { - env->ExceptionDescribe(); - return -1; - } + jni::jobject* position = jni::GetField(*env, marker, *markerPositionId); + jni::jobject* icon = jni::GetField(*env, marker, *markerIconId); - jstring jid = reinterpret_cast(env->GetObjectField(icon, iconIdId)); + jni::jstring* jid = reinterpret_cast(jni::GetField(*env, icon, *iconIdId)); std::string id = std_string_from_jstring(env, jid); - jdouble latitude = env->GetDoubleField(position, latLngLatitudeId); - if (env->ExceptionCheck()) { - env->ExceptionDescribe(); - return -1; - } - - jdouble longitude = env->GetDoubleField(position, latLngLongitudeId); - if (env->ExceptionCheck()) { - env->ExceptionDescribe(); - return -1; - } + jdouble latitude = jni::GetField(*env, position, *latLngLatitudeId); + jdouble longitude = jni::GetField(*env, position, *latLngLongitudeId); // Because Java only has int, not unsigned int, we need to bump the annotation id up to a long. return nativeMapView->getMap().addPointAnnotation(mbgl::PointAnnotation(mbgl::LatLng(latitude, longitude), id)); } -void nativeUpdateMarker(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jobject marker) { +void nativeUpdateMarker(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jni::jobject* marker) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeUpdateMarker"); assert(nativeMapViewPtr != 0); NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - jlong markerId = env->GetLongField(marker, markerIdId); - if (env->ExceptionCheck()) { - env->ExceptionDescribe(); - } - + jlong markerId = jni::GetField(*env, marker, *markerIdId); if (markerId == -1) { return; } - jobject position = env->GetObjectField(marker, markerPositionId); - if (env->ExceptionCheck()) { - env->ExceptionDescribe(); - } - - jobject icon = env->GetObjectField(marker, markerIconId); - if (env->ExceptionCheck()) { - env->ExceptionDescribe(); - } + jni::jobject* position = jni::GetField(*env, marker, *markerPositionId); + jni::jobject* icon = jni::GetField(*env, marker, *markerIconId); - jstring jid = reinterpret_cast(env->GetObjectField(icon, iconIdId)); + jni::jstring* jid = reinterpret_cast(jni::GetField(*env, icon, *iconIdId)); std::string iconId = std_string_from_jstring(env, jid); - jdouble latitude = env->GetDoubleField(position, latLngLatitudeId); - if (env->ExceptionCheck()) { - env->ExceptionDescribe(); - } - - jdouble longitude = env->GetDoubleField(position, latLngLongitudeId); - if (env->ExceptionCheck()) { - env->ExceptionDescribe(); - } + jdouble latitude = jni::GetField(*env, position, *latLngLatitudeId); + jdouble longitude = jni::GetField(*env, position, *latLngLongitudeId); // Because Java only has int, not unsigned int, we need to bump the annotation id up to a long. nativeMapView->getMap().updatePointAnnotation(markerId, mbgl::PointAnnotation(mbgl::LatLng(latitude, longitude), iconId)); } -jlongArray nativeAddMarkers(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jobject jlist) { +jni::jarray* nativeAddMarkers(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jni::jobject* jlist) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeAddMarkers"); assert(nativeMapViewPtr != 0); NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); std::vector markers; - if (jlist == nullptr) { - if (env->ThrowNew(nullPointerExceptionClass, "List cannot be null.") < 0) { - env->ExceptionDescribe(); - return nullptr; - } - return nullptr; - } + NullCheck(*env, jlist); + jni::jarray* jarray = + reinterpret_cast*>(jni::CallMethod(*env, jlist, *listToArrayId)); - jobjectArray jarray = - reinterpret_cast(env->CallObjectMethod(jlist, listToArrayId)); - if (env->ExceptionCheck() || (jarray == nullptr)) { - env->ExceptionDescribe(); - return nullptr; - } - - jsize len = env->GetArrayLength(jarray); - if (len < 0) { - env->ExceptionDescribe(); - return nullptr; - } + NullCheck(*env, jarray); + std::size_t len = jni::GetArrayLength(*env, *jarray); markers.reserve(len); - for (jsize i = 0; i < len; i++) { - jobject marker = reinterpret_cast(env->GetObjectArrayElement(jarray, i)); - - jobject position = env->GetObjectField(marker, markerPositionId); - if (env->ExceptionCheck()) { - env->ExceptionDescribe(); - return nullptr; - } - - jobject icon = env->GetObjectField(marker, markerIconId); - if (env->ExceptionCheck()) { - env->ExceptionDescribe(); - return nullptr; - } - env->DeleteLocalRef(marker); + for (std::size_t i = 0; i < len; i++) { + jni::jobject* marker = jni::GetObjectArrayElement(*env, *jarray, i); + jni::jobject* position = jni::GetField(*env, marker, *markerPositionId); + jni::jobject* icon = jni::GetField(*env, marker, *markerIconId); + jni::DeleteLocalRef(*env, marker); - jstring jid = reinterpret_cast(env->GetObjectField(icon, iconIdId)); - env->DeleteLocalRef(icon); + jni::jstring* jid = reinterpret_cast(jni::GetField(*env, icon, *iconIdId)); + jni::DeleteLocalRef(*env, icon); std::string id = std_string_from_jstring(env, jid); - env->DeleteLocalRef(jid); + jni::DeleteLocalRef(*env, jid); - jdouble latitude = env->GetDoubleField(position, latLngLatitudeId); - if (env->ExceptionCheck()) { - env->ExceptionDescribe(); - return nullptr; - } - - jdouble longitude = env->GetDoubleField(position, latLngLongitudeId); - if (env->ExceptionCheck()) { - env->ExceptionDescribe(); - return nullptr; - } - env->DeleteLocalRef(position); + jdouble latitude = jni::GetField(*env, position, *latLngLatitudeId); + jdouble longitude = jni::GetField(*env, position, *latLngLongitudeId); + jni::DeleteLocalRef(*env, position); markers.emplace_back(mbgl::PointAnnotation(mbgl::LatLng(latitude, longitude), id)); } - env->DeleteLocalRef(jarray); + jni::DeleteLocalRef(*env, jarray); std::vector pointAnnotationIDs = nativeMapView->getMap().addPointAnnotations(markers); return std_vector_uint_to_jobject(env, pointAnnotationIDs); } -jlong nativeAddPolyline(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jobject polyline) { +jlong nativeAddPolyline(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jni::jobject* polyline) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeAddPolyline"); assert(nativeMapViewPtr != 0); NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - jfloat alpha = env->GetFloatField(polyline, polylineAlphaId); - if (env->ExceptionCheck()) { - env->ExceptionDescribe(); - return -1; - } - - jint color = env->GetIntField(polyline, polylineColorId); - if (env->ExceptionCheck()) { - env->ExceptionDescribe(); - return -1; - } + jfloat alpha = jni::GetField(*env, polyline, *polylineAlphaId); + jint color = jni::GetField(*env, polyline, *polylineColorId); int r = (color >> 16) & 0xFF; int g = (color >> 8) & 0xFF; int b = (color) & 0xFF; int a = (color >> 24) & 0xFF; - jfloat width = env->GetFloatField(polyline, polylineWidthId); - if (env->ExceptionCheck()) { - env->ExceptionDescribe(); - return -1; - } + jfloat width = jni::GetField(*env, polyline, *polylineWidthId); mbgl::ShapeAnnotation::Properties shapeProperties; mbgl::LineAnnotationProperties lineProperties; @@ -1127,7 +859,7 @@ jlong nativeAddPolyline(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jobjec lineProperties.width = width; shapeProperties.set(lineProperties); - jobject points = env->GetObjectField(polyline, polylinePointsId); + jni::jobject* points = jni::GetField(*env, polyline, *polylinePointsId); mbgl::AnnotationSegment segment = annotation_segment_from_latlng_jlist(env, points); std::vector shapes; @@ -1139,61 +871,33 @@ jlong nativeAddPolyline(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jobjec return id; } -jlongArray nativeAddPolylines(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jobject jlist) { +jni::jarray* nativeAddPolylines(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jni::jobject* jlist) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeAddPolylines"); assert(nativeMapViewPtr != 0); NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); std::vector shapes; - if (jlist == nullptr) { - if (env->ThrowNew(nullPointerExceptionClass, "List cannot be null.") < 0) { - env->ExceptionDescribe(); - return nullptr; - } - return nullptr; - } + jni::jarray* jarray = + reinterpret_cast*>(jni::CallMethod(*env, jlist, *listToArrayId)); - jobjectArray jarray = - reinterpret_cast(env->CallObjectMethod(jlist, listToArrayId)); - if (env->ExceptionCheck() || (jarray == nullptr)) { - env->ExceptionDescribe(); - return nullptr; - } - - jsize len = env->GetArrayLength(jarray); - if (len < 0) { - env->ExceptionDescribe(); - return nullptr; - } + NullCheck(*env, jarray); + std::size_t len = jni::GetArrayLength(*env, *jarray); shapes.reserve(len); - for (jsize i = 0; i < len; i++) { - jobject polyline = reinterpret_cast(env->GetObjectArrayElement(jarray, i)); - - jfloat alpha = env->GetFloatField(polyline, polylineAlphaId); - if (env->ExceptionCheck()) { - env->ExceptionDescribe(); - return nullptr; - } + for (std::size_t i = 0; i < len; i++) { + jni::jobject* polyline = jni::GetObjectArrayElement(*env, *jarray, i); - jint color = env->GetIntField(polyline, polylineColorId); - if (env->ExceptionCheck()) { - env->ExceptionDescribe(); - return nullptr; - } + jfloat alpha = jni::GetField(*env, polyline, *polylineAlphaId); + jint color = jni::GetField(*env, polyline, *polylineColorId); int r = (color >> 16) & 0xFF; int g = (color >> 8) & 0xFF; int b = (color) & 0xFF; int a = (color >> 24) & 0xFF; - jfloat width = env->GetFloatField(polyline, polylineWidthId); - if (env->ExceptionCheck()) { - env->ExceptionDescribe(); - return nullptr; - } + jfloat width = jni::GetField(*env, polyline, *polylineWidthId); mbgl::ShapeAnnotation::Properties shapeProperties; mbgl::LineAnnotationProperties lineProperties; @@ -1202,21 +906,21 @@ jlongArray nativeAddPolylines(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, lineProperties.width = width; shapeProperties.set(lineProperties); - jobject points = env->GetObjectField(polyline, polylinePointsId); + jni::jobject* points = jni::GetField(*env, polyline, *polylinePointsId); mbgl::AnnotationSegment segment = annotation_segment_from_latlng_jlist(env, points); shapes.emplace_back(mbgl::AnnotationSegments { segment }, shapeProperties); - env->DeleteLocalRef(polyline); + jni::DeleteLocalRef(*env, polyline); } - env->DeleteLocalRef(jarray); + jni::DeleteLocalRef(*env, jarray); std::vector shapeAnnotationIDs = nativeMapView->getMap().addShapeAnnotations(shapes); return std_vector_uint_to_jobject(env, shapeAnnotationIDs); } -jlong nativeAddPolygon(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jobject polygon) { +jlong nativeAddPolygon(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jni::jobject* polygon) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeAddPolygon"); assert(nativeMapViewPtr != 0); NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); @@ -1224,11 +928,6 @@ jlong nativeAddPolygon(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jobject std::vector shapes; std::pair segment = annotation_std_pair_from_polygon_jobject(env, polygon); - if (env->ExceptionCheck()) { - env->ExceptionDescribe(); - return -1; - } - shapes.emplace_back(mbgl::AnnotationSegments { segment.first }, segment.second); std::vector shapeAnnotationIDs = nativeMapView->getMap().addShapeAnnotations(shapes); @@ -1236,96 +935,66 @@ jlong nativeAddPolygon(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jobject return id; } -jlongArray nativeAddPolygons(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jobject jlist) { +jni::jarray* nativeAddPolygons(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jni::jobject* jlist) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeAddPolygons"); assert(nativeMapViewPtr != 0); NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); std::vector shapes; - if (jlist == nullptr) { - if (env->ThrowNew(nullPointerExceptionClass, "List cannot be null.") < 0) { - env->ExceptionDescribe(); - return nullptr; - } - return nullptr; - } - - jobjectArray jarray = - reinterpret_cast(env->CallObjectMethod(jlist, listToArrayId)); - if (env->ExceptionCheck() || (jarray == nullptr)) { - env->ExceptionDescribe(); - return nullptr; - } - - jsize len = env->GetArrayLength(jarray); - if (len < 0) { - env->ExceptionDescribe(); - return nullptr; - } + jni::jarray* jarray = + reinterpret_cast*>(jni::CallMethod(*env, jlist, *listToArrayId)); + NullCheck(*env, jarray); + std::size_t len = jni::GetArrayLength(*env, *jarray); shapes.reserve(len); - for (jsize i = 0; i < len; i++) { - jobject polygon = reinterpret_cast(env->GetObjectArrayElement(jarray, i)); + for (std::size_t i = 0; i < len; i++) { + jni::jobject* polygon = jni::GetObjectArrayElement(*env, *jarray, i); std::pair segment = annotation_std_pair_from_polygon_jobject(env, polygon); - if (env->ExceptionCheck()) { - env->ExceptionDescribe(); - return nullptr; - } - shapes.emplace_back(mbgl::AnnotationSegments { segment.first }, segment.second); - env->DeleteLocalRef(polygon); + jni::DeleteLocalRef(*env, polygon); } - env->DeleteLocalRef(jarray); + jni::DeleteLocalRef(*env, jarray); std::vector shapeAnnotationIDs = nativeMapView->getMap().addShapeAnnotations(shapes); return std_vector_uint_to_jobject(env, shapeAnnotationIDs); } -void nativeRemoveAnnotation(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jlong annotationId) { +void nativeRemoveAnnotation(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jlong annotationId) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeRemoveAnnotation"); assert(nativeMapViewPtr != 0); NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); nativeMapView->getMap().removeAnnotation(static_cast(annotationId)); } -void nativeRemoveAnnotations(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jlongArray jarray) { +void nativeRemoveAnnotations(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jni::jarray* jarray) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeRemoveAnnotations"); assert(nativeMapViewPtr != 0); NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - std::vector ids; - - if (env->ExceptionCheck() || (jarray == nullptr)) { - env->ExceptionDescribe(); - return; - } - - jsize len = env->GetArrayLength(jarray); - if (len < 0) { - env->ExceptionDescribe(); - return; - } + NullCheck(*env, jarray); + std::size_t len = jni::GetArrayLength(*env, *jarray); + std::vector ids; ids.reserve(len); - jlong* jids = env->GetLongArrayElements(jarray, nullptr); - for (jsize i = 0; i < len; i++) { + auto elements = jni::GetArrayElements(*env, *jarray); + jlong* jids = std::get<0>(elements).get(); + + for (std::size_t i = 0; i < len; i++) { if(jids[i] == -1L) continue; ids.push_back(static_cast(jids[i])); } - env->ReleaseLongArrayElements(jarray, jids, JNI_ABORT); - nativeMapView->getMap().removeAnnotations(ids); } -jlongArray nativeGetAnnotationsInBounds(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jobject latLngBounds_) { +jni::jarray* nativeGetAnnotationsInBounds(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jni::jobject* latLngBounds_) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeGetAnnotationsInBounds"); assert(nativeMapViewPtr != 0); NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); @@ -1343,22 +1012,23 @@ jlongArray nativeGetAnnotationsInBounds(JNIEnv *env, jobject obj, jlong nativeMa return std_vector_uint_to_jobject(env, annotations); } -void nativeAddAnnotationIcon(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, - jstring symbol, jint width, jint height, jfloat scale, jbyteArray jpixels) { +void nativeAddAnnotationIcon(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, + jni::jstring* symbol, jint width, jint height, jfloat scale, jni::jarray* jpixels) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeAddAnnotationIcon"); assert(nativeMapViewPtr != 0); NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); const std::string symbolName = std_string_from_jstring(env, symbol); - jsize size = env->GetArrayLength(jpixels); + NullCheck(*env, jpixels); + std::size_t size = jni::GetArrayLength(*env, *jpixels); mbgl::PremultipliedImage premultipliedImage(width, height); if (premultipliedImage.size() != uint32_t(size)) { throw mbgl::util::SpriteImageException("Sprite image pixel count mismatch"); } - env->GetByteArrayRegion(jpixels, 0, size, reinterpret_cast(premultipliedImage.data.get())); + jni::GetArrayRegion(*env, *jpixels, 0, size, reinterpret_cast(premultipliedImage.data.get())); auto iconImage = std::make_shared( std::move(premultipliedImage), @@ -1367,54 +1037,28 @@ void nativeAddAnnotationIcon(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, nativeMapView->getMap().addAnnotationIcon(symbolName, iconImage); } -void nativeSetVisibleCoordinateBounds(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, - jobjectArray coordinates, jobject padding, jdouble direction, jlong duration) { +void nativeSetVisibleCoordinateBounds(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, + jni::jarray* coordinates, jni::jobject* padding, jdouble direction, jlong duration) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeSetVisibleCoordinateBounds"); assert(nativeMapViewPtr != 0); NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - jfloat left = env->GetFloatField(padding, rectFLeftId); - if (env->ExceptionCheck()) { - env->ExceptionDescribe(); - return; - } + jfloat left = jni::GetField(*env, padding, *rectFLeftId); + jfloat right = jni::GetField(*env, padding, *rectFRightId); + jfloat top = jni::GetField(*env, padding, *rectFTopId); + jfloat bottom = jni::GetField(*env, padding, *rectFBottomId); - jfloat right = env->GetFloatField(padding, rectFRightId); - if (env->ExceptionCheck()) { - env->ExceptionDescribe(); - return; - } - - jfloat top = env->GetFloatField(padding, rectFTopId); - if (env->ExceptionCheck()) { - env->ExceptionDescribe(); - return; - } - - jfloat bottom = env->GetFloatField(padding, rectFBottomId); - if (env->ExceptionCheck()) { - env->ExceptionDescribe(); - return; - } - - jsize count = env->GetArrayLength(coordinates); + NullCheck(*env, coordinates); + std::size_t count = jni::GetArrayLength(*env, *coordinates); mbgl::EdgeInsets mbglInsets = {top, left, bottom, right}; mbgl::AnnotationSegment segment; segment.reserve(count); - for (int i = 0; i < count; i++) { - jobject latLng = reinterpret_cast(env->GetObjectArrayElement(coordinates, i)); - jdouble latitude = env->GetDoubleField(latLng, latLngLatitudeId); - if (env->ExceptionCheck()) { - env->ExceptionDescribe(); - return; - } - jdouble longitude = env->GetDoubleField(latLng, latLngLongitudeId); - if (env->ExceptionCheck()) { - env->ExceptionDescribe(); - return; - } + for (std::size_t i = 0; i < count; i++) { + jni::jobject* latLng = jni::GetObjectArrayElement(*env, *coordinates, i); + jdouble latitude = jni::GetField(*env, latLng, *latLngLatitudeId); + jdouble longitude = jni::GetField(*env, latLng, *latLngLongitudeId); segment.push_back(mbgl::LatLng(latitude, longitude)); } @@ -1433,14 +1077,14 @@ void nativeSetVisibleCoordinateBounds(JNIEnv *env, jobject obj, jlong nativeMapV nativeMapView->getMap().easeTo(cameraOptions, animationOptions); } -void nativeOnLowMemory(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) { +void nativeOnLowMemory(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeOnLowMemory"); assert(nativeMapViewPtr != 0); NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); nativeMapView->getMap().onLowMemory(); } -void nativeSetDebug(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jboolean debug) { +void nativeSetDebug(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jboolean debug) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeSetDebug"); assert(nativeMapViewPtr != 0); NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); @@ -1451,7 +1095,7 @@ void nativeSetDebug(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jboolean d nativeMapView->enableFps(debug); } -void nativeToggleDebug(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) { +void nativeToggleDebug(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeToggleDebug"); assert(nativeMapViewPtr != 0); NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); @@ -1459,21 +1103,21 @@ void nativeToggleDebug(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) { nativeMapView->enableFps(nativeMapView->getMap().getDebug() != DebugOptions::NoDebug); } -jboolean nativeGetDebug(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) { +jboolean nativeGetDebug(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeGetDebug"); assert(nativeMapViewPtr != 0); NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); return nativeMapView->getMap().getDebug() != DebugOptions::NoDebug; } -jboolean nativeIsFullyLoaded(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) { +jboolean nativeIsFullyLoaded(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeIsFullyLoaded"); assert(nativeMapViewPtr != 0); NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); return nativeMapView->getMap().isFullyLoaded(); } -void nativeSetReachability(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jboolean status) { +void nativeSetReachability(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jboolean status) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeSetReachability"); assert(nativeMapViewPtr != 0); if (status) { @@ -1481,148 +1125,75 @@ void nativeSetReachability(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jbo } } -jdouble nativeGetMetersPerPixelAtLatitude(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jdouble lat, jdouble zoom) { +jdouble nativeGetMetersPerPixelAtLatitude(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jdouble lat, jdouble zoom) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeGetMetersPerPixelAtLatitude"); assert(nativeMapViewPtr != 0); NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); return nativeMapView->getMap().getMetersPerPixelAtLatitude(lat, zoom); } -jobject nativeProjectedMetersForLatLng(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jobject latLng) { +jni::jobject* nativeProjectedMetersForLatLng(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jni::jobject* latLng) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeProjectedMetersForLatLng"); assert(nativeMapViewPtr != 0); NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - jdouble latitude = env->GetDoubleField(latLng, latLngLatitudeId); - if (env->ExceptionCheck()) { - env->ExceptionDescribe(); - return nullptr; - } - - jdouble longitude = env->GetDoubleField(latLng, latLngLongitudeId); - if (env->ExceptionCheck()) { - env->ExceptionDescribe(); - return nullptr; - } + jdouble latitude = jni::GetField(*env, latLng, *latLngLatitudeId); + jdouble longitude = jni::GetField(*env, latLng, *latLngLongitudeId); mbgl::ProjectedMeters projectedMeters = nativeMapView->getMap().projectedMetersForLatLng(mbgl::LatLng(latitude, longitude)); - - jobject ret = env->NewObject(projectedMetersClass, projectedMetersConstructorId, projectedMeters.northing, projectedMeters.easting); - if (ret == nullptr) { - env->ExceptionDescribe(); - return nullptr; - } - - return ret; + return &jni::NewObject(*env, *projectedMetersClass, *projectedMetersConstructorId, projectedMeters.northing, projectedMeters.easting); } -jobject nativeLatLngForProjectedMeters(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jobject projectedMeters) { +jni::jobject* nativeLatLngForProjectedMeters(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jni::jobject* projectedMeters) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeLatLngForProjectedMeters"); assert(nativeMapViewPtr != 0); NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - jdouble northing = env->GetDoubleField(projectedMeters, projectedMetersNorthingId); - if (env->ExceptionCheck()) { - env->ExceptionDescribe(); - return nullptr; - } - - jdouble easting = env->GetDoubleField(projectedMeters, projectedMetersEastingId); - if (env->ExceptionCheck()) { - env->ExceptionDescribe(); - return nullptr; - } + jdouble northing = jni::GetField(*env, projectedMeters, *projectedMetersNorthingId); + jdouble easting = jni::GetField(*env, projectedMeters, *projectedMetersEastingId); mbgl::LatLng latLng = nativeMapView->getMap().latLngForProjectedMeters(mbgl::ProjectedMeters(northing, easting)); - - jobject ret = env->NewObject(latLngClass, latLngConstructorId, latLng.latitude, latLng.longitude); - if (ret == nullptr) { - env->ExceptionDescribe(); - return nullptr; - } - - return ret; + return &jni::NewObject(*env, *latLngClass, *latLngConstructorId, latLng.latitude, latLng.longitude); } -jobject nativePixelForLatLng(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jobject latLng) { +jni::jobject* nativePixelForLatLng(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jni::jobject* latLng) { mbgl::Log::Debug(mbgl::Event::JNI, "nativePixelForLatLng"); assert(nativeMapViewPtr != 0); NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - jdouble latitude = env->GetDoubleField(latLng, latLngLatitudeId); - if (env->ExceptionCheck()) { - env->ExceptionDescribe(); - return nullptr; - } - - jdouble longitude = env->GetDoubleField(latLng, latLngLongitudeId); - if (env->ExceptionCheck()) { - env->ExceptionDescribe(); - return nullptr; - } + jdouble latitude = jni::GetField(*env, latLng, *latLngLatitudeId); + jdouble longitude = jni::GetField(*env, latLng, *latLngLongitudeId); mbgl::ScreenCoordinate pixel = nativeMapView->getMap().pixelForLatLng(mbgl::LatLng(latitude, longitude)); - - jobject ret = env->NewObject(pointFClass, pointFConstructorId, static_cast(pixel.x), static_cast(pixel.y)); - if (ret == nullptr) { - env->ExceptionDescribe(); - return nullptr; - } - - return ret; + return &jni::NewObject(*env, *pointFClass, *pointFConstructorId, static_cast(pixel.x), static_cast(pixel.y)); } -jobject nativeLatLngForPixel(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jobject pixel) { +jni::jobject* nativeLatLngForPixel(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jni::jobject* pixel) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeLatLngForPixel"); assert(nativeMapViewPtr != 0); NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - jfloat x = env->GetFloatField(pixel, pointFXId); - if (env->ExceptionCheck()) { - env->ExceptionDescribe(); - return nullptr; - } - - jfloat y = env->GetFloatField(pixel, pointFYId); - if (env->ExceptionCheck()) { - env->ExceptionDescribe(); - return nullptr; - } + jfloat x = jni::GetField(*env, pixel, *pointFXId); + jfloat y = jni::GetField(*env, pixel, *pointFYId); mbgl::LatLng latLng = nativeMapView->getMap().latLngForPixel(mbgl::ScreenCoordinate(x, y)); - - jobject ret = env->NewObject(latLngClass, latLngConstructorId, latLng.latitude, latLng.longitude); - if (ret == nullptr) { - env->ExceptionDescribe(); - return nullptr; - } - - return ret; + return &jni::NewObject(*env, *latLngClass, *latLngConstructorId, latLng.latitude, latLng.longitude); } -jdouble nativeGetTopOffsetPixelsForAnnotationSymbol(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jstring symbolName) { +jdouble nativeGetTopOffsetPixelsForAnnotationSymbol(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jni::jstring* symbolName) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeGetTopOffsetPixelsForAnnotationSymbol"); assert(nativeMapViewPtr != 0); NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); return nativeMapView->getMap().getTopOffsetPixelsForAnnotationIcon(std_string_from_jstring(env, symbolName)); } -void nativeJumpTo(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jdouble angle, jobject centerLatLng, jdouble pitch, jdouble zoom) { +void nativeJumpTo(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jdouble angle, jni::jobject* centerLatLng, jdouble pitch, jdouble zoom) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeJumpTo"); assert(nativeMapViewPtr != 0); NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - jdouble latitude = env->GetDoubleField(centerLatLng, latLngLatitudeId); - if (env->ExceptionCheck()) { - env->ExceptionDescribe(); - return; - } - - jdouble longitude = env->GetDoubleField(centerLatLng, latLngLongitudeId); - if (env->ExceptionCheck()) { - env->ExceptionDescribe(); - return; - } + jdouble latitude = jni::GetField(*env, centerLatLng, *latLngLatitudeId); + jdouble longitude = jni::GetField(*env, centerLatLng, *latLngLongitudeId); mbgl::CameraOptions options; if (angle != -1) { @@ -1640,22 +1211,13 @@ void nativeJumpTo(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jdouble angl nativeMapView->getMap().jumpTo(options); } -void nativeEaseTo(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jdouble angle, jobject centerLatLng, jlong duration, jdouble pitch, jdouble zoom) { +void nativeEaseTo(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jdouble angle, jni::jobject* centerLatLng, jlong duration, jdouble pitch, jdouble zoom) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeEaseTo"); assert(nativeMapViewPtr != 0); NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - jdouble latitude = env->GetDoubleField(centerLatLng, latLngLatitudeId); - if (env->ExceptionCheck()) { - env->ExceptionDescribe(); - return; - } - - jdouble longitude = env->GetDoubleField(centerLatLng, latLngLongitudeId); - if (env->ExceptionCheck()) { - env->ExceptionDescribe(); - return; - } + jdouble latitude = jni::GetField(*env, centerLatLng, *latLngLatitudeId); + jdouble longitude = jni::GetField(*env, centerLatLng, *latLngLongitudeId); mbgl::CameraOptions cameraOptions; if (angle != -1) { @@ -1675,7 +1237,7 @@ void nativeEaseTo(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jdouble angl nativeMapView->getMap().easeTo(cameraOptions, animationOptions); } -void nativeSetContentPadding(JNIEnv *env, jobject obj,long nativeMapViewPtr, double top, double left, double bottom, double right) { +void nativeSetContentPadding(JNIEnv *env, jni::jobject* obj,long nativeMapViewPtr, double top, double left, double bottom, double right) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeSetContentPadding"); assert(nativeMapViewPtr != 0); NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); @@ -1683,22 +1245,13 @@ void nativeSetContentPadding(JNIEnv *env, jobject obj,long nativeMapViewPtr, dou } -void nativeFlyTo(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jdouble angle, jobject centerLatLng, jlong duration, jdouble pitch, jdouble zoom) { +void nativeFlyTo(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jdouble angle, jni::jobject* centerLatLng, jlong duration, jdouble pitch, jdouble zoom) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeFlyTo"); assert(nativeMapViewPtr != 0); NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - jdouble latitude = env->GetDoubleField(centerLatLng, latLngLatitudeId); - if (env->ExceptionCheck()) { - env->ExceptionDescribe(); - return; - } - - jdouble longitude = env->GetDoubleField(centerLatLng, latLngLongitudeId); - if (env->ExceptionCheck()) { - env->ExceptionDescribe(); - return; - } + jdouble latitude = jni::GetField(*env, centerLatLng, *latLngLatitudeId); + jdouble longitude = jni::GetField(*env, centerLatLng, *latLngLongitudeId); mbgl::CameraOptions cameraOptions; if (angle != -1) { @@ -1718,20 +1271,20 @@ void nativeFlyTo(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jdouble angle nativeMapView->getMap().flyTo(cameraOptions, animationOptions); } -void nativeAddCustomLayer(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jobject customLayer, jstring before) { +void nativeAddCustomLayer(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jni::jobject* customLayer, jni::jstring* before) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeAddCustomLayer"); assert(nativeMapViewPtr != 0); NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); nativeMapView->getMap().addCustomLayer( - std_string_from_jstring(env, reinterpret_cast(env->GetObjectField(customLayer, customLayerIdId))), - reinterpret_cast(env->GetLongField(customLayer, customLayerInitializeFunctionId)), - reinterpret_cast(env->GetLongField(customLayer, customLayerRenderFunctionId)), - reinterpret_cast(env->GetLongField(customLayer, customLayerDeinitializeFunctionId)), - reinterpret_cast(env->GetLongField(customLayer, customLayerContextId)), + std_string_from_jstring(env, reinterpret_cast(jni::GetField(*env, customLayer, *customLayerIdId))), + reinterpret_cast(jni::GetField(*env, customLayer, *customLayerInitializeFunctionId)), + reinterpret_cast(jni::GetField(*env, customLayer, *customLayerRenderFunctionId)), + reinterpret_cast(jni::GetField(*env, customLayer, *customLayerDeinitializeFunctionId)), + reinterpret_cast(jni::GetField(*env, customLayer, *customLayerContextId)), before ? std_string_from_jstring(env, before).c_str() : nullptr); } -void nativeRemoveCustomLayer(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jstring id) { +void nativeRemoveCustomLayer(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jni::jstring* id) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeRemoveCustomLayer"); assert(nativeMapViewPtr != 0); NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); @@ -1740,7 +1293,7 @@ void nativeRemoveCustomLayer(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, j // Offline calls begin -jlong createDefaultFileSource(JNIEnv *env, jobject obj, jstring cachePath_, jstring assetRoot_, jlong maximumCacheSize) { +jlong createDefaultFileSource(JNIEnv *env, jni::jobject* obj, jni::jstring* cachePath_, jni::jstring* assetRoot_, jlong maximumCacheSize) { mbgl::Log::Debug(mbgl::Event::JNI, "createDefaultFileSource"); std::string cachePath = std_string_from_jstring(env, cachePath_); std::string assetRoot = std_string_from_jstring(env, assetRoot_); @@ -1749,7 +1302,7 @@ jlong createDefaultFileSource(JNIEnv *env, jobject obj, jstring cachePath_, jstr return defaultFileSourcePtr; } -void setAccessToken(JNIEnv *env, jobject obj, jlong defaultFileSourcePtr, jstring accessToken_) { +void setAccessToken(JNIEnv *env, jni::jobject* obj, jlong defaultFileSourcePtr, jni::jstring* accessToken_) { mbgl::Log::Debug(mbgl::Event::JNI, "setAccessToken"); assert(defaultFileSourcePtr != 0); std::string accessToken = std_string_from_jstring(env, accessToken_); @@ -1757,7 +1310,7 @@ void setAccessToken(JNIEnv *env, jobject obj, jlong defaultFileSourcePtr, jstrin defaultFileSource->setAccessToken(accessToken); } -jstring getAccessToken(JNIEnv *env, jobject obj, jlong defaultFileSourcePtr) { +jni::jstring* getAccessToken(JNIEnv *env, jni::jobject* obj, jlong defaultFileSourcePtr) { mbgl::Log::Debug(mbgl::Event::JNI, "getAccessToken"); assert(defaultFileSourcePtr != 0); mbgl::DefaultFileSource *defaultFileSource = reinterpret_cast(defaultFileSourcePtr); @@ -1765,23 +1318,20 @@ jstring getAccessToken(JNIEnv *env, jobject obj, jlong defaultFileSourcePtr) { return std_string_to_jstring(env, accessToken); } -void listOfflineRegions(JNIEnv *env, jobject obj, jlong defaultFileSourcePtr, jobject listCallback) { +void listOfflineRegions(JNIEnv *env, jni::jobject* obj, jlong defaultFileSourcePtr, jni::jobject* listCallback) { mbgl::Log::Debug(mbgl::Event::JNI, "listOfflineRegions"); // Checks assert(defaultFileSourcePtr != 0); - if (listCallback == nullptr) { - mbgl::Log::Error(mbgl::Event::JNI, "Callback has to be set."); - return; - } + NullCheck(*env, listCallback); // Makes sure the objects don't get GC'ed - obj = reinterpret_cast(env->NewGlobalRef(obj)); - listCallback = reinterpret_cast(env->NewGlobalRef(listCallback)); + obj = jni::NewGlobalRef(*env, obj).release(); + listCallback = jni::NewGlobalRef(*env, listCallback).release(); // Launch listCallback mbgl::DefaultFileSource *defaultFileSource = reinterpret_cast(defaultFileSourcePtr); - defaultFileSource->listOfflineRegions([obj, defaultFileSourcePtr, listCallback](std::exception_ptr error, mbgl::optional> regions) { + defaultFileSource->listOfflineRegions([obj, defaultFileSourcePtr, listCallback](std::exception_ptr error, mbgl::optional> regions) mutable { // Reattach, the callback comes from a different thread JNIEnv *env2; @@ -1792,67 +1342,65 @@ void listOfflineRegions(JNIEnv *env, jobject obj, jlong defaultFileSourcePtr, jo if (error) { std::string message = mbgl::util::toString(error); - env2->CallVoidMethod(listCallback, listOnErrorMethodId, std_string_to_jstring(env2, message)); + jni::CallMethod(*env2, listCallback, *listOnErrorMethodId, std_string_to_jstring(env2, message)); } else if (regions) { - // Build jobjectArray - jsize index = 0; - jobjectArray jregions = env2->NewObjectArray(regions->size(), offlineRegionClass, NULL); + // Build jni::jarray* + std::size_t index = 0; + jni::jarray* jregions = &jni::NewObjectArray(*env2, regions->size(), *offlineRegionClass, NULL); for (auto& region : *regions) { // Build the Region object - jobject jregion = env2->NewObject(offlineRegionClass, offlineRegionConstructorId); - env2->SetObjectField(jregion, offlineRegionOfflineManagerId, obj); - env2->SetLongField(jregion, offlineRegionIdId, region.getID()); + jni::jobject* jregion = &jni::NewObject(*env2, *offlineRegionClass, *offlineRegionConstructorId); + jni::SetField(*env2, jregion, *offlineRegionOfflineManagerId, obj); + jni::SetField(*env2, jregion, *offlineRegionIdId, region.getID()); + // Definition object mbgl::OfflineTilePyramidRegionDefinition definition = region.getDefinition(); - jobject jdefinition = env2->NewObject(offlineRegionDefinitionClass, offlineRegionDefinitionConstructorId); - env2->SetObjectField(jdefinition, offlineRegionDefinitionStyleURLId, std_string_to_jstring(env2, definition.styleURL)); - env2->SetObjectField(jdefinition, offlineRegionDefinitionBoundsId, latlngbounds_from_native(env2, definition.bounds)); - env2->SetDoubleField(jdefinition, offlineRegionDefinitionMinZoomId, definition.minZoom); - env2->SetDoubleField(jdefinition, offlineRegionDefinitionMaxZoomId, definition.maxZoom); - env2->SetFloatField(jdefinition, offlineRegionDefinitionPixelRatioId, definition.pixelRatio); - env2->SetObjectField(jregion, offlineRegionDefinitionId, jdefinition); + jni::jobject* jdefinition = &jni::NewObject(*env2, *offlineRegionDefinitionClass, *offlineRegionDefinitionConstructorId); + jni::SetField(*env2, jdefinition, *offlineRegionDefinitionStyleURLId, std_string_to_jstring(env2, definition.styleURL)); + jni::SetField(*env2, jdefinition, *offlineRegionDefinitionBoundsId, latlngbounds_from_native(env2, definition.bounds)); + jni::SetField(*env2, jdefinition, *offlineRegionDefinitionMinZoomId, definition.minZoom); + jni::SetField(*env2, jdefinition, *offlineRegionDefinitionMaxZoomId, definition.maxZoom); + jni::SetField(*env2, jdefinition, *offlineRegionDefinitionPixelRatioId, definition.pixelRatio); + jni::SetField(*env2, jregion, *offlineRegionDefinitionId, jdefinition); // Metadata object - jbyteArray metadata = metadata_from_native(env2, region.getMetadata()); - env2->SetObjectField(jregion, offlineRegionMetadataId, metadata); + jni::jarray* metadata = metadata_from_native(env2, region.getMetadata()); + jni::SetField(*env2, jregion, *offlineRegionMetadataId, metadata); // Moves the region on the stack into a heap-allocated one - env2->SetLongField(jregion, offlineRegionPtrId, + jni::SetField(*env2, jregion, *offlineRegionPtrId, reinterpret_cast(new mbgl::OfflineRegion(std::move(region)))); - env2->SetObjectArrayElement(jregions, index, jregion); + jni::SetObjectArrayElement(*env2, *jregions, index, jregion); index++; } // Trigger callback - env2->CallVoidMethod(listCallback, listOnListMethodId, jregions); + jni::CallMethod(*env2, listCallback, *listOnListMethodId, jregions); } // Delete global refs and detach when we're done - env2->DeleteGlobalRef(obj); - env2->DeleteGlobalRef(listCallback); + jni::DeleteGlobalRef(*env2, jni::UniqueGlobalRef(obj)); + jni::DeleteGlobalRef(*env2, jni::UniqueGlobalRef(listCallback)); detach_jni_thread(theJVM, &env2, renderDetach); }); } -void createOfflineRegion(JNIEnv *env, jobject obj, jlong defaultFileSourcePtr, jobject definition_, jbyteArray metadata_, jobject createCallback) { +void createOfflineRegion(JNIEnv *env, jni::jobject* obj, jlong defaultFileSourcePtr, jni::jobject* definition_, jni::jarray* metadata_, jni::jobject* createCallback) { mbgl::Log::Debug(mbgl::Event::JNI, "createOfflineRegion"); // Checks assert(defaultFileSourcePtr != 0); - if (createCallback == nullptr) { - mbgl::Log::Error(mbgl::Event::JNI, "Callback has to be set."); - return; - } + NullCheck(*env, createCallback); // Definition fields - jstring jStyleURL = reinterpret_cast(env->GetObjectField(definition_, offlineRegionDefinitionStyleURLId)); + jni::jstring* jStyleURL = reinterpret_cast(jni::GetField(*env, definition_, *offlineRegionDefinitionStyleURLId)); std::string styleURL = std_string_from_jstring(env, jStyleURL); - jobject jBounds = env->GetObjectField(definition_, offlineRegionDefinitionBoundsId); - jdouble jMinZoom = env->GetDoubleField(definition_, offlineRegionDefinitionMinZoomId); - jdouble jMaxZoom = env->GetDoubleField(definition_, offlineRegionDefinitionMaxZoomId); - jfloat jPixelRatio = env->GetFloatField(definition_, offlineRegionDefinitionPixelRatioId); + jni::jobject* jBounds = jni::GetField(*env, definition_, *offlineRegionDefinitionBoundsId); + jdouble jMinZoom = jni::GetField(*env, definition_, *offlineRegionDefinitionMinZoomId); + jdouble jMaxZoom = jni::GetField(*env, definition_, *offlineRegionDefinitionMaxZoomId); + jfloat jPixelRatio = jni::GetField(*env, definition_, *offlineRegionDefinitionPixelRatioId); // Convert bounds fields to native mbgl::LatLngBounds bounds = latlngbounds_from_java(env, jBounds); @@ -1863,16 +1411,16 @@ void createOfflineRegion(JNIEnv *env, jobject obj, jlong defaultFileSourcePtr, j // Metadata mbgl::OfflineRegionMetadata metadata; if (metadata_ != nullptr) { - metadata = metadata_from_java(env, metadata_); + metadata = metadata_from_java(env, *metadata_); } // Makes sure the objects don't get GC'ed - obj = reinterpret_cast(env->NewGlobalRef(obj)); - createCallback = reinterpret_cast(env->NewGlobalRef(createCallback)); + obj = jni::NewGlobalRef(*env, obj).release(); + createCallback = jni::NewGlobalRef(*env, createCallback).release(); // Launch createCallback mbgl::DefaultFileSource *defaultFileSource = reinterpret_cast(defaultFileSourcePtr); - defaultFileSource->createOfflineRegion(definition, metadata, [obj, defaultFileSourcePtr, createCallback] (std::exception_ptr error, mbgl::optional region) { + defaultFileSource->createOfflineRegion(definition, metadata, [obj, defaultFileSourcePtr, createCallback] (std::exception_ptr error, mbgl::optional region) mutable { // Reattach, the callback comes from a different thread JNIEnv *env2; @@ -1883,33 +1431,33 @@ void createOfflineRegion(JNIEnv *env, jobject obj, jlong defaultFileSourcePtr, j if (error) { std::string message = mbgl::util::toString(error); - env2->CallVoidMethod(createCallback, createOnErrorMethodId, std_string_to_jstring(env2, message)); + jni::CallMethod(*env2, createCallback, *createOnErrorMethodId, std_string_to_jstring(env2, message)); } else if (region) { // Build the Region object - jobject jregion = env2->NewObject(offlineRegionClass, offlineRegionConstructorId); - env2->SetObjectField(jregion, offlineRegionOfflineManagerId, obj); - env2->SetLongField(jregion, offlineRegionIdId, region->getID()); + jni::jobject* jregion = &jni::NewObject(*env2, *offlineRegionClass, *offlineRegionConstructorId); + jni::SetField(*env2, jregion, *offlineRegionOfflineManagerId, obj); + jni::SetField(*env2, jregion, *offlineRegionIdId, region->getID()); // Metadata object - jbyteArray jmetadata = metadata_from_native(env2, region->getMetadata()); - env2->SetObjectField(jregion, offlineRegionMetadataId, jmetadata); + jni::jarray* jmetadata = metadata_from_native(env2, region->getMetadata()); + jni::SetField(*env2, jregion, *offlineRegionMetadataId, jmetadata); // Moves the region on the stack into a heap-allocated one - env2->SetLongField(jregion, offlineRegionPtrId, + jni::SetField(*env2, jregion, *offlineRegionPtrId, reinterpret_cast(new mbgl::OfflineRegion(std::move(*region)))); // Invoke Java callback - env2->CallVoidMethod(createCallback, createOnCreateMethodId, jregion); + jni::CallMethod(*env2, createCallback, *createOnCreateMethodId, jregion); } // Delete global refs and detach when we're done - env2->DeleteGlobalRef(obj); - env2->DeleteGlobalRef(createCallback); + jni::DeleteGlobalRef(*env2, jni::UniqueGlobalRef(obj)); + jni::DeleteGlobalRef(*env2, jni::UniqueGlobalRef(createCallback)); detach_jni_thread(theJVM, &env2, renderDetach); }); } -void setOfflineMapboxTileCountLimit(JNIEnv *env, jobject obj, jlong defaultFileSourcePtr, jlong limit) { +void setOfflineMapboxTileCountLimit(JNIEnv *env, jni::jobject* obj, jlong defaultFileSourcePtr, jlong limit) { mbgl::Log::Debug(mbgl::Event::JNI, "setOfflineMapboxTileCountLimit"); // Checks @@ -1921,7 +1469,7 @@ void setOfflineMapboxTileCountLimit(JNIEnv *env, jobject obj, jlong defaultFileS defaultFileSource->setOfflineMapboxTileCountLimit(limit); } -void destroyOfflineRegion(JNIEnv *env, jobject obj, jlong offlineRegionPtr) { +void destroyOfflineRegion(JNIEnv *env, jni::jobject* obj, jlong offlineRegionPtr) { mbgl::Log::Debug(mbgl::Event::JNI, "destroyOfflineRegion"); assert(offlineRegionPtr != 0); mbgl::OfflineRegion *offlineRegion = reinterpret_cast(offlineRegionPtr); @@ -1929,22 +1477,22 @@ void destroyOfflineRegion(JNIEnv *env, jobject obj, jlong offlineRegionPtr) { offlineRegion = nullptr; } -void setOfflineRegionObserver(JNIEnv *env, jobject obj, jobject offlineRegion_, jobject observerCallback) { +void setOfflineRegionObserver(JNIEnv *env, jni::jobject* obj, jni::jobject* offlineRegion_, jni::jobject* observerCallback) { mbgl::Log::Debug(mbgl::Event::JNI, "setOfflineRegionObserver"); // Offline region - jlong offlineRegionPtr = env->GetLongField(offlineRegion_, offlineRegionPtrId); + jlong offlineRegionPtr = jni::GetField(*env, offlineRegion_, *offlineRegionPtrId); mbgl::OfflineRegion *offlineRegion = reinterpret_cast(offlineRegionPtr); // File source - jobject jmanager = env->GetObjectField(offlineRegion_, offlineRegionOfflineManagerId); - jlong defaultFileSourcePtr = env->GetLongField(jmanager, offlineManagerClassPtrId); + jni::jobject* jmanager = jni::GetField(*env, offlineRegion_, *offlineRegionOfflineManagerId); + jlong defaultFileSourcePtr = jni::GetField(*env, jmanager, *offlineManagerClassPtrId); mbgl::DefaultFileSource *defaultFileSource = reinterpret_cast(defaultFileSourcePtr); // Define the observer class Observer : public mbgl::OfflineRegionObserver { public: - Observer(jobject observerCallback_) + Observer(jni::jobject* observerCallback_) : observerCallback(observerCallback_) { } @@ -1965,19 +1513,19 @@ void setOfflineRegionObserver(JNIEnv *env, jobject obj, jobject offlineRegion_, } // Stats object - jobject jstatus = env2->NewObject(offlineRegionStatusClass, offlineRegionStatusConstructorId); - env2->SetIntField(jstatus, offlineRegionStatusDownloadStateId, downloadState); - env2->SetLongField(jstatus, offlineRegionStatusCompletedResourceCountId, status.completedResourceCount); - env2->SetLongField(jstatus, offlineRegionStatusCompletedResourceSizeId, status.completedResourceSize); - env2->SetLongField(jstatus, offlineRegionStatusRequiredResourceCountId, status.requiredResourceCount); - env2->SetBooleanField(jstatus, offlineRegionStatusRequiredResourceCountIsPreciseId, status.requiredResourceCountIsPrecise); - env2->CallVoidMethod(observerCallback, offlineRegionObserveronStatusChangedId, jstatus); + jni::jobject* jstatus = &jni::NewObject(*env2, *offlineRegionStatusClass, *offlineRegionStatusConstructorId); + jni::SetField(*env2, jstatus, *offlineRegionStatusDownloadStateId, downloadState); + jni::SetField(*env2, jstatus, *offlineRegionStatusCompletedResourceCountId, status.completedResourceCount); + jni::SetField(*env2, jstatus, *offlineRegionStatusCompletedResourceSizeId, status.completedResourceSize); + jni::SetField(*env2, jstatus, *offlineRegionStatusRequiredResourceCountId, status.requiredResourceCount); + jni::SetField(*env2, jstatus, *offlineRegionStatusRequiredResourceCountIsPreciseId, status.requiredResourceCountIsPrecise); + jni::CallMethod(*env2, observerCallback, *offlineRegionObserveronStatusChangedId, jstatus); // Detach when we're done detach_jni_thread(theJVM, &env2, renderDetach); } - void responseError(mbgl::Response::Error error) override { + void responseError(mbgl::Response::Error error) override { // Env JNIEnv* env2; jboolean renderDetach = attach_jni_thread(theJVM, &env2, "Offline Thread"); @@ -2003,10 +1551,10 @@ void setOfflineRegionObserver(JNIEnv *env, jobject obj, jobject offlineRegion_, } // Error object - jobject jerror = env2->NewObject(offlineRegionErrorClass, offlineRegionErrorConstructorId); - env2->SetObjectField(jerror, offlineRegionErrorReasonId, std_string_to_jstring(env2, errorReason)); - env2->SetObjectField(jerror, offlineRegionErrorMessageId, std_string_to_jstring(env2, error.message)); - env2->CallVoidMethod(observerCallback, offlineRegionObserveronErrorId, jerror); + jni::jobject* jerror = &jni::NewObject(*env2, *offlineRegionErrorClass, *offlineRegionErrorConstructorId); + jni::SetField(*env2, jerror, *offlineRegionErrorReasonId, std_string_to_jstring(env2, errorReason)); + jni::SetField(*env2, jerror, *offlineRegionErrorMessageId, std_string_to_jstring(env2, error.message)); + jni::CallMethod(*env2, observerCallback, *offlineRegionObserveronErrorId, jerror); // Detach when we're done detach_jni_thread(theJVM, &env2, renderDetach); @@ -2018,23 +1566,23 @@ void setOfflineRegionObserver(JNIEnv *env, jobject obj, jobject offlineRegion_, jboolean renderDetach = attach_jni_thread(theJVM, &env2, "Offline Thread"); // Send limit - env2->CallVoidMethod(observerCallback, offlineRegionObserveronLimitId, limit); + jni::CallMethod(*env2, observerCallback, *offlineRegionObserveronLimitId, jlong(limit)); // Detach when we're done - detach_jni_thread(theJVM, &env2, renderDetach); + detach_jni_thread(theJVM, &env2, renderDetach); } - jobject observerCallback; + jni::jobject* observerCallback; }; // Makes sure the callback doesn't get GC'ed - observerCallback = reinterpret_cast(env->NewGlobalRef(observerCallback)); + observerCallback = jni::NewGlobalRef(*env, observerCallback).release(); // Set the observer defaultFileSource->setOfflineRegionObserver(*offlineRegion, std::make_unique(observerCallback)); } -void setOfflineRegionDownloadState(JNIEnv *env, jobject obj, jobject offlineRegion_, jint offlineRegionDownloadState) { +void setOfflineRegionDownloadState(JNIEnv *env, jni::jobject* obj, jni::jobject* offlineRegion_, jint offlineRegionDownloadState) { mbgl::Log::Debug(mbgl::Event::JNI, "setOfflineRegionDownloadState"); // State @@ -2049,35 +1597,35 @@ void setOfflineRegionDownloadState(JNIEnv *env, jobject obj, jobject offlineRegi } // Offline region - jlong offlineRegionPtr = env->GetLongField(offlineRegion_, offlineRegionPtrId); + jlong offlineRegionPtr = jni::GetField(*env, offlineRegion_, *offlineRegionPtrId); mbgl::OfflineRegion *offlineRegion = reinterpret_cast(offlineRegionPtr); // File source - jobject jmanager = env->GetObjectField(offlineRegion_, offlineRegionOfflineManagerId); - jlong defaultFileSourcePtr = env->GetLongField(jmanager, offlineManagerClassPtrId); + jni::jobject* jmanager = jni::GetField(*env, offlineRegion_, *offlineRegionOfflineManagerId); + jlong defaultFileSourcePtr = jni::GetField(*env, jmanager, *offlineManagerClassPtrId); mbgl::DefaultFileSource *defaultFileSource = reinterpret_cast(defaultFileSourcePtr); // Set new state defaultFileSource->setOfflineRegionDownloadState(*offlineRegion, state); } -void getOfflineRegionStatus(JNIEnv *env, jobject obj, jobject offlineRegion_, jobject statusCallback) { +void getOfflineRegionStatus(JNIEnv *env, jni::jobject* obj, jni::jobject* offlineRegion_, jni::jobject* statusCallback) { mbgl::Log::Debug(mbgl::Event::JNI, "getOfflineRegionStatus"); // Offline region - jlong offlineRegionPtr = env->GetLongField(offlineRegion_, offlineRegionPtrId); + jlong offlineRegionPtr = jni::GetField(*env, offlineRegion_, *offlineRegionPtrId); mbgl::OfflineRegion *offlineRegion = reinterpret_cast(offlineRegionPtr); // File source - jobject jmanager = env->GetObjectField(offlineRegion_, offlineRegionOfflineManagerId); - jlong defaultFileSourcePtr = env->GetLongField(jmanager, offlineManagerClassPtrId); + jni::jobject* jmanager = jni::GetField(*env, offlineRegion_, *offlineRegionOfflineManagerId); + jlong defaultFileSourcePtr = jni::GetField(*env, jmanager, *offlineManagerClassPtrId); mbgl::DefaultFileSource *defaultFileSource = reinterpret_cast(defaultFileSourcePtr); // Makes sure the callback doesn't get GC'ed - statusCallback = reinterpret_cast(env->NewGlobalRef(statusCallback)); + statusCallback = jni::NewGlobalRef(*env, statusCallback).release(); // Set new state - defaultFileSource->getOfflineRegionStatus(*offlineRegion, [statusCallback](std::exception_ptr error, mbgl::optional status) { + defaultFileSource->getOfflineRegionStatus(*offlineRegion, [statusCallback](std::exception_ptr error, mbgl::optional status) mutable { // Reattach, the callback comes from a different thread JNIEnv *env2; @@ -2088,7 +1636,7 @@ void getOfflineRegionStatus(JNIEnv *env, jobject obj, jobject offlineRegion_, jo if (error) { std::string message = mbgl::util::toString(error); - env2->CallVoidMethod(statusCallback, offlineRegionStatusOnErrorId, std_string_to_jstring(env2, message)); + jni::CallMethod(*env2, statusCallback, *offlineRegionStatusOnErrorId, std_string_to_jstring(env2, message)); } else if (status) { // Conver to jint jint downloadState = -1; @@ -2102,38 +1650,38 @@ void getOfflineRegionStatus(JNIEnv *env, jobject obj, jobject offlineRegion_, jo } // Stats object - jobject jstatus = env2->NewObject(offlineRegionStatusClass, offlineRegionStatusConstructorId); - env2->SetIntField(jstatus, offlineRegionStatusDownloadStateId, downloadState); - env2->SetLongField(jstatus, offlineRegionStatusCompletedResourceCountId, status->completedResourceCount); - env2->SetLongField(jstatus, offlineRegionStatusCompletedResourceSizeId, status->completedResourceSize); - env2->SetLongField(jstatus, offlineRegionStatusRequiredResourceCountId, status->requiredResourceCount); - env2->SetBooleanField(jstatus, offlineRegionStatusRequiredResourceCountIsPreciseId, status->requiredResourceCountIsPrecise); - env2->CallVoidMethod(statusCallback, offlineRegionStatusOnStatusId, jstatus); + jni::jobject* jstatus = &jni::NewObject(*env2, *offlineRegionStatusClass, *offlineRegionStatusConstructorId); + jni::SetField(*env2, jstatus, *offlineRegionStatusDownloadStateId, downloadState); + jni::SetField(*env2, jstatus, *offlineRegionStatusCompletedResourceCountId, status->completedResourceCount); + jni::SetField(*env2, jstatus, *offlineRegionStatusCompletedResourceSizeId, status->completedResourceSize); + jni::SetField(*env2, jstatus, *offlineRegionStatusRequiredResourceCountId, status->requiredResourceCount); + jni::SetField(*env2, jstatus, *offlineRegionStatusRequiredResourceCountIsPreciseId, status->requiredResourceCountIsPrecise); + jni::CallMethod(*env2, statusCallback, *offlineRegionStatusOnStatusId, jstatus); } // Delete global refs and detach when we're done - env2->DeleteGlobalRef(statusCallback); + jni::DeleteGlobalRef(*env2, jni::UniqueGlobalRef(statusCallback)); detach_jni_thread(theJVM, &env2, renderDetach); }); } -void deleteOfflineRegion(JNIEnv *env, jobject obj, jobject offlineRegion_, jobject deleteCallback) { +void deleteOfflineRegion(JNIEnv *env, jni::jobject* obj, jni::jobject* offlineRegion_, jni::jobject* deleteCallback) { mbgl::Log::Debug(mbgl::Event::JNI, "deleteOfflineRegion"); // Offline region - jlong offlineRegionPtr = env->GetLongField(offlineRegion_, offlineRegionPtrId); + jlong offlineRegionPtr = jni::GetField(*env, offlineRegion_, *offlineRegionPtrId); mbgl::OfflineRegion *offlineRegion = reinterpret_cast(offlineRegionPtr); // File source - jobject jmanager = env->GetObjectField(offlineRegion_, offlineRegionOfflineManagerId); - jlong defaultFileSourcePtr = env->GetLongField(jmanager, offlineManagerClassPtrId); + jni::jobject* jmanager = jni::GetField(*env, offlineRegion_, *offlineRegionOfflineManagerId); + jlong defaultFileSourcePtr = jni::GetField(*env, jmanager, *offlineManagerClassPtrId); mbgl::DefaultFileSource *defaultFileSource = reinterpret_cast(defaultFileSourcePtr); // Makes sure the callback doesn't get GC'ed - deleteCallback = reinterpret_cast(env->NewGlobalRef(deleteCallback)); + deleteCallback = jni::NewGlobalRef(*env, deleteCallback).release(); // Set new state - defaultFileSource->deleteOfflineRegion(std::move(*offlineRegion), [deleteCallback](std::exception_ptr error) { + defaultFileSource->deleteOfflineRegion(std::move(*offlineRegion), [deleteCallback](std::exception_ptr error) mutable { // Reattach, the callback comes from a different thread JNIEnv *env2; @@ -2144,14 +1692,14 @@ void deleteOfflineRegion(JNIEnv *env, jobject obj, jobject offlineRegion_, jobje if (error) { std::string message = mbgl::util::toString(error); - env2->CallVoidMethod(deleteCallback, offlineRegionDeleteOnErrorId, std_string_to_jstring(env2, message)); + jni::CallMethod(*env2, deleteCallback, *offlineRegionDeleteOnErrorId, std_string_to_jstring(env2, message)); } else { std::string message = mbgl::util::toString(error); - env2->CallVoidMethod(deleteCallback, offlineRegionDeleteOnDeleteId); + jni::CallMethod(*env2, deleteCallback, *offlineRegionDeleteOnDeleteId); } // Delete global refs and detach when we're done - env2->DeleteGlobalRef(deleteCallback); + jni::DeleteGlobalRef(*env2, jni::UniqueGlobalRef(deleteCallback)); detach_jni_thread(theJVM, &env2, renderDetach); }); } @@ -2160,1151 +1708,273 @@ void deleteOfflineRegion(JNIEnv *env, jobject obj, jobject offlineRegion_, jobje } -extern "C" { - extern "C" JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved) { - // This reads out values from objects - mbgl::Log::Debug(mbgl::Event::JNI, "JNI_OnLoad"); - theJVM = vm; - JNIEnv *env = nullptr; - jint ret = vm->GetEnv(reinterpret_cast(&env), JNI_VERSION_1_6); - if (ret != JNI_OK) { - mbgl::Log::Error(mbgl::Event::JNI, "GetEnv() failed with %i", ret); - return JNI_ERR; - } - - mbgl::android::RegisterNativeHTTPRequest(*env); - - latLngClass = env->FindClass("com/mapbox/mapboxsdk/geometry/LatLng"); - if (latLngClass == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - latLngConstructorId = env->GetMethodID(latLngClass, "", "(DD)V"); - if (latLngConstructorId == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - latLngLatitudeId = env->GetFieldID(latLngClass, "latitude", "D"); - if (latLngLatitudeId == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - latLngLongitudeId = env->GetFieldID(latLngClass, "longitude", "D"); - if (latLngLongitudeId == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - latLngBoundsClass = env->FindClass("com/mapbox/mapboxsdk/geometry/LatLngBounds"); - if (latLngBoundsClass == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - latLngBoundsConstructorId = env->GetMethodID(latLngBoundsClass, "", "(DDDD)V"); - if (latLngBoundsConstructorId == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - latLngBoundsLatNorthId = env->GetFieldID(latLngBoundsClass, "mLatNorth", "D"); - if (latLngBoundsLatNorthId == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - latLngBoundsLatSouthId = env->GetFieldID(latLngBoundsClass, "mLatSouth", "D"); - if (latLngBoundsLatSouthId == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - latLngBoundsLonEastId = env->GetFieldID(latLngBoundsClass, "mLonEast", "D"); - if (latLngBoundsLonEastId == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - latLngBoundsLonWestId = env->GetFieldID(latLngBoundsClass, "mLonWest", "D"); - if (latLngBoundsLonWestId == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - iconClass = env->FindClass("com/mapbox/mapboxsdk/annotations/Icon"); - if (iconClass == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - iconIdId = env->GetFieldID(iconClass, "mId", "Ljava/lang/String;"); - if (iconIdId == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - markerClass = env->FindClass("com/mapbox/mapboxsdk/annotations/Marker"); - if (markerClass == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - markerPositionId = env->GetFieldID(markerClass, "position", "Lcom/mapbox/mapboxsdk/geometry/LatLng;"); - if (markerPositionId == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - markerIconId = env->GetFieldID(markerClass, "icon", "Lcom/mapbox/mapboxsdk/annotations/Icon;"); - if (markerIconId == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - markerIdId = env->GetFieldID(markerClass, "id", "J"); - if (markerIdId == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - polylineClass = env->FindClass("com/mapbox/mapboxsdk/annotations/Polyline"); - if (polylineClass == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - polylineAlphaId = env->GetFieldID(polylineClass, "alpha", "F"); - if (polylineAlphaId == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - polylineColorId = env->GetFieldID(polylineClass, "color", "I"); - if (polylineColorId == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - polylineWidthId = env->GetFieldID(polylineClass, "width", "F"); - if (polylineWidthId == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - polylinePointsId = env->GetFieldID(polylineClass, "points", "Ljava/util/List;"); - if (polylineWidthId == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - polygonClass = env->FindClass("com/mapbox/mapboxsdk/annotations/Polygon"); - if (polygonClass == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - polygonAlphaId = env->GetFieldID(polygonClass, "alpha", "F"); - if (polygonAlphaId == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - polygonFillColorId = env->GetFieldID(polygonClass, "fillColor", "I"); - if (polygonFillColorId == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - polygonStrokeColorId = env->GetFieldID(polygonClass, "strokeColor", "I"); - if (polygonStrokeColorId == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - polygonPointsId = env->GetFieldID(polygonClass, "points", "Ljava/util/List;"); - if (polygonPointsId == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - jclass nativeMapViewClass = env->FindClass("com/mapbox/mapboxsdk/maps/NativeMapView"); - if (nativeMapViewClass == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - onInvalidateId = env->GetMethodID(nativeMapViewClass, "onInvalidate", "()V"); - if (onInvalidateId == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - onMapChangedId = env->GetMethodID(nativeMapViewClass, "onMapChanged", "(I)V"); - if (onMapChangedId == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - onFpsChangedId = env->GetMethodID(nativeMapViewClass, "onFpsChanged", "(D)V"); - if (onFpsChangedId == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - runtimeExceptionClass = env->FindClass("java/lang/RuntimeException"); - if (runtimeExceptionClass == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - nullPointerExceptionClass = env->FindClass("java/lang/NullPointerException"); - if (nullPointerExceptionClass == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - jclass listClass = env->FindClass("java/util/List"); - if (listClass == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - listToArrayId = env->GetMethodID(listClass, "toArray", "()[Ljava/lang/Object;"); - if (listToArrayId == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - arrayListClass = env->FindClass("java/util/ArrayList"); - if (arrayListClass == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - arrayListConstructorId = env->GetMethodID(arrayListClass, "", "()V"); - if (arrayListConstructorId == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - arrayListAddId = env->GetMethodID(arrayListClass, "add", "(Ljava/lang/Object;)Z"); - if (arrayListAddId == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - projectedMetersClass = env->FindClass("com/mapbox/mapboxsdk/geometry/ProjectedMeters"); - if (projectedMetersClass == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - projectedMetersConstructorId = env->GetMethodID(projectedMetersClass, "", "(DD)V"); - if (projectedMetersConstructorId == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - projectedMetersNorthingId = env->GetFieldID(projectedMetersClass, "northing", "D"); - if (projectedMetersNorthingId == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - projectedMetersEastingId = env->GetFieldID(projectedMetersClass, "easting", "D"); - if (projectedMetersEastingId == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - pointFClass = env->FindClass("android/graphics/PointF"); - if (pointFClass == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - pointFConstructorId = env->GetMethodID(pointFClass, "", "(FF)V"); - if (pointFConstructorId == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - pointFXId = env->GetFieldID(pointFClass, "x", "F"); - if (pointFXId == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - pointFYId = env->GetFieldID(pointFClass, "y", "F"); - if (pointFYId == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - rectFClass = env->FindClass("android/graphics/RectF"); - if (rectFClass == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - rectFConstructorId = env->GetMethodID(rectFClass, "", "()V"); - if (rectFConstructorId == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - rectFLeftId = env->GetFieldID(rectFClass, "left", "F"); - if (rectFLeftId == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - rectFRightId = env->GetFieldID(rectFClass, "right", "F"); - if (rectFRightId == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - rectFTopId = env->GetFieldID(rectFClass, "top", "F"); - if (rectFTopId == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - rectFBottomId = env->GetFieldID(rectFClass, "bottom", "F"); - if (rectFBottomId == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - customLayerClass = env->FindClass("com/mapbox/mapboxsdk/layers/CustomLayer"); - if (customLayerClass == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - customLayerIdId = env->GetFieldID(customLayerClass, "mID", "Ljava/lang/String;"); - if (customLayerIdId == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - customLayerContextId = env->GetFieldID(customLayerClass, "mContext", "J"); - if (customLayerContextId == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - customLayerInitializeFunctionId = env->GetFieldID(customLayerClass, "mInitializeFunction", "J"); - if (customLayerInitializeFunctionId == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - customLayerRenderFunctionId = env->GetFieldID(customLayerClass, "mRenderFunction", "J"); - if (customLayerRenderFunctionId == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - customLayerDeinitializeFunctionId = env->GetFieldID(customLayerClass, "mDeinitializeFunction", "J"); - if (customLayerDeinitializeFunctionId == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - // Offline definitions begin - - offlineManagerClass = env->FindClass("com/mapbox/mapboxsdk/offline/OfflineManager"); - if (offlineManagerClass == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - offlineManagerClassPtrId = env->GetFieldID(offlineManagerClass, "mDefaultFileSourcePtr", "J"); - if (offlineManagerClassPtrId == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - listOfflineRegionsCallbackClass = env->FindClass("com/mapbox/mapboxsdk/offline/OfflineManager$ListOfflineRegionsCallback"); - if (listOfflineRegionsCallbackClass == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - listOnListMethodId = env->GetMethodID(listOfflineRegionsCallbackClass, "onList", "([Lcom/mapbox/mapboxsdk/offline/OfflineRegion;)V"); - if (listOnListMethodId == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - listOnErrorMethodId = env->GetMethodID(listOfflineRegionsCallbackClass, "onError", "(Ljava/lang/String;)V"); - if (listOnErrorMethodId == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - offlineRegionClass = env->FindClass("com/mapbox/mapboxsdk/offline/OfflineRegion"); - if (offlineRegionClass == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - offlineRegionConstructorId = env->GetMethodID(offlineRegionClass, "", "()V"); - if (offlineRegionConstructorId == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - offlineRegionOfflineManagerId = env->GetFieldID(offlineRegionClass, "offlineManager", "Lcom/mapbox/mapboxsdk/offline/OfflineManager;"); - if (offlineRegionOfflineManagerId == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - offlineRegionIdId = env->GetFieldID(offlineRegionClass, "mId", "J"); - if (offlineRegionIdId == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - offlineRegionDefinitionId = env->GetFieldID(offlineRegionClass, "mDefinition", "Lcom/mapbox/mapboxsdk/offline/OfflineRegionDefinition;"); - if (offlineRegionDefinitionId == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - offlineRegionMetadataId = env->GetFieldID(offlineRegionClass, "mMetadata", "[B"); - if (offlineRegionMetadataId == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - offlineRegionPtrId = env->GetFieldID(offlineRegionClass, "mOfflineRegionPtr", "J"); - if (offlineRegionPtrId == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - // This needs to be updated once we support more than one type of region definition - offlineRegionDefinitionClass = env->FindClass("com/mapbox/mapboxsdk/offline/OfflineTilePyramidRegionDefinition"); - if (offlineRegionDefinitionClass == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - offlineRegionDefinitionConstructorId = env->GetMethodID(offlineRegionDefinitionClass, "", "()V"); - if (offlineRegionDefinitionConstructorId == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - offlineRegionDefinitionStyleURLId = env->GetFieldID(offlineRegionDefinitionClass, "styleURL", "Ljava/lang/String;"); - if (offlineRegionDefinitionStyleURLId == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - offlineRegionDefinitionBoundsId = env->GetFieldID(offlineRegionDefinitionClass, "bounds", "Lcom/mapbox/mapboxsdk/geometry/LatLngBounds;"); - if (offlineRegionDefinitionBoundsId == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - offlineRegionDefinitionMinZoomId = env->GetFieldID(offlineRegionDefinitionClass, "minZoom", "D"); - if (offlineRegionDefinitionMinZoomId == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - offlineRegionDefinitionMaxZoomId = env->GetFieldID(offlineRegionDefinitionClass, "maxZoom", "D"); - if (offlineRegionDefinitionMaxZoomId == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - offlineRegionDefinitionPixelRatioId = env->GetFieldID(offlineRegionDefinitionClass, "pixelRatio", "F"); - if (offlineRegionDefinitionPixelRatioId == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - createOfflineRegionCallbackClass = env->FindClass("com/mapbox/mapboxsdk/offline/OfflineManager$CreateOfflineRegionCallback"); - if (createOfflineRegionCallbackClass == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - createOnCreateMethodId = env->GetMethodID(createOfflineRegionCallbackClass, "onCreate", "(Lcom/mapbox/mapboxsdk/offline/OfflineRegion;)V"); - if (createOnCreateMethodId == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - createOnErrorMethodId = env->GetMethodID(createOfflineRegionCallbackClass, "onError", "(Ljava/lang/String;)V"); - if (createOnErrorMethodId == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - offlineRegionObserverClass = env->FindClass("com/mapbox/mapboxsdk/offline/OfflineRegion$OfflineRegionObserver"); - if (offlineRegionObserverClass == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - offlineRegionObserveronStatusChangedId = env->GetMethodID(offlineRegionObserverClass, "onStatusChanged", "(Lcom/mapbox/mapboxsdk/offline/OfflineRegionStatus;)V"); - if (offlineRegionObserveronStatusChangedId == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - offlineRegionObserveronErrorId = env->GetMethodID(offlineRegionObserverClass, "onError", "(Lcom/mapbox/mapboxsdk/offline/OfflineRegionError;)V"); - if (offlineRegionObserveronErrorId == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - offlineRegionObserveronLimitId = env->GetMethodID(offlineRegionObserverClass, "mapboxTileCountLimitExceeded", "(J)V"); - if (offlineRegionObserveronLimitId == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - offlineRegionStatusClass = env->FindClass("com/mapbox/mapboxsdk/offline/OfflineRegionStatus"); - if (offlineRegionStatusClass == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - offlineRegionStatusConstructorId = env->GetMethodID(offlineRegionStatusClass, "", "()V"); - if (offlineRegionStatusConstructorId == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - offlineRegionStatusDownloadStateId = env->GetFieldID(offlineRegionStatusClass, "downloadState", "I"); - if (offlineRegionStatusDownloadStateId == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - offlineRegionStatusCompletedResourceCountId = env->GetFieldID(offlineRegionStatusClass, "completedResourceCount", "J"); - if (offlineRegionStatusCompletedResourceCountId == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - offlineRegionStatusCompletedResourceSizeId = env->GetFieldID(offlineRegionStatusClass, "completedResourceSize", "J"); - if (offlineRegionStatusCompletedResourceSizeId == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - offlineRegionStatusRequiredResourceCountId = env->GetFieldID(offlineRegionStatusClass, "requiredResourceCount", "J"); - if (offlineRegionStatusRequiredResourceCountId == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - offlineRegionStatusRequiredResourceCountIsPreciseId = env->GetFieldID(offlineRegionStatusClass, "requiredResourceCountIsPrecise", "Z"); - if (offlineRegionStatusRequiredResourceCountIsPreciseId == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - offlineRegionErrorClass = env->FindClass("com/mapbox/mapboxsdk/offline/OfflineRegionError"); - if (offlineRegionErrorClass == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - offlineRegionErrorConstructorId = env->GetMethodID(offlineRegionErrorClass, "", "()V"); - if (offlineRegionErrorConstructorId == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - offlineRegionErrorReasonId = env->GetFieldID(offlineRegionErrorClass, "reason", "Ljava/lang/String;"); - if (offlineRegionErrorReasonId == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - offlineRegionErrorMessageId = env->GetFieldID(offlineRegionErrorClass, "message", "Ljava/lang/String;"); - if (offlineRegionErrorMessageId == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - offlineRegionStatusCallbackClass = env->FindClass("com/mapbox/mapboxsdk/offline/OfflineRegion$OfflineRegionStatusCallback"); - if (offlineRegionStatusCallbackClass == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - offlineRegionStatusOnStatusId = env->GetMethodID(offlineRegionStatusCallbackClass, "onStatus", "(Lcom/mapbox/mapboxsdk/offline/OfflineRegionStatus;)V"); - if (offlineRegionStatusOnStatusId == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - offlineRegionStatusOnErrorId = env->GetMethodID(offlineRegionStatusCallbackClass, "onError", "(Ljava/lang/String;)V"); - if (offlineRegionStatusOnErrorId == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - offlineRegionDeleteCallbackClass = env->FindClass("com/mapbox/mapboxsdk/offline/OfflineRegion$OfflineRegionDeleteCallback"); - if (offlineRegionDeleteCallbackClass == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - offlineRegionDeleteOnDeleteId = env->GetMethodID(offlineRegionDeleteCallbackClass, "onDelete", "()V"); - if (offlineRegionDeleteOnDeleteId == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - offlineRegionDeleteOnErrorId = env->GetMethodID(offlineRegionDeleteCallbackClass, "onError", "(Ljava/lang/String;)V"); - if (offlineRegionDeleteOnErrorId == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - // Offline definitions end - - const std::vector methods = { - {"nativeCreate", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;FIJ)J", - reinterpret_cast(&nativeCreate)}, - {"nativeDestroy", "(J)V", reinterpret_cast(&nativeDestroy)}, - {"nativeInitializeDisplay", "(J)V", reinterpret_cast(&nativeInitializeDisplay)}, - {"nativeTerminateDisplay", "(J)V", reinterpret_cast(&nativeTerminateDisplay)}, - {"nativeInitializeContext", "(J)V", reinterpret_cast(&nativeInitializeContext)}, - {"nativeTerminateContext", "(J)V", reinterpret_cast(&nativeTerminateContext)}, - {"nativeCreateSurface", "(JLandroid/view/Surface;)V", - reinterpret_cast(&nativeCreateSurface)}, - {"nativeDestroySurface", "(J)V", reinterpret_cast(&nativeDestroySurface)}, - {"nativePause", "(J)V", reinterpret_cast(&nativePause)}, - {"nativeIsPaused", "(J)Z", reinterpret_cast(&nativeIsPaused)}, - {"nativeResume", "(J)V", reinterpret_cast(&nativeResume)}, - {"nativeUpdate", "(J)V", reinterpret_cast(&nativeUpdate)}, - {"nativeRenderSync", "(J)V", reinterpret_cast(&nativeRenderSync)}, - {"nativeViewResize", "(JII)V", - reinterpret_cast(static_cast(&nativeViewResize))}, - {"nativeFramebufferResize", "(JII)V", - reinterpret_cast(static_cast(&nativeFramebufferResize))}, - {"nativeAddClass", "(JLjava/lang/String;)V", - reinterpret_cast(&nativeAddClass)}, - {"nativeRemoveClass", "(JLjava/lang/String;)V", - reinterpret_cast(&nativeRemoveClass)}, - {"nativeHasClass", "(JLjava/lang/String;)Z", - reinterpret_cast(&nativeHasClass)}, - {"nativeSetClasses", "(JLjava/util/List;)V", - reinterpret_cast(&nativeSetClasses)}, - {"nativeGetClasses", "(J)Ljava/util/List;", - reinterpret_cast(&nativeGetClasses)}, - {"nativeSetDefaultTransitionDuration", "(JJ)V", - reinterpret_cast(&nativeSetDefaultTransitionDuration)}, - {"nativeGetDefaultTransitionDuration", "(J)J", - reinterpret_cast(&nativeGetDefaultTransitionDuration)}, - {"nativeSetStyleUrl", "(JLjava/lang/String;)V", - reinterpret_cast(&nativeSetStyleURL)}, - {"nativeSetStyleJson", "(JLjava/lang/String;Ljava/lang/String;)V", - reinterpret_cast(&nativeSetStyleJSON)}, - {"nativeGetStyleJson", "(J)Ljava/lang/String;", - reinterpret_cast(&nativeGetStyleJSON)}, - {"nativeSetAccessToken", "(JLjava/lang/String;)V", - reinterpret_cast(&nativeSetAccessToken)}, - {"nativeGetAccessToken", "(J)Ljava/lang/String;", - reinterpret_cast(&nativeGetAccessToken)}, - {"nativeCancelTransitions", "(J)V", reinterpret_cast(&nativeCancelTransitions)}, - {"nativeSetGestureInProgress", "(JZ)V", reinterpret_cast(&nativeSetGestureInProgress)}, - {"nativeMoveBy", "(JDDJ)V", reinterpret_cast(&nativeMoveBy)}, - {"nativeSetLatLng", "(JLcom/mapbox/mapboxsdk/geometry/LatLng;J)V", - reinterpret_cast(&nativeSetLatLng)}, - {"nativeGetLatLng", "(J)Lcom/mapbox/mapboxsdk/geometry/LatLng;", - reinterpret_cast(&nativeGetLatLng)}, - {"nativeResetPosition", "(J)V", reinterpret_cast(&nativeResetPosition)}, - {"nativeGetCameraValues","(J)[D", reinterpret_cast(&nativeGetCameraValues)}, - {"nativeGetPitch", "(J)D", reinterpret_cast(&nativeGetPitch)}, - {"nativeSetPitch", "(JDJ)V", reinterpret_cast(&nativeSetPitch)}, - {"nativeScaleBy", "(JDDDJ)V", reinterpret_cast(&nativeScaleBy)}, - {"nativeSetScale", "(JDDDJ)V", reinterpret_cast(&nativeSetScale)}, - {"nativeGetScale", "(J)D", reinterpret_cast(&nativeGetScale)}, - {"nativeSetZoom", "(JDJ)V", reinterpret_cast(&nativeSetZoom)}, - {"nativeGetZoom", "(J)D", reinterpret_cast(&nativeGetZoom)}, - {"nativeResetZoom", "(J)V", reinterpret_cast(&nativeResetZoom)}, - {"nativeGetMinZoom", "(J)D", reinterpret_cast(&nativeGetMinZoom)}, - {"nativeSetMinZoom", "(JD)V", reinterpret_cast(&nativeSetMinZoom)}, - {"nativeGetMaxZoom", "(J)D", reinterpret_cast(&nativeGetMaxZoom)}, - {"nativeSetMaxZoom", "(JD)V", reinterpret_cast(&nativeSetMaxZoom)}, - {"nativeRotateBy", "(JDDDDJ)V", reinterpret_cast(&nativeRotateBy)}, - {"nativeSetBearing", "(JDJ)V", - reinterpret_cast( - static_cast( - &nativeSetBearing))}, - {"nativeSetBearing", "(JDDD)V", - reinterpret_cast( - static_cast( - &nativeSetBearing))}, - {"nativeGetBearing", "(J)D", reinterpret_cast(&nativeGetBearing)}, - {"nativeResetNorth", "(J)V", reinterpret_cast(&nativeResetNorth)}, - {"nativeAddMarker", "(JLcom/mapbox/mapboxsdk/annotations/Marker;)J", - reinterpret_cast(&nativeAddMarker)}, - {"nativeAddMarkers", "(JLjava/util/List;)[J", - reinterpret_cast(&nativeAddMarkers)}, - {"nativeAddPolyline", "(JLcom/mapbox/mapboxsdk/annotations/Polyline;)J", - reinterpret_cast(&nativeAddPolyline)}, - {"nativeAddPolylines", "(JLjava/util/List;)[J", - reinterpret_cast(&nativeAddPolylines)}, - {"nativeAddPolygon", "(JLcom/mapbox/mapboxsdk/annotations/Polygon;)J", - reinterpret_cast(&nativeAddPolygon)}, - {"nativeAddPolygons", "(JLjava/util/List;)[J", - reinterpret_cast(&nativeAddPolygons)}, - {"nativeUpdateMarker", "(JLcom/mapbox/mapboxsdk/annotations/Marker;)V", - reinterpret_cast(&nativeUpdateMarker)} , - {"nativeRemoveAnnotation", "(JJ)V", reinterpret_cast(&nativeRemoveAnnotation)}, - {"nativeRemoveAnnotations", "(J[J)V", reinterpret_cast(&nativeRemoveAnnotations)}, - {"nativeGetAnnotationsInBounds", "(JLcom/mapbox/mapboxsdk/geometry/LatLngBounds;)[J", - reinterpret_cast(&nativeGetAnnotationsInBounds)}, - {"nativeAddAnnotationIcon", "(JLjava/lang/String;IIF[B)V", reinterpret_cast(&nativeAddAnnotationIcon)}, - {"nativeSetVisibleCoordinateBounds", "(J[Lcom/mapbox/mapboxsdk/geometry/LatLng;Landroid/graphics/RectF;DJ)V", - reinterpret_cast(&nativeSetVisibleCoordinateBounds)}, - {"nativeOnLowMemory", "(J)V", reinterpret_cast(&nativeOnLowMemory)}, - {"nativeSetDebug", "(JZ)V", reinterpret_cast(&nativeSetDebug)}, - {"nativeToggleDebug", "(J)V", reinterpret_cast(&nativeToggleDebug)}, - {"nativeGetDebug", "(J)Z", reinterpret_cast(&nativeGetDebug)}, - {"nativeIsFullyLoaded", "(J)Z", reinterpret_cast(&nativeIsFullyLoaded)}, - {"nativeSetReachability", "(JZ)V", reinterpret_cast(&nativeSetReachability)}, - {"nativeGetMetersPerPixelAtLatitude", "(JDD)D", reinterpret_cast(&nativeGetMetersPerPixelAtLatitude)}, - {"nativeProjectedMetersForLatLng", - "(JLcom/mapbox/mapboxsdk/geometry/LatLng;)Lcom/mapbox/mapboxsdk/geometry/ProjectedMeters;", - reinterpret_cast(&nativeProjectedMetersForLatLng)}, - {"nativeLatLngForProjectedMeters", - "(JLcom/mapbox/mapboxsdk/geometry/ProjectedMeters;)Lcom/mapbox/mapboxsdk/geometry/LatLng;", - reinterpret_cast(&nativeLatLngForProjectedMeters)}, - {"nativePixelForLatLng", "(JLcom/mapbox/mapboxsdk/geometry/LatLng;)Landroid/graphics/PointF;", - reinterpret_cast(&nativePixelForLatLng)}, - {"nativeLatLngForPixel", "(JLandroid/graphics/PointF;)Lcom/mapbox/mapboxsdk/geometry/LatLng;", - reinterpret_cast(&nativeLatLngForPixel)}, - {"nativeGetTopOffsetPixelsForAnnotationSymbol", "(JLjava/lang/String;)D", - reinterpret_cast(&nativeGetTopOffsetPixelsForAnnotationSymbol)}, - {"nativeJumpTo", "(JDLcom/mapbox/mapboxsdk/geometry/LatLng;DD)V", - reinterpret_cast(&nativeJumpTo)}, - {"nativeEaseTo", "(JDLcom/mapbox/mapboxsdk/geometry/LatLng;JDD)V", - reinterpret_cast(&nativeEaseTo)}, - {"nativeFlyTo", "(JDLcom/mapbox/mapboxsdk/geometry/LatLng;JDD)V", - reinterpret_cast(&nativeFlyTo)}, - {"nativeAddCustomLayer", "(JLcom/mapbox/mapboxsdk/layers/CustomLayer;Ljava/lang/String;)V", - reinterpret_cast(&nativeAddCustomLayer)}, - {"nativeRemoveCustomLayer", "(JLjava/lang/String;)V", - reinterpret_cast(&nativeRemoveCustomLayer)}, - {"nativeSetContentPadding", "(JDDDD)V", - reinterpret_cast(&nativeSetContentPadding)} + jni::JNIEnv& env = jni::GetEnv(*vm, jni::jni_version_1_6); + + mbgl::android::RegisterNativeHTTPRequest(env); + + latLngClass = &jni::FindClass(env, "com/mapbox/mapboxsdk/geometry/LatLng"); + latLngClass = jni::NewGlobalRef(env, latLngClass).release(); + latLngConstructorId = &jni::GetMethodID(env, *latLngClass, "", "(DD)V"); + latLngLatitudeId = &jni::GetFieldID(env, *latLngClass, "latitude", "D"); + latLngLongitudeId = &jni::GetFieldID(env, *latLngClass, "longitude", "D"); + + latLngBoundsClass = &jni::FindClass(env, "com/mapbox/mapboxsdk/geometry/LatLngBounds"); + latLngBoundsClass = jni::NewGlobalRef(env, latLngBoundsClass).release(); + latLngBoundsConstructorId = &jni::GetMethodID(env, *latLngBoundsClass, "", "(DDDD)V"); + latLngBoundsLatNorthId = &jni::GetFieldID(env, *latLngBoundsClass, "mLatNorth", "D"); + latLngBoundsLatSouthId = &jni::GetFieldID(env, *latLngBoundsClass, "mLatSouth", "D"); + latLngBoundsLonEastId = &jni::GetFieldID(env, *latLngBoundsClass, "mLonEast", "D"); + latLngBoundsLonWestId = &jni::GetFieldID(env, *latLngBoundsClass, "mLonWest", "D"); + + iconClass = &jni::FindClass(env, "com/mapbox/mapboxsdk/annotations/Icon"); + iconClass = jni::NewGlobalRef(env, iconClass).release(); + iconIdId = &jni::GetFieldID(env, *iconClass, "mId", "Ljava/lang/String;"); + + markerClass = &jni::FindClass(env, "com/mapbox/mapboxsdk/annotations/Marker"); + markerClass = jni::NewGlobalRef(env, markerClass).release(); + markerPositionId = &jni::GetFieldID(env, *markerClass, "position", "Lcom/mapbox/mapboxsdk/geometry/LatLng;"); + markerIconId = &jni::GetFieldID(env, *markerClass, "icon", "Lcom/mapbox/mapboxsdk/annotations/Icon;"); + markerIdId = &jni::GetFieldID(env, *markerClass, "id", "J"); + + polylineClass = &jni::FindClass(env, "com/mapbox/mapboxsdk/annotations/Polyline"); + polylineClass = jni::NewGlobalRef(env, polylineClass).release(); + polylineAlphaId = &jni::GetFieldID(env, *polylineClass, "alpha", "F"); + polylineColorId = &jni::GetFieldID(env, *polylineClass, "color", "I"); + polylineWidthId = &jni::GetFieldID(env, *polylineClass, "width", "F"); + polylinePointsId = &jni::GetFieldID(env, *polylineClass, "points", "Ljava/util/List;"); + + polygonClass = &jni::FindClass(env, "com/mapbox/mapboxsdk/annotations/Polygon"); + polygonClass = jni::NewGlobalRef(env, polygonClass).release(); + polygonAlphaId = &jni::GetFieldID(env, *polygonClass, "alpha", "F"); + polygonFillColorId = &jni::GetFieldID(env, *polygonClass, "fillColor", "I"); + polygonStrokeColorId = &jni::GetFieldID(env, *polygonClass, "strokeColor", "I"); + polygonPointsId = &jni::GetFieldID(env, *polygonClass, "points", "Ljava/util/List;"); + + jni::jclass* listClass = &jni::FindClass(env, "java/util/List"); + listToArrayId = &jni::GetMethodID(env, *listClass, "toArray", "()[Ljava/lang/Object;"); + + arrayListClass = &jni::FindClass(env, "java/util/ArrayList"); + arrayListClass = jni::NewGlobalRef(env, arrayListClass).release(); + arrayListConstructorId = &jni::GetMethodID(env, *arrayListClass, "", "()V"); + arrayListAddId = &jni::GetMethodID(env, *arrayListClass, "add", "(Ljava/lang/Object;)Z"); + + projectedMetersClass = &jni::FindClass(env, "com/mapbox/mapboxsdk/geometry/ProjectedMeters"); + projectedMetersClass = jni::NewGlobalRef(env, projectedMetersClass).release(); + projectedMetersConstructorId = &jni::GetMethodID(env, *projectedMetersClass, "", "(DD)V"); + projectedMetersNorthingId = &jni::GetFieldID(env, *projectedMetersClass, "northing", "D"); + projectedMetersEastingId = &jni::GetFieldID(env, *projectedMetersClass, "easting", "D"); + + pointFClass = &jni::FindClass(env, "android/graphics/PointF"); + pointFClass = jni::NewGlobalRef(env, pointFClass).release(); + pointFConstructorId = &jni::GetMethodID(env, *pointFClass, "", "(FF)V"); + pointFXId = &jni::GetFieldID(env, *pointFClass, "x", "F"); + pointFYId = &jni::GetFieldID(env, *pointFClass, "y", "F"); + + rectFClass = &jni::FindClass(env, "android/graphics/RectF"); + rectFClass = jni::NewGlobalRef(env, rectFClass).release(); + rectFConstructorId = &jni::GetMethodID(env, *rectFClass, "", "()V"); + rectFLeftId = &jni::GetFieldID(env, *rectFClass, "left", "F"); + rectFRightId = &jni::GetFieldID(env, *rectFClass, "right", "F"); + rectFTopId = &jni::GetFieldID(env, *rectFClass, "top", "F"); + rectFBottomId = &jni::GetFieldID(env, *rectFClass, "bottom", "F"); + + customLayerClass = &jni::FindClass(env, "com/mapbox/mapboxsdk/layers/CustomLayer"); + customLayerClass = jni::NewGlobalRef(env, customLayerClass).release(); + customLayerIdId = &jni::GetFieldID(env, *customLayerClass, "mID", "Ljava/lang/String;"); + customLayerContextId = &jni::GetFieldID(env, *customLayerClass, "mContext", "J"); + customLayerInitializeFunctionId = &jni::GetFieldID(env, *customLayerClass, "mInitializeFunction", "J"); + customLayerRenderFunctionId = &jni::GetFieldID(env, *customLayerClass, "mRenderFunction", "J"); + customLayerDeinitializeFunctionId = &jni::GetFieldID(env, *customLayerClass, "mDeinitializeFunction", "J"); + + jni::jclass& nativeMapViewClass = jni::FindClass(env, "com/mapbox/mapboxsdk/maps/NativeMapView"); + + onInvalidateId = &jni::GetMethodID(env, nativeMapViewClass, "onInvalidate", "()V"); + onMapChangedId = &jni::GetMethodID(env, nativeMapViewClass, "onMapChanged", "(I)V"); + onFpsChangedId = &jni::GetMethodID(env, nativeMapViewClass, "onFpsChanged", "(D)V"); + + #define MAKE_NATIVE_METHOD(name, sig) jni::MakeNativeMethod( #name, sig ) + + jni::RegisterNatives(env, nativeMapViewClass, + MAKE_NATIVE_METHOD(nativeCreate, "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;FIJ)J"), + MAKE_NATIVE_METHOD(nativeDestroy, "(J)V"), + MAKE_NATIVE_METHOD(nativeInitializeDisplay, "(J)V"), + MAKE_NATIVE_METHOD(nativeTerminateDisplay, "(J)V"), + MAKE_NATIVE_METHOD(nativeInitializeContext, "(J)V"), + MAKE_NATIVE_METHOD(nativeTerminateContext, "(J)V"), + MAKE_NATIVE_METHOD(nativeCreateSurface, "(JLandroid/view/Surface;)V"), + MAKE_NATIVE_METHOD(nativeDestroySurface, "(J)V"), + MAKE_NATIVE_METHOD(nativePause, "(J)V"), + MAKE_NATIVE_METHOD(nativeIsPaused, "(J)Z"), + MAKE_NATIVE_METHOD(nativeResume, "(J)V"), + MAKE_NATIVE_METHOD(nativeUpdate, "(J)V"), + MAKE_NATIVE_METHOD(nativeRenderSync, "(J)V"), + MAKE_NATIVE_METHOD(nativeViewResize, "(JII)V"), + MAKE_NATIVE_METHOD(nativeFramebufferResize, "(JII)V"), + MAKE_NATIVE_METHOD(nativeAddClass, "(JLjava/lang/String;)V"), + MAKE_NATIVE_METHOD(nativeRemoveClass, "(JLjava/lang/String;)V"), + MAKE_NATIVE_METHOD(nativeHasClass, "(JLjava/lang/String;)Z"), + MAKE_NATIVE_METHOD(nativeSetClasses, "(JLjava/util/List;)V"), + MAKE_NATIVE_METHOD(nativeGetClasses, "(J)Ljava/util/List;"), + MAKE_NATIVE_METHOD(nativeSetDefaultTransitionDuration, "(JJ)V"), + MAKE_NATIVE_METHOD(nativeGetDefaultTransitionDuration, "(J)J"), + MAKE_NATIVE_METHOD(nativeSetStyleUrl, "(JLjava/lang/String;)V"), + MAKE_NATIVE_METHOD(nativeSetStyleJson, "(JLjava/lang/String;Ljava/lang/String;)V"), + MAKE_NATIVE_METHOD(nativeGetStyleJson, "(J)Ljava/lang/String;"), + MAKE_NATIVE_METHOD(nativeSetAccessToken, "(JLjava/lang/String;)V"), + MAKE_NATIVE_METHOD(nativeGetAccessToken, "(J)Ljava/lang/String;"), + MAKE_NATIVE_METHOD(nativeCancelTransitions, "(J)V"), + MAKE_NATIVE_METHOD(nativeSetGestureInProgress, "(JZ)V"), + MAKE_NATIVE_METHOD(nativeMoveBy, "(JDDJ)V"), + MAKE_NATIVE_METHOD(nativeSetLatLng, "(JLcom/mapbox/mapboxsdk/geometry/LatLng;J)V"), + MAKE_NATIVE_METHOD(nativeGetLatLng, "(J)Lcom/mapbox/mapboxsdk/geometry/LatLng;"), + MAKE_NATIVE_METHOD(nativeResetPosition, "(J)V"), + MAKE_NATIVE_METHOD(nativeGetCameraValues, "(J)[D"), + MAKE_NATIVE_METHOD(nativeGetPitch, "(J)D"), + MAKE_NATIVE_METHOD(nativeSetPitch, "(JDJ)V"), + MAKE_NATIVE_METHOD(nativeScaleBy, "(JDDDJ)V"), + MAKE_NATIVE_METHOD(nativeSetScale, "(JDDDJ)V"), + MAKE_NATIVE_METHOD(nativeGetScale, "(J)D"), + MAKE_NATIVE_METHOD(nativeSetZoom, "(JDJ)V"), + MAKE_NATIVE_METHOD(nativeGetZoom, "(J)D"), + MAKE_NATIVE_METHOD(nativeResetZoom, "(J)V"), + MAKE_NATIVE_METHOD(nativeGetMinZoom, "(J)D"), + MAKE_NATIVE_METHOD(nativeSetMinZoom, "(JD)V"), + MAKE_NATIVE_METHOD(nativeGetMaxZoom, "(J)D"), + MAKE_NATIVE_METHOD(nativeSetMaxZoom, "(JD)V"), + MAKE_NATIVE_METHOD(nativeRotateBy, "(JDDDDJ)V"), + MAKE_NATIVE_METHOD(nativeSetBearing, "(JDJ)V"), + MAKE_NATIVE_METHOD(nativeSetBearingXY, "(JDDD)V"), + MAKE_NATIVE_METHOD(nativeGetBearing, "(J)D"), + MAKE_NATIVE_METHOD(nativeResetNorth, "(J)V"), + MAKE_NATIVE_METHOD(nativeAddMarker, "(JLcom/mapbox/mapboxsdk/annotations/Marker;)J"), + MAKE_NATIVE_METHOD(nativeAddMarkers, "(JLjava/util/List;)[J"), + MAKE_NATIVE_METHOD(nativeAddPolyline, "(JLcom/mapbox/mapboxsdk/annotations/Polyline;)J"), + MAKE_NATIVE_METHOD(nativeAddPolylines, "(JLjava/util/List;)[J"), + MAKE_NATIVE_METHOD(nativeAddPolygon, "(JLcom/mapbox/mapboxsdk/annotations/Polygon;)J"), + MAKE_NATIVE_METHOD(nativeAddPolygons, "(JLjava/util/List;)[J"), + MAKE_NATIVE_METHOD(nativeUpdateMarker, "(JLcom/mapbox/mapboxsdk/annotations/Marker;)V"), + MAKE_NATIVE_METHOD(nativeRemoveAnnotation, "(JJ)V"), + MAKE_NATIVE_METHOD(nativeRemoveAnnotations, "(J[J)V"), + MAKE_NATIVE_METHOD(nativeGetAnnotationsInBounds, "(JLcom/mapbox/mapboxsdk/geometry/LatLngBounds;)[J"), + MAKE_NATIVE_METHOD(nativeAddAnnotationIcon, "(JLjava/lang/String;IIF[B)V"), + MAKE_NATIVE_METHOD(nativeSetVisibleCoordinateBounds, "(J[Lcom/mapbox/mapboxsdk/geometry/LatLng;Landroid/graphics/RectF;DJ)V"), + MAKE_NATIVE_METHOD(nativeOnLowMemory, "(J)V"), + MAKE_NATIVE_METHOD(nativeSetDebug, "(JZ)V"), + MAKE_NATIVE_METHOD(nativeToggleDebug, "(J)V"), + MAKE_NATIVE_METHOD(nativeGetDebug, "(J)Z"), + MAKE_NATIVE_METHOD(nativeIsFullyLoaded, "(J)Z"), + MAKE_NATIVE_METHOD(nativeSetReachability, "(JZ)V"), + MAKE_NATIVE_METHOD(nativeGetMetersPerPixelAtLatitude, "(JDD)D"), + MAKE_NATIVE_METHOD(nativeProjectedMetersForLatLng, "(JLcom/mapbox/mapboxsdk/geometry/LatLng;)Lcom/mapbox/mapboxsdk/geometry/ProjectedMeters;"), + MAKE_NATIVE_METHOD(nativeLatLngForProjectedMeters, "(JLcom/mapbox/mapboxsdk/geometry/ProjectedMeters;)Lcom/mapbox/mapboxsdk/geometry/LatLng;"), + MAKE_NATIVE_METHOD(nativePixelForLatLng, "(JLcom/mapbox/mapboxsdk/geometry/LatLng;)Landroid/graphics/PointF;"), + MAKE_NATIVE_METHOD(nativeLatLngForPixel, "(JLandroid/graphics/PointF;)Lcom/mapbox/mapboxsdk/geometry/LatLng;"), + MAKE_NATIVE_METHOD(nativeGetTopOffsetPixelsForAnnotationSymbol, "(JLjava/lang/String;)D"), + MAKE_NATIVE_METHOD(nativeJumpTo, "(JDLcom/mapbox/mapboxsdk/geometry/LatLng;DD)V"), + MAKE_NATIVE_METHOD(nativeEaseTo, "(JDLcom/mapbox/mapboxsdk/geometry/LatLng;JDD)V"), + MAKE_NATIVE_METHOD(nativeFlyTo, "(JDLcom/mapbox/mapboxsdk/geometry/LatLng;JDD)V"), + MAKE_NATIVE_METHOD(nativeAddCustomLayer, "(JLcom/mapbox/mapboxsdk/layers/CustomLayer;Ljava/lang/String;)V"), + MAKE_NATIVE_METHOD(nativeRemoveCustomLayer, "(JLjava/lang/String;)V"), + MAKE_NATIVE_METHOD(nativeSetContentPadding, "(JDDDD)V") + ); + + // Offline begin + + struct OfflineManager { + static constexpr auto Name() { return "com/mapbox/mapboxsdk/offline/OfflineManager"; } + + struct ListOfflineRegionsCallback { + static constexpr auto Name() { return "com/mapbox/mapboxsdk/offline/OfflineManager$ListOfflineRegionsCallback"; } + }; + + struct CreateOfflineRegionsCallback { + static constexpr auto Name() { return "com/mapbox/mapboxsdk/offline/OfflineManager$CreateOfflineRegionCallback"; } + }; }; - if (env->RegisterNatives(nativeMapViewClass, methods.data(), methods.size()) < 0) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - // Offline register begin - - const std::vector offlineManagerMethods = { - {"createDefaultFileSource", "(Ljava/lang/String;Ljava/lang/String;J)J", reinterpret_cast(&createDefaultFileSource)}, - {"setAccessToken", "(JLjava/lang/String;)V", reinterpret_cast(&setAccessToken)}, - {"getAccessToken", "(J)Ljava/lang/String;", reinterpret_cast(&getAccessToken)}, - {"listOfflineRegions", "(JLcom/mapbox/mapboxsdk/offline/OfflineManager$ListOfflineRegionsCallback;)V", reinterpret_cast(&listOfflineRegions)}, - {"createOfflineRegion", "(JLcom/mapbox/mapboxsdk/offline/OfflineRegionDefinition;[BLcom/mapbox/mapboxsdk/offline/OfflineManager$CreateOfflineRegionCallback;)V", reinterpret_cast(&createOfflineRegion)}, - {"setOfflineMapboxTileCountLimit", "(JJ)V", reinterpret_cast(&setOfflineMapboxTileCountLimit)} + struct OfflineRegion { + static constexpr auto Name() { return "com/mapbox/mapboxsdk/offline/OfflineRegion"; } }; - if (env->RegisterNatives(offlineManagerClass, offlineManagerMethods.data(), offlineManagerMethods.size()) < 0) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - const std::vector offlineRegionMethods = { - {"destroyOfflineRegion", "(J)V", reinterpret_cast(&destroyOfflineRegion)}, - {"setOfflineRegionObserver", "(Lcom/mapbox/mapboxsdk/offline/OfflineRegion;Lcom/mapbox/mapboxsdk/offline/OfflineRegion$OfflineRegionObserver;)V", reinterpret_cast(&setOfflineRegionObserver)}, - {"setOfflineRegionDownloadState", "(Lcom/mapbox/mapboxsdk/offline/OfflineRegion;I)V", reinterpret_cast(&setOfflineRegionDownloadState)}, - {"getOfflineRegionStatus", "(Lcom/mapbox/mapboxsdk/offline/OfflineRegion;Lcom/mapbox/mapboxsdk/offline/OfflineRegion$OfflineRegionStatusCallback;)V", reinterpret_cast(&getOfflineRegionStatus)}, - {"deleteOfflineRegion", "(Lcom/mapbox/mapboxsdk/offline/OfflineRegion;Lcom/mapbox/mapboxsdk/offline/OfflineRegion$OfflineRegionDeleteCallback;)V", reinterpret_cast(&deleteOfflineRegion)} - }; - - if (env->RegisterNatives(offlineRegionClass, offlineRegionMethods.data(), offlineRegionMethods.size()) < 0) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - // Offline register end - - latLngClass = reinterpret_cast(env->NewGlobalRef(latLngClass)); - if (latLngClass == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - latLngBoundsClass = reinterpret_cast(env->NewGlobalRef(latLngBoundsClass)); - if (latLngBoundsClass == nullptr) { - env->ExceptionDescribe(); - env->DeleteGlobalRef(latLngClass); - env->DeleteGlobalRef(latLngBoundsClass); - return JNI_ERR; - } - - iconClass = reinterpret_cast(env->NewGlobalRef(iconClass)); - if (iconClass == nullptr) { - env->ExceptionDescribe(); - env->DeleteGlobalRef(latLngClass); - env->DeleteGlobalRef(latLngBoundsClass); - return JNI_ERR; - } - - markerClass = reinterpret_cast(env->NewGlobalRef(markerClass)); - if (markerClass == nullptr) { - env->ExceptionDescribe(); - env->DeleteGlobalRef(latLngClass); - env->DeleteGlobalRef(latLngBoundsClass); - env->DeleteGlobalRef(iconClass); - return JNI_ERR; - } - - polylineClass = reinterpret_cast(env->NewGlobalRef(polylineClass)); - if (polylineClass == nullptr) { - env->ExceptionDescribe(); - env->DeleteGlobalRef(latLngClass); - env->DeleteGlobalRef(latLngBoundsClass); - env->DeleteGlobalRef(iconClass); - env->DeleteGlobalRef(markerClass); - return JNI_ERR; - } - - polygonClass = reinterpret_cast(env->NewGlobalRef(polygonClass)); - if (polygonClass == nullptr) { - env->ExceptionDescribe(); - env->DeleteGlobalRef(latLngClass); - env->DeleteGlobalRef(latLngBoundsClass); - env->DeleteGlobalRef(iconClass); - env->DeleteGlobalRef(markerClass); - env->DeleteGlobalRef(polylineClass); - return JNI_ERR; - } - - runtimeExceptionClass = reinterpret_cast(env->NewGlobalRef(runtimeExceptionClass)); - if (runtimeExceptionClass == nullptr) { - env->ExceptionDescribe(); - env->DeleteGlobalRef(latLngClass); - env->DeleteGlobalRef(latLngBoundsClass); - env->DeleteGlobalRef(iconClass); - env->DeleteGlobalRef(markerClass); - env->DeleteGlobalRef(polylineClass); - env->DeleteGlobalRef(polygonClass); - return JNI_ERR; - } - - nullPointerExceptionClass = - reinterpret_cast(env->NewGlobalRef(nullPointerExceptionClass)); - if (nullPointerExceptionClass == nullptr) { - env->ExceptionDescribe(); - env->DeleteGlobalRef(latLngClass); - env->DeleteGlobalRef(latLngBoundsClass); - env->DeleteGlobalRef(iconClass); - env->DeleteGlobalRef(markerClass); - env->DeleteGlobalRef(polylineClass); - env->DeleteGlobalRef(polygonClass); - env->DeleteGlobalRef(runtimeExceptionClass); - return JNI_ERR; - } - - arrayListClass = reinterpret_cast(env->NewGlobalRef(arrayListClass)); - if (arrayListClass == 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); - return JNI_ERR; - } + jni::Class offlineManagerClass = jni::Class::Find(env); + offlineManagerClassPtrId = &jni::GetFieldID(env, offlineManagerClass, "mDefaultFileSourcePtr", "J"); + + jni::RegisterNatives(env, offlineManagerClass, + MAKE_NATIVE_METHOD(createDefaultFileSource, "(Ljava/lang/String;Ljava/lang/String;J)J"), + MAKE_NATIVE_METHOD(setAccessToken, "(JLjava/lang/String;)V"), + MAKE_NATIVE_METHOD(getAccessToken, "(J)Ljava/lang/String;"), + MAKE_NATIVE_METHOD(listOfflineRegions, "(JLcom/mapbox/mapboxsdk/offline/OfflineManager$ListOfflineRegionsCallback;)V"), + MAKE_NATIVE_METHOD(createOfflineRegion, "(JLcom/mapbox/mapboxsdk/offline/OfflineRegionDefinition;[BLcom/mapbox/mapboxsdk/offline/OfflineManager$CreateOfflineRegionCallback;)V"), + MAKE_NATIVE_METHOD(setOfflineMapboxTileCountLimit, "(JJ)V") + ); + + jni::Class listOfflineRegionsCallbackClass = jni::Class::Find(env); + listOnListMethodId = &jni::GetMethodID(env, listOfflineRegionsCallbackClass, "onList", "([Lcom/mapbox/mapboxsdk/offline/OfflineRegion;)V"); + listOnErrorMethodId = &jni::GetMethodID(env, listOfflineRegionsCallbackClass, "onError", "(Ljava/lang/String;)V"); + + jni::Class createOfflineRegionCallbackClass = jni::Class::Find(env); + createOnCreateMethodId = &jni::GetMethodID(env, createOfflineRegionCallbackClass, "onCreate", "(Lcom/mapbox/mapboxsdk/offline/OfflineRegion;)V"); + createOnErrorMethodId = &jni::GetMethodID(env, createOfflineRegionCallbackClass, "onError", "(Ljava/lang/String;)V"); + + offlineRegionClass = &jni::FindClass(env, OfflineRegion::Name()); + offlineRegionClass = jni::NewGlobalRef(env, offlineRegionClass).release(); + offlineRegionConstructorId = &jni::GetMethodID(env, *offlineRegionClass, "", "()V"); + offlineRegionOfflineManagerId = &jni::GetFieldID(env, *offlineRegionClass, "offlineManager", "Lcom/mapbox/mapboxsdk/offline/OfflineManager;"); + offlineRegionIdId = &jni::GetFieldID(env, *offlineRegionClass, "mId", "J"); + offlineRegionDefinitionId = &jni::GetFieldID(env, *offlineRegionClass, "mDefinition", "Lcom/mapbox/mapboxsdk/offline/OfflineRegionDefinition;"); + offlineRegionMetadataId = &jni::GetFieldID(env, *offlineRegionClass, "mMetadata", "[B"); + offlineRegionPtrId = &jni::GetFieldID(env, *offlineRegionClass, "mOfflineRegionPtr", "J"); + + jni::RegisterNatives(env, *offlineRegionClass, + MAKE_NATIVE_METHOD(destroyOfflineRegion, "(J)V"), + MAKE_NATIVE_METHOD(setOfflineRegionObserver, "(Lcom/mapbox/mapboxsdk/offline/OfflineRegion;Lcom/mapbox/mapboxsdk/offline/OfflineRegion$OfflineRegionObserver;)V"), + MAKE_NATIVE_METHOD(setOfflineRegionDownloadState, "(Lcom/mapbox/mapboxsdk/offline/OfflineRegion;I)V"), + MAKE_NATIVE_METHOD(getOfflineRegionStatus, "(Lcom/mapbox/mapboxsdk/offline/OfflineRegion;Lcom/mapbox/mapboxsdk/offline/OfflineRegion$OfflineRegionStatusCallback;)V"), + MAKE_NATIVE_METHOD(deleteOfflineRegion, "(Lcom/mapbox/mapboxsdk/offline/OfflineRegion;Lcom/mapbox/mapboxsdk/offline/OfflineRegion$OfflineRegionDeleteCallback;)V") + ); - projectedMetersClass = reinterpret_cast(env->NewGlobalRef(projectedMetersClass)); - if (projectedMetersClass == 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); - return JNI_ERR; - } - - pointFClass = reinterpret_cast(env->NewGlobalRef(pointFClass)); - if (pointFClass == nullptr) { - env->ExceptionDescribe(); - env->DeleteGlobalRef(latLngClass); - env->DeleteGlobalRef(latLngBoundsClass); - env->DeleteGlobalRef(markerClass); - env->DeleteGlobalRef(iconClass); - env->DeleteGlobalRef(polylineClass); - env->DeleteGlobalRef(polygonClass); - env->DeleteGlobalRef(runtimeExceptionClass); - env->DeleteGlobalRef(nullPointerExceptionClass); - env->DeleteGlobalRef(arrayListClass); - env->DeleteGlobalRef(projectedMetersClass); - return JNI_ERR; - } - - rectFClass = reinterpret_cast(env->NewGlobalRef(rectFClass)); - if (rectFClass == nullptr) { - env->ExceptionDescribe(); - env->DeleteGlobalRef(latLngClass); - env->DeleteGlobalRef(markerClass); - env->DeleteGlobalRef(latLngBoundsClass); - env->DeleteGlobalRef(polylineClass); - env->DeleteGlobalRef(polygonClass); - env->DeleteGlobalRef(runtimeExceptionClass); - env->DeleteGlobalRef(nullPointerExceptionClass); - env->DeleteGlobalRef(arrayListClass); - env->DeleteGlobalRef(projectedMetersClass); - env->DeleteGlobalRef(pointFClass); - return JNI_ERR; - } - - // Offline global definitions begin - - offlineManagerClass = reinterpret_cast(env->NewGlobalRef(offlineManagerClass)); - if (offlineManagerClass == 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); - } - - listOfflineRegionsCallbackClass = reinterpret_cast(env->NewGlobalRef(listOfflineRegionsCallbackClass)); - if (listOfflineRegionsCallbackClass == 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); - } - - offlineRegionClass = reinterpret_cast(env->NewGlobalRef(offlineRegionClass)); - if (offlineRegionClass == 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(listOfflineRegionsCallbackClass); - } - - offlineRegionDefinitionClass = reinterpret_cast(env->NewGlobalRef(offlineRegionDefinitionClass)); - if (offlineRegionDefinitionClass == 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(offlineManagerClass); - env->DeleteGlobalRef(listOfflineRegionsCallbackClass); - env->DeleteGlobalRef(offlineRegionClass); - } - - createOfflineRegionCallbackClass = reinterpret_cast(env->NewGlobalRef(createOfflineRegionCallbackClass)); - if (createOfflineRegionCallbackClass == 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(offlineManagerClass); - env->DeleteGlobalRef(listOfflineRegionsCallbackClass); - env->DeleteGlobalRef(offlineRegionClass); - env->DeleteGlobalRef(offlineRegionDefinitionClass); - } - - offlineRegionObserverClass = reinterpret_cast(env->NewGlobalRef(offlineRegionObserverClass)); - if (offlineRegionObserverClass == 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(offlineManagerClass); - env->DeleteGlobalRef(listOfflineRegionsCallbackClass); - env->DeleteGlobalRef(offlineRegionClass); - env->DeleteGlobalRef(offlineRegionDefinitionClass); - env->DeleteGlobalRef(createOfflineRegionCallbackClass); - } - - offlineRegionStatusClass = reinterpret_cast(env->NewGlobalRef(offlineRegionStatusClass)); - if (offlineRegionStatusClass == 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(offlineManagerClass); - env->DeleteGlobalRef(listOfflineRegionsCallbackClass); - env->DeleteGlobalRef(offlineRegionClass); - env->DeleteGlobalRef(offlineRegionDefinitionClass); - env->DeleteGlobalRef(createOfflineRegionCallbackClass); - env->DeleteGlobalRef(offlineRegionObserverClass); - } - - offlineRegionErrorClass = reinterpret_cast(env->NewGlobalRef(offlineRegionErrorClass)); - if (offlineRegionErrorClass == 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(offlineManagerClass); - env->DeleteGlobalRef(listOfflineRegionsCallbackClass); - env->DeleteGlobalRef(offlineRegionClass); - env->DeleteGlobalRef(offlineRegionDefinitionClass); - env->DeleteGlobalRef(createOfflineRegionCallbackClass); - env->DeleteGlobalRef(offlineRegionObserverClass); - env->DeleteGlobalRef(offlineRegionStatusClass); - } - - offlineRegionStatusCallbackClass = reinterpret_cast(env->NewGlobalRef(offlineRegionStatusCallbackClass)); - if (offlineRegionStatusCallbackClass == 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(offlineManagerClass); - env->DeleteGlobalRef(listOfflineRegionsCallbackClass); - env->DeleteGlobalRef(offlineRegionClass); - env->DeleteGlobalRef(offlineRegionDefinitionClass); - env->DeleteGlobalRef(createOfflineRegionCallbackClass); - env->DeleteGlobalRef(offlineRegionObserverClass); - env->DeleteGlobalRef(offlineRegionStatusClass); - env->DeleteGlobalRef(offlineRegionErrorClass); - } - - offlineRegionDeleteCallbackClass = reinterpret_cast(env->NewGlobalRef(offlineRegionDeleteCallbackClass)); - if (offlineRegionDeleteCallbackClass == 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(offlineManagerClass); - env->DeleteGlobalRef(listOfflineRegionsCallbackClass); - env->DeleteGlobalRef(offlineRegionClass); - env->DeleteGlobalRef(offlineRegionDefinitionClass); - env->DeleteGlobalRef(createOfflineRegionCallbackClass); - env->DeleteGlobalRef(offlineRegionObserverClass); - env->DeleteGlobalRef(offlineRegionStatusClass); - env->DeleteGlobalRef(offlineRegionErrorClass); - env->DeleteGlobalRef(offlineRegionStatusCallbackClass); - } - - // Offline global definitions end + // This needs to be updated once we support more than one type of region definition + offlineRegionDefinitionClass = &jni::FindClass(env, "com/mapbox/mapboxsdk/offline/OfflineTilePyramidRegionDefinition"); + offlineRegionDefinitionClass = jni::NewGlobalRef(env, offlineRegionDefinitionClass).release(); + offlineRegionDefinitionConstructorId = &jni::GetMethodID(env, *offlineRegionDefinitionClass, "", "()V"); + offlineRegionDefinitionStyleURLId = &jni::GetFieldID(env, *offlineRegionDefinitionClass, "styleURL", "Ljava/lang/String;"); + offlineRegionDefinitionBoundsId = &jni::GetFieldID(env, *offlineRegionDefinitionClass, "bounds", "Lcom/mapbox/mapboxsdk/geometry/LatLngBounds;"); + offlineRegionDefinitionMinZoomId = &jni::GetFieldID(env, *offlineRegionDefinitionClass, "minZoom", "D"); + offlineRegionDefinitionMaxZoomId = &jni::GetFieldID(env, *offlineRegionDefinitionClass, "maxZoom", "D"); + offlineRegionDefinitionPixelRatioId = &jni::GetFieldID(env, *offlineRegionDefinitionClass, "pixelRatio", "F"); + + jni::jclass* offlineRegionObserverClass = &jni::FindClass(env, "com/mapbox/mapboxsdk/offline/OfflineRegion$OfflineRegionObserver"); + offlineRegionObserveronStatusChangedId = &jni::GetMethodID(env, *offlineRegionObserverClass, "onStatusChanged", "(Lcom/mapbox/mapboxsdk/offline/OfflineRegionStatus;)V"); + offlineRegionObserveronErrorId = &jni::GetMethodID(env, *offlineRegionObserverClass, "onError", "(Lcom/mapbox/mapboxsdk/offline/OfflineRegionError;)V"); + offlineRegionObserveronLimitId = &jni::GetMethodID(env, *offlineRegionObserverClass, "mapboxTileCountLimitExceeded", "(J)V"); + + offlineRegionStatusClass = &jni::FindClass(env, "com/mapbox/mapboxsdk/offline/OfflineRegionStatus"); + offlineRegionStatusClass = jni::NewGlobalRef(env, offlineRegionStatusClass).release(); + offlineRegionStatusConstructorId = &jni::GetMethodID(env, *offlineRegionStatusClass, "", "()V"); + offlineRegionStatusDownloadStateId = &jni::GetFieldID(env, *offlineRegionStatusClass, "downloadState", "I"); + offlineRegionStatusCompletedResourceCountId = &jni::GetFieldID(env, *offlineRegionStatusClass, "completedResourceCount", "J"); + offlineRegionStatusCompletedResourceSizeId = &jni::GetFieldID(env, *offlineRegionStatusClass, "completedResourceSize", "J"); + offlineRegionStatusRequiredResourceCountId = &jni::GetFieldID(env, *offlineRegionStatusClass, "requiredResourceCount", "J"); + offlineRegionStatusRequiredResourceCountIsPreciseId = &jni::GetFieldID(env, *offlineRegionStatusClass, "requiredResourceCountIsPrecise", "Z"); + + offlineRegionErrorClass = &jni::FindClass(env, "com/mapbox/mapboxsdk/offline/OfflineRegionError"); + offlineRegionErrorClass = jni::NewGlobalRef(env, offlineRegionErrorClass).release(); + offlineRegionErrorConstructorId = &jni::GetMethodID(env, *offlineRegionErrorClass, "", "()V"); + offlineRegionErrorReasonId = &jni::GetFieldID(env, *offlineRegionErrorClass, "reason", "Ljava/lang/String;"); + offlineRegionErrorMessageId = &jni::GetFieldID(env, *offlineRegionErrorClass, "message", "Ljava/lang/String;"); + + jni::jclass* offlineRegionStatusCallbackClass = &jni::FindClass(env, "com/mapbox/mapboxsdk/offline/OfflineRegion$OfflineRegionStatusCallback"); + offlineRegionStatusOnStatusId = &jni::GetMethodID(env, *offlineRegionStatusCallbackClass, "onStatus", "(Lcom/mapbox/mapboxsdk/offline/OfflineRegionStatus;)V"); + offlineRegionStatusOnErrorId = &jni::GetMethodID(env, *offlineRegionStatusCallbackClass, "onError", "(Ljava/lang/String;)V"); + + jni::jclass* offlineRegionDeleteCallbackClass = &jni::FindClass(env, "com/mapbox/mapboxsdk/offline/OfflineRegion$OfflineRegionDeleteCallback"); + offlineRegionDeleteOnDeleteId = &jni::GetMethodID(env, *offlineRegionDeleteCallbackClass, "onDelete", "()V"); + offlineRegionDeleteOnErrorId = &jni::GetMethodID(env, *offlineRegionDeleteCallbackClass, "onError", "(Ljava/lang/String;)V"); + + // Offline end char release[PROP_VALUE_MAX] = ""; __system_property_get("ro.build.version.release", release); @@ -3312,5 +1982,3 @@ extern "C" JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved) { return JNI_VERSION_1_6; } - -}