From 465c949153a838bb3159204ab268eb551fbd2e6c Mon Sep 17 00:00:00 2001 From: Ivo van Dongen Date: Thu, 16 Feb 2017 16:16:47 +0200 Subject: [android] jni high level binding refactor --- platform/android/src/jni.cpp | 2108 ++---------------------------------------- 1 file changed, 66 insertions(+), 2042 deletions(-) (limited to 'platform/android/src/jni.cpp') diff --git a/platform/android/src/jni.cpp b/platform/android/src/jni.cpp index 59602c3299..bd12cff3fa 100755 --- a/platform/android/src/jni.cpp +++ b/platform/android/src/jni.cpp @@ -1,21 +1,29 @@ -#include -#include -#include -#include -#include -#include +#include "jni.hpp" -#include -#include +#include -#include "jni.hpp" -#include "java_types.hpp" -#include "native_map_view.hpp" +#include "annotation/marker.hpp" +#include "annotation/polygon.hpp" +#include "annotation/polyline.hpp" #include "bitmap.hpp" #include "bitmap_factory.hpp" #include "connectivity_listener.hpp" -#include "default_file_source.hpp" -#include "attach_env.hpp" +#include "conversion/conversion.hpp" +#include "conversion/collection.hpp" +#include "file_source.hpp" +#include "geometry/feature.hpp" +#include "geometry/lat_lng.hpp" +#include "geometry/lat_lng_bounds.hpp" +#include "geometry/projected_meters.hpp" +#include "graphics/pointf.hpp" +#include "graphics/rectf.hpp" +#include "java_types.hpp" +#include "native_map_view.hpp" +#include "offline/offline_manager.hpp" +#include "offline/offline_region.hpp" +#include "offline/offline_region_definition.hpp" +#include "offline/offline_region_error.hpp" +#include "offline/offline_region_status.hpp" #include "style/functions/categorical_stops.hpp" #include "style/functions/exponential_stops.hpp" #include "style/functions/identity_stops.hpp" @@ -24,30 +32,6 @@ #include "style/layers/layers.hpp" #include "style/sources/sources.hpp" -#include "conversion/conversion.hpp" -#include "conversion/collection.hpp" -#include "geometry/conversion/feature.hpp" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -#pragma clang diagnostic ignored "-Wunused-parameter" - namespace mbgl { namespace android { @@ -55,129 +39,7 @@ void RegisterNativeHTTPRequest(JNIEnv&); JavaVM* theJVM; -std::string cachePath; -std::string dataPath; -std::string apkPath; -std::string androidRelease; - -jni::jmethodID* onInvalidateId = nullptr; -jni::jmethodID* onMapChangedId = nullptr; -jni::jmethodID* onFpsChangedId = nullptr; -jni::jmethodID* onSnapshotReadyId = 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; - -// Offline declarations start - -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* transformOnURLMethodId = nullptr; - -jni::jmethodID* updateMetadataOnUpdateMethodId = nullptr; -jni::jmethodID* updateMetadataOnErrorMethodId = 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* offlineRegionStatusCompletedTileCountId = nullptr; -jni::jfieldID* offlineRegionStatusCompletedTileSizeId = 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 - +//TODO: remove bool attach_jni_thread(JavaVM* vm, JNIEnv** env, std::string threadName) { assert(vm != nullptr); assert(env != nullptr); @@ -205,6 +67,7 @@ bool attach_jni_thread(JavaVM* vm, JNIEnv** env, std::string threadName) { return detach; } +//TODO: remove void detach_jni_thread(JavaVM* vm, JNIEnv** env, bool detach) { if (detach) { assert(vm != nullptr); @@ -219,1900 +82,61 @@ void detach_jni_thread(JavaVM* vm, JNIEnv** env, bool detach) { *env = nullptr; } -std::string std_string_from_jstring(JNIEnv *env, jni::jstring* jstr) { - return jni::Make(*env, jni::String(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, jni::jobject* jlist) { - std::vector vector; - - jni::NullCheck(*env, jlist); - jni::jarray* jarray = - reinterpret_cast*>(jni::CallMethod(*env, jlist, *listToArrayId)); - - 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)); - } - - return vector; -} - -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) { - jni::CallMethod(*env, jlist, *arrayListAddId, std_string_to_jstring(env, str)); - } - - return jlist; -} - -jni::jarray* std_vector_uint_to_jobject(JNIEnv *env, const std::vector& vector) { - jni::jarray& jarray = jni::NewArray(*env, vector.size()); - - std::vector v; - v.reserve(vector.size()); - std::move(vector.begin(), vector.end(), std::back_inserter(v)); - - jni::SetArrayRegion(*env, jarray, 0, v); - - return &jarray; -} - -static std::vector metadata_from_java(JNIEnv* env, jni::jarray& j) { - std::size_t length = jni::GetArrayLength(*env, j); - std::vector c; - c.resize(length); - jni::GetArrayRegion(*env, j, 0, length, reinterpret_cast(c.data())); - return c; -} - -static jni::jarray* metadata_from_native(JNIEnv* env, const std::vector& c) { - 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, 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 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(); - - jni::jobject* jbounds = &jni::NewObject(*env, *latLngBoundsClass, *latLngBoundsConstructorId, - northLatitude, eastLongitude, southLatitude, westLongitude); - - return jbounds; -} - -} -} - -namespace { - -using namespace mbgl::android; -using DebugOptions = mbgl::MapDebugOptions; - -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_); - return reinterpret_cast(new NativeMapView(env, jni::Unwrap(obj), pixelRatio, availableProcessors, totalMemory)); -} - -void nativeDestroy(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr) { - mbgl::Log::Debug(mbgl::Event::JNI, "nativeDestroy"); - assert(nativeMapViewPtr != 0); - delete reinterpret_cast(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); - nativeMapView->initializeDisplay(); -} - -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, jni::jobject* obj, jlong nativeMapViewPtr) { - mbgl::Log::Debug(mbgl::Event::JNI, "nativeInitializeContext"); - assert(nativeMapViewPtr != 0); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - nativeMapView->initializeContext(); -} - -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, jni::jobject* obj, jlong nativeMapViewPtr, jni::jobject* surface) { - mbgl::Log::Debug(mbgl::Event::JNI, "nativeCreateSurface"); - assert(nativeMapViewPtr != 0); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - nativeMapView->createSurface(ANativeWindow_fromSurface(env, jni::Unwrap(surface))); -} - -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 nativeUpdate(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr) { - assert(nativeMapViewPtr != 0); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - nativeMapView->invalidate(); -} - -void nativeRender(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr) { - assert(nativeMapViewPtr != 0); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - nativeMapView->render(); -} - -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); - assert(height >= 0); - assert(width <= UINT16_MAX); - assert(height <= UINT16_MAX); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - nativeMapView->resizeView(width, height); -} - -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); - assert(fbHeight >= 0); - assert(fbWidth <= UINT16_MAX); - assert(fbHeight <= UINT16_MAX); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - nativeMapView->resizeFramebuffer(fbWidth, fbHeight); -} - -void nativeRemoveClass(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jni::jstring* clazz) { - assert(nativeMapViewPtr != 0); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - nativeMapView->getMap().removeClass(std_string_from_jstring(env, clazz)); -} - -jboolean nativeHasClass(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jni::jstring* clazz) { - assert(nativeMapViewPtr != 0); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - return nativeMapView->getMap().hasClass(std_string_from_jstring(env, clazz)); -} - -void nativeAddClass(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jni::jstring* clazz) { - assert(nativeMapViewPtr != 0); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - nativeMapView->getMap().addClass(std_string_from_jstring(env, clazz)); -} - -void nativeSetClasses(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jni::jobject* classes) { - assert(nativeMapViewPtr != 0); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - nativeMapView->getMap().setClasses(std_vector_string_from_jobject(env, classes)); -} - -jni::jobject* nativeGetClasses(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr) { - assert(nativeMapViewPtr != 0); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - return std_vector_string_to_jobject(env, nativeMapView->getMap().getClasses()); -} - -void nativeSetAPIBaseURL(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jni::jstring* url) { - assert(nativeMapViewPtr != 0); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - nativeMapView->getFileSource().setAPIBaseURL(std_string_from_jstring(env, url)); -} - -void nativeSetStyleUrl(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jni::jstring* url) { - assert(nativeMapViewPtr != 0); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - nativeMapView->getMap().setStyleURL(std_string_from_jstring(env, url)); -} - -jni::jstring* nativeGetStyleUrl(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr){ - assert(nativeMapViewPtr != 0); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - return std_string_to_jstring(env, nativeMapView->getMap().getStyleURL()); -} - -void nativeSetStyleJson(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jni::jstring* newStyleJson) { - assert(nativeMapViewPtr != 0); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - nativeMapView->getMap().setStyleJSON(std_string_from_jstring(env, newStyleJson)); -} - -jni::jstring* nativeGetStyleJson(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr) { - assert(nativeMapViewPtr != 0); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - return std_string_to_jstring(env, nativeMapView->getMap().getStyleJSON()); -} - -void nativeSetAccessToken(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jni::jstring* accessToken) { - assert(nativeMapViewPtr != 0); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - nativeMapView->getFileSource().setAccessToken(std_string_from_jstring(env, accessToken)); -} - -jni::jstring* nativeGetAccessToken(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr) { - assert(nativeMapViewPtr != 0); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - return std_string_to_jstring(env, nativeMapView->getFileSource().getAccessToken()); -} - -void nativeCancelTransitions(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr) { - assert(nativeMapViewPtr != 0); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - nativeMapView->getMap().cancelTransitions(); -} - -void nativeSetGestureInProgress(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jboolean inProgress) { - assert(nativeMapViewPtr != 0); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - nativeMapView->getMap().setGestureInProgress(inProgress); -} - -void nativeMoveBy(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jdouble dx, jdouble dy, - jlong duration) { - assert(nativeMapViewPtr != 0); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - - mbgl::AnimationOptions animationOptions; - if (duration > 0) { - animationOptions.duration.emplace(mbgl::Milliseconds(duration)); - animationOptions.easing.emplace(mbgl::util::UnitBezier { 0, 0.3, 0.6, 1.0 }); - } - - nativeMapView->getMap().moveBy({dx, dy}, animationOptions); -} - -void nativeSetLatLng(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jdouble latitude, jdouble longitude, jlong duration) { - assert(nativeMapViewPtr != 0); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - nativeMapView->getMap().setLatLng(mbgl::LatLng(latitude, longitude), nativeMapView->getInsets(), mbgl::Duration(duration)); -} - -jni::jobject* nativeGetLatLng(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr) { - assert(nativeMapViewPtr != 0); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - mbgl::LatLng latLng = nativeMapView->getMap().getLatLng(nativeMapView->getInsets()); - return &jni::NewObject(*env, *latLngClass, *latLngConstructorId, latLng.latitude, latLng.longitude); -} - -jdoubleArray nativeGetCameraValues(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr) { - assert(nativeMapViewPtr != 0); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - mbgl::LatLng latLng = nativeMapView->getMap().getLatLng(nativeMapView->getInsets()); - jdoubleArray output = env->NewDoubleArray(5); - jsize start = 0; - jsize leng = 5; - jdouble buf[5]; - buf[0] = latLng.latitude; - buf[1] = latLng.longitude; - buf[2] = -nativeMapView->getMap().getBearing(); - buf[3] = nativeMapView->getMap().getPitch(); - buf[4] = nativeMapView->getMap().getZoom(); - env->SetDoubleArrayRegion(output, start, leng, buf); - - if (output == nullptr) { - env->ExceptionDescribe(); - return nullptr; - } - - return output; -} - -void nativeResetPosition(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr) { - assert(nativeMapViewPtr != 0); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - nativeMapView->getMap().resetPosition(); -} - -jdouble nativeGetPitch(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr) { - assert(nativeMapViewPtr != 0); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - return nativeMapView->getMap().getPitch(); -} - -void nativeSetPitch(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jdouble pitch, jlong milliseconds) { - assert(nativeMapViewPtr != 0); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - mbgl::Duration duration((mbgl::Milliseconds(milliseconds))); - nativeMapView->getMap().setPitch(pitch, duration); -} - -void nativeScaleBy(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jdouble ds, jdouble cx, - jdouble cy, jlong duration) { - assert(nativeMapViewPtr != 0); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - mbgl::ScreenCoordinate center(cx, cy); - nativeMapView->getMap().scaleBy(ds, center, mbgl::Milliseconds(duration)); -} - -void nativeSetScale(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jdouble scale, - jdouble cx, jdouble cy, jlong duration) { - assert(nativeMapViewPtr != 0); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - mbgl::ScreenCoordinate center(cx, cy); - nativeMapView->getMap().setScale(scale, center, mbgl::Milliseconds(duration)); -} - -jdouble nativeGetScale(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr) { - assert(nativeMapViewPtr != 0); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - return nativeMapView->getMap().getScale(); -} - -void nativeSetZoom(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jdouble zoom, jlong duration) { - assert(nativeMapViewPtr != 0); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - nativeMapView->getMap().setZoom(zoom, mbgl::Milliseconds(duration)); -} - -jdouble nativeGetZoom(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr) { - assert(nativeMapViewPtr != 0); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - return nativeMapView->getMap().getZoom(); -} - -void nativeResetZoom(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr) { - assert(nativeMapViewPtr != 0); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - nativeMapView->getMap().resetZoom(); -} - -void nativeSetMinZoom(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jdouble zoom) { - assert(nativeMapViewPtr != 0); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - nativeMapView->getMap().setMinZoom(zoom); -} - -jdouble nativeGetMinZoom(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr) { - assert(nativeMapViewPtr != 0); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - return nativeMapView->getMap().getMinZoom(); -} - -void nativeSetMaxZoom(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jdouble zoom) { - assert(nativeMapViewPtr != 0); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - nativeMapView->getMap().setMaxZoom(zoom); -} - -jdouble nativeGetMaxZoom(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr) { - assert(nativeMapViewPtr != 0); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - return nativeMapView->getMap().getMaxZoom(); -} - -void nativeRotateBy(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jdouble sx, - jdouble sy, jdouble ex, jdouble ey, jlong duration) { - assert(nativeMapViewPtr != 0); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - mbgl::ScreenCoordinate first(sx, sy); - mbgl::ScreenCoordinate second(ex, ey); - nativeMapView->getMap().rotateBy(first, second, mbgl::Milliseconds(duration)); -} - -void nativeSetBearing(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jdouble degrees, - jlong milliseconds) { - assert(nativeMapViewPtr != 0); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - mbgl::Duration duration((mbgl::Milliseconds(milliseconds))); - nativeMapView->getMap().setBearing(degrees, duration); -} - -void nativeSetFocalBearing(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jdouble degrees, jdouble fx, - jdouble fy, jlong milliseconds) { - assert(nativeMapViewPtr != 0); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - mbgl::ScreenCoordinate center(fx, fy); - nativeMapView->getMap().setBearing(degrees, center, mbgl::Milliseconds(milliseconds)); -} - -void nativeSetBearingXY(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jdouble degrees, - jdouble cx, jdouble cy) { - assert(nativeMapViewPtr != 0); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - mbgl::ScreenCoordinate center(cx, cy); - nativeMapView->getMap().setBearing(degrees, center); -} - -jdouble nativeGetBearing(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr) { - assert(nativeMapViewPtr != 0); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - return nativeMapView->getMap().getBearing(); -} - -void nativeResetNorth(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr) { - assert(nativeMapViewPtr != 0); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - nativeMapView->getMap().resetNorth(); -} - -void nativeUpdateMarker(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jlong markerId, jdouble lat, jdouble lon, jni::jstring* jid) { - assert(nativeMapViewPtr != 0); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - if (markerId == -1) { - return; - } - std::string iconId = std_string_from_jstring(env, jid); - // Because Java only has int, not unsigned int, we need to bump the annotation id up to a long. - nativeMapView->getMap().updateAnnotation(markerId, mbgl::SymbolAnnotation { mbgl::Point(lon, lat), iconId }); -} - -jni::jarray* nativeAddMarkers(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jni::jarray* jarray) { - assert(nativeMapViewPtr != 0); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - - NullCheck(*env, jarray); - std::size_t len = jni::GetArrayLength(*env, *jarray); - - mbgl::AnnotationIDs ids; - ids.reserve(len); - - 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::jstring* jid = reinterpret_cast(jni::GetField(*env, icon, *iconIdId)); - - jdouble latitude = jni::GetField(*env, position, *latLngLatitudeId); - jdouble longitude = jni::GetField(*env, position, *latLngLongitudeId); - - ids.push_back(nativeMapView->getMap().addAnnotation(mbgl::SymbolAnnotation { - mbgl::Point(longitude, latitude), - std_string_from_jstring(env, jid) - })); - - jni::DeleteLocalRef(*env, position); - jni::DeleteLocalRef(*env, jid); - jni::DeleteLocalRef(*env, icon); - jni::DeleteLocalRef(*env, marker); - } - - return std_vector_uint_to_jobject(env, ids); -} - -static mbgl::Color toColor(jint color) { - float r = (color >> 16) & 0xFF; - float g = (color >> 8) & 0xFF; - float b = (color) & 0xFF; - float a = (color >> 24) & 0xFF; - return { r / 255.0f, g / 255.0f, b / 255.0f, a / 255.0f }; -} - -template -Geometry toGeometry(JNIEnv *env, jni::jobject* jlist) { - NullCheck(*env, jlist); - jni::jarray* jarray = - reinterpret_cast*>(jni::CallMethod(*env, jlist, *listToArrayId)); - NullCheck(*env, jarray); - - std::size_t size = jni::GetArrayLength(*env, *jarray); - - Geometry geometry; - geometry.reserve(size); - - for (std::size_t i = 0; i < size; i++) { - jni::jobject* latLng = reinterpret_cast(jni::GetObjectArrayElement(*env, *jarray, i)); - NullCheck(*env, latLng); - - geometry.push_back(mbgl::Point( - jni::GetField(*env, latLng, *latLngLongitudeId), - jni::GetField(*env, latLng, *latLngLatitudeId))); - - jni::DeleteLocalRef(*env, latLng); - } - - jni::DeleteLocalRef(*env, jarray); - jni::DeleteLocalRef(*env, jlist); - - return geometry; -} - -jni::jarray* nativeAddPolylines(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jni::jarray* jarray) { - assert(nativeMapViewPtr != 0); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - - NullCheck(*env, jarray); - std::size_t len = jni::GetArrayLength(*env, *jarray); - - mbgl::AnnotationIDs ids; - ids.reserve(len); - - for (std::size_t i = 0; i < len; i++) { - jni::jobject* polyline = jni::GetObjectArrayElement(*env, *jarray, i); - jni::jobject* points = jni::GetField(*env, polyline, *polylinePointsId); - - mbgl::LineAnnotation annotation { toGeometry>(env, points) }; - annotation.opacity = { jni::GetField(*env, polyline, *polylineAlphaId) }; - annotation.color = { toColor(jni::GetField(*env, polyline, *polylineColorId)) }; - annotation.width = { jni::GetField(*env, polyline, *polylineWidthId) }; - ids.push_back(nativeMapView->getMap().addAnnotation(annotation)); - - jni::DeleteLocalRef(*env, polyline); - } - - return std_vector_uint_to_jobject(env, ids); -} - -jni::jarray* nativeAddPolygons(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jni::jarray* jarray) { - assert(nativeMapViewPtr != 0); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - - NullCheck(*env, jarray); - std::size_t len = jni::GetArrayLength(*env, *jarray); - - mbgl::AnnotationIDs ids; - ids.reserve(len); - - for (std::size_t i = 0; i < len; i++) { - jni::jobject* polygon = jni::GetObjectArrayElement(*env, *jarray, i); - jni::jobject* points = jni::GetField(*env, polygon, *polygonPointsId); - - mbgl::FillAnnotation annotation { mbgl::Polygon { toGeometry>(env, points) } }; - annotation.opacity = { jni::GetField(*env, polygon, *polygonAlphaId) }; - annotation.outlineColor = { toColor(jni::GetField(*env, polygon, *polygonStrokeColorId)) }; - annotation.color = { toColor(jni::GetField(*env, polygon, *polygonFillColorId)) }; - ids.push_back(nativeMapView->getMap().addAnnotation(annotation)); - - jni::DeleteLocalRef(*env, polygon); - } - - return std_vector_uint_to_jobject(env, ids); -} - -void nativeUpdatePolygon(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jlong polygonId, jni::jobject* polygon) { - assert(nativeMapViewPtr != 0); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - jni::jobject* points = jni::GetField(*env, polygon, *polygonPointsId); - - mbgl::FillAnnotation annotation { mbgl::Polygon { toGeometry>(env, points) } }; - annotation.opacity = { jni::GetField(*env, polygon, *polygonAlphaId) }; - annotation.outlineColor = { toColor(jni::GetField(*env, polygon, *polygonStrokeColorId)) }; - annotation.color = { toColor(jni::GetField(*env, polygon, *polygonFillColorId)) }; - nativeMapView->getMap().updateAnnotation(polygonId, annotation); -} - -void nativeUpdatePolyline(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jlong polylineId, jni::jobject* polyline) { - assert(nativeMapViewPtr != 0); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - jni::jobject* points = jni::GetField(*env, polyline, *polylinePointsId); - - mbgl::LineAnnotation annotation { toGeometry>(env, points) }; - annotation.opacity = { jni::GetField(*env, polyline, *polylineAlphaId) }; - annotation.color = { toColor(jni::GetField(*env, polyline, *polylineColorId)) }; - annotation.width = { jni::GetField(*env, polyline, *polylineWidthId) }; - nativeMapView->getMap().updateAnnotation(polylineId, annotation); -} - -void nativeRemoveAnnotations(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jni::jarray* jarray) { - assert(nativeMapViewPtr != 0); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - - NullCheck(*env, jarray); - std::size_t len = jni::GetArrayLength(*env, *jarray); - 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; - nativeMapView->getMap().removeAnnotation(jids[i]); - } -} - -jni::jarray* nativeQueryPointAnnotations(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jni::jobject* rect) { - assert(nativeMapViewPtr != 0); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - - // Conversion - jfloat left = jni::GetField(*env, rect, *rectFLeftId); - jfloat right = jni::GetField(*env, rect, *rectFRightId); - jfloat top = jni::GetField(*env, rect, *rectFTopId); - jfloat bottom = jni::GetField(*env, rect, *rectFBottomId); - mbgl::ScreenBox box = { - { left, top }, - { right, bottom }, - }; +void registerNatives(JavaVM *vm) { + theJVM = vm; - // Assume only points for now - mbgl::AnnotationIDs ids = nativeMapView->getMap().queryPointAnnotations(box); + jni::JNIEnv& env = jni::GetEnv(*vm, jni::jni_version_1_6); - return std_vector_uint_to_jobject(env, ids); -} + // For the DefaultFileSource + static mbgl::util::RunLoop mainRunLoop; + FileSource::registerNative(env); -void nativeAddAnnotationIcon(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, - jni::jstring* symbol, jint width, jint height, jfloat scale, jni::jarray* jpixels) { - assert(nativeMapViewPtr != 0); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); + // Basic types + java::registerNatives(env); + java::util::registerNative(env); + PointF::registerNative(env); + RectF::registerNative(env); - const std::string symbolName = std_string_from_jstring(env, symbol); + // Geometry + Feature::registerNative(env); + LatLng::registerNative(env); + LatLngBounds::registerNative(env); + ProjectedMeters::registerNative(env); - NullCheck(*env, jpixels); - std::size_t size = jni::GetArrayLength(*env, *jpixels); - mbgl::PremultipliedImage premultipliedImage( - { static_cast(width), static_cast(height) }); + //Annotation + Marker::registerNative(env); + Polygon::registerNative(env); + Polyline::registerNative(env); - if (premultipliedImage.bytes() != uint32_t(size)) { - throw mbgl::util::SpriteImageException("Sprite image pixel count mismatch"); - } + // Map + NativeMapView::registerNative(env); - jni::GetArrayRegion(*env, *jpixels, 0, size, reinterpret_cast(premultipliedImage.data.get())); + // Http + RegisterNativeHTTPRequest(env); - auto iconImage = std::make_shared( - std::move(premultipliedImage), - float(scale)); + // Bitmap + Bitmap::registerNative(env); + BitmapFactory::registerNative(env); - nativeMapView->getMap().addAnnotationIcon(symbolName, iconImage); -} + // Style + registerNativeLayers(env); + registerNativeSources(env); + Stop::registerNative(env); + CategoricalStops::registerNative(env); + ExponentialStops::registerNative(env); + IdentityStops::registerNative(env); + IntervalStops::registerNative(env); -void nativeSetVisibleCoordinateBounds(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, - jni::jarray* coordinates, jni::jobject* padding, jdouble direction, jlong duration) { - assert(nativeMapViewPtr != 0); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - - 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); - - NullCheck(*env, coordinates); - std::size_t count = jni::GetArrayLength(*env, *coordinates); - - mbgl::EdgeInsets mbglInsets = {top, left, bottom, right}; - std::vector latLngs; - latLngs.reserve(count); - - 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); - latLngs.push_back(mbgl::LatLng(latitude, longitude)); - } - - mbgl::CameraOptions cameraOptions = nativeMapView->getMap().cameraForLatLngs(latLngs, mbglInsets); - if (direction >= 0) { - // convert from degrees to radians - cameraOptions.angle = (-direction * M_PI) / 180; - } - mbgl::AnimationOptions animationOptions; - if (duration > 0) { - animationOptions.duration.emplace(mbgl::Milliseconds(duration)); - // equivalent to kCAMediaTimingFunctionDefault in iOS - animationOptions.easing.emplace(mbgl::util::UnitBezier { 0.25, 0.1, 0.25, 0.1 }); - } - - nativeMapView->getMap().easeTo(cameraOptions, animationOptions); -} - -jni::jarray* nativeQueryRenderedFeaturesForPoint(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jni::jfloat x, jni::jfloat y, jni::jarray* layerIds) { - using namespace mbgl::android::conversion; - using namespace mapbox::geometry; - - assert(nativeMapViewPtr != 0); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - - mbgl::optional> layers; - if (layerIds != nullptr && jni::GetArrayLength(*env, *layerIds) > 0) { - layers = toVector(*env, *layerIds); - } - point point = {x, y}; - - return *convert*, std::vector>(*env, nativeMapView->getMap().queryRenderedFeatures(point, layers)); -} - -jni::jarray* nativeQueryRenderedFeaturesForBox(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jni::jfloat left, jni::jfloat top, jni::jfloat right, jni::jfloat bottom, jni::jarray* layerIds) { - using namespace mbgl::android::conversion; - using namespace mapbox::geometry; - - assert(nativeMapViewPtr != 0); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - - mbgl::optional> layers; - if (layerIds != nullptr && jni::GetArrayLength(*env, *layerIds) > 0) { - layers = toVector(*env, *layerIds); - } - box box = { point{ left, top}, point{ right, bottom } }; - - return *convert*, std::vector>(*env, nativeMapView->getMap().queryRenderedFeatures(box, layers)); -} - -void nativeOnLowMemory(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr) { - assert(nativeMapViewPtr != 0); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - nativeMapView->getMap().onLowMemory(); -} - -void nativeSetDebug(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jboolean debug) { - assert(nativeMapViewPtr != 0); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - - DebugOptions debugOptions = debug ? DebugOptions::TileBorders | DebugOptions::ParseStatus | DebugOptions::Collision - : DebugOptions::NoDebug; - nativeMapView->getMap().setDebug(debugOptions); - nativeMapView->enableFps(debug); -} - -void nativeToggleDebug(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr) { - assert(nativeMapViewPtr != 0); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - nativeMapView->getMap().cycleDebugOptions(); - nativeMapView->enableFps(nativeMapView->getMap().getDebug() != DebugOptions::NoDebug); -} - -jboolean nativeGetDebug(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr) { - assert(nativeMapViewPtr != 0); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - return nativeMapView->getMap().getDebug() != DebugOptions::NoDebug; -} - -jboolean nativeIsFullyLoaded(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr) { - assert(nativeMapViewPtr != 0); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - return nativeMapView->getMap().isFullyLoaded(); -} - -void nativeSetReachability(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jboolean status) { - assert(nativeMapViewPtr != 0); - if (status) { - mbgl::NetworkStatus::Reachable(); - } -} - -jdouble nativeGetMetersPerPixelAtLatitude(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jdouble lat, jdouble zoom) { - assert(nativeMapViewPtr != 0); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - return nativeMapView->getMap().getMetersPerPixelAtLatitude(lat, zoom); -} - -jni::jobject* nativeProjectedMetersForLatLng(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jdouble latitude, jdouble longitude) { - assert(nativeMapViewPtr != 0); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - mbgl::ProjectedMeters projectedMeters = nativeMapView->getMap().projectedMetersForLatLng(mbgl::LatLng(latitude, longitude)); - return &jni::NewObject(*env, *projectedMetersClass, *projectedMetersConstructorId, projectedMeters.northing, projectedMeters.easting); -} - -jni::jobject* nativeLatLngForProjectedMeters(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jdouble northing, jdouble easting) { - assert(nativeMapViewPtr != 0); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - mbgl::LatLng latLng = nativeMapView->getMap().latLngForProjectedMeters(mbgl::ProjectedMeters(northing, easting)); - return &jni::NewObject(*env, *latLngClass, *latLngConstructorId, latLng.latitude, latLng.longitude); -} - -jni::jobject* nativePixelForLatLng(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jdouble latitude, jdouble longitude) { - assert(nativeMapViewPtr != 0); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - mbgl::ScreenCoordinate pixel = nativeMapView->getMap().pixelForLatLng(mbgl::LatLng(latitude, longitude)); - return &jni::NewObject(*env, *pointFClass, *pointFConstructorId, static_cast(pixel.x), static_cast(pixel.y)); -} - -jni::jobject* nativeLatLngForPixel(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jfloat x, jfloat y) { - assert(nativeMapViewPtr != 0); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - mbgl::LatLng latLng = nativeMapView->getMap().latLngForPixel(mbgl::ScreenCoordinate(x, y)); - return &jni::NewObject(*env, *latLngClass, *latLngConstructorId, latLng.latitude, latLng.longitude); -} - -jdouble nativeGetTopOffsetPixelsForAnnotationSymbol(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jni::jstring* symbolName) { - assert(nativeMapViewPtr != 0); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - return nativeMapView->getMap().getTopOffsetPixelsForAnnotationIcon(std_string_from_jstring(env, symbolName)); -} - -void nativeJumpTo(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jdouble angle, jdouble latitude, jdouble longitude, jdouble pitch, jdouble zoom) { - assert(nativeMapViewPtr != 0); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - - mbgl::CameraOptions options; - if (angle != -1) { - options.angle = (-angle * M_PI) / 180; - } - options.center = mbgl::LatLng(latitude, longitude); - options.padding = nativeMapView->getInsets(); - if (pitch != -1) { - options.pitch = pitch * M_PI / 180; - } - if (zoom != -1) { - options.zoom = zoom; - } - - nativeMapView->getMap().jumpTo(options); -} - -void nativeEaseTo(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jdouble angle, jdouble latitude, jdouble longitude, jlong duration, jdouble pitch, jdouble zoom, jboolean easing) { - assert(nativeMapViewPtr != 0); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - - mbgl::CameraOptions cameraOptions; - if (angle != -1) { - cameraOptions.angle = (-angle * M_PI) / 180; - } - cameraOptions.center = mbgl::LatLng(latitude, longitude); - cameraOptions.padding = nativeMapView->getInsets(); - if (pitch != -1) { - cameraOptions.pitch = pitch * M_PI / 180; - } - if (zoom != -1) { - cameraOptions.zoom = zoom; - } - mbgl::AnimationOptions animationOptions; - animationOptions.duration.emplace(mbgl::Duration(duration)); - - if (!easing) { - // add a linear interpolator instead of easing - animationOptions.easing.emplace(mbgl::util::UnitBezier { 0, 0, 1, 1 }); - } - - nativeMapView->getMap().easeTo(cameraOptions, animationOptions); -} - -void nativeSetContentPadding(JNIEnv *env, jni::jobject* obj,long nativeMapViewPtr, double top, double left, double bottom, double right) { - assert(nativeMapViewPtr != 0); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - nativeMapView->setInsets({top, left, bottom, right}); -} - -void nativeFlyTo(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jdouble angle, jdouble latitude, jdouble longitude, jlong duration, jdouble pitch, jdouble zoom) { - assert(nativeMapViewPtr != 0); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - - mbgl::CameraOptions cameraOptions; - if (angle != -1) { - cameraOptions.angle = (-angle * M_PI) / 180 ; - } - cameraOptions.center = mbgl::LatLng(latitude, longitude); - cameraOptions.padding = nativeMapView->getInsets(); - if (pitch != -1) { - cameraOptions.pitch = pitch * M_PI / 180; - } - if (zoom != -1) { - cameraOptions.zoom = zoom; - } - mbgl::AnimationOptions animationOptions; - animationOptions.duration.emplace(mbgl::Duration(duration)); - - nativeMapView->getMap().flyTo(cameraOptions, animationOptions); -} - -jlong nativeGetTransitionDuration(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr) { - assert(env); - assert(nativeMapViewPtr != 0); - - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - - const auto transitionOptions = nativeMapView->getMap().getTransitionOptions(); - return transitionOptions.duration.value_or(mbgl::Duration::zero()).count(); -} - -void nativeSetTransitionDuration(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jlong duration) { - assert(env); - assert(nativeMapViewPtr != 0); - - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - - auto transitionOptions = nativeMapView->getMap().getTransitionOptions(); - transitionOptions.duration = std::chrono::duration_cast(std::chrono::duration(duration)); - nativeMapView->getMap().setTransitionOptions(transitionOptions); -} - -jlong nativeGetTransitionDelay(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr) { - assert(env); - assert(nativeMapViewPtr != 0); - - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - - const auto transitionOptions = nativeMapView->getMap().getTransitionOptions(); - return transitionOptions.delay.value_or(mbgl::Duration::zero()).count(); -} - -void nativeSetTransitionDelay(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jlong delay) { - assert(env); - assert(nativeMapViewPtr != 0); - - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - - auto transitionOptions = nativeMapView->getMap().getTransitionOptions(); - transitionOptions.delay = std::chrono::duration_cast(std::chrono::duration(delay)); - nativeMapView->getMap().setTransitionOptions(transitionOptions); -} - -jni::jobject* nativeGetLayer(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jni::jstring* layerId) { - assert(env); - assert(nativeMapViewPtr != 0); - - // Get the native map peer - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - - // Find the layer - mbgl::style::Layer* coreLayer = nativeMapView->getMap().getLayer(std_string_from_jstring(env, layerId)); - if (!coreLayer) { - mbgl::Log::Debug(mbgl::Event::JNI, "No layer found"); - return jni::Object(); - } - - // Create and return the layer's native peer - return createJavaLayerPeer(*env, nativeMapView->getMap(), *coreLayer); -} - -void nativeAddLayer(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jlong nativeLayerPtr, jni::jstring* before) { - assert(nativeMapViewPtr != 0); - assert(nativeLayerPtr != 0); - - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - - Layer *layer = reinterpret_cast(nativeLayerPtr); - try { - layer->addToMap(nativeMapView->getMap(), before ? mbgl::optional(std_string_from_jstring(env, before)) : mbgl::optional()); - } catch (const std::runtime_error& error) { - jni::ThrowNew(*env, jni::FindClass(*env, "com/mapbox/mapboxsdk/style/layers/CannotAddLayerException"), error.what()); - } -} - -/** - * Remove by layer id. Ownership is not transferred back - */ -void nativeRemoveLayerById(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jni::jstring* id) { - assert(nativeMapViewPtr != 0); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - - nativeMapView->getMap().removeLayer(std_string_from_jstring(env, id)); -} - -/** - * Remove with wrapper object id. Ownership is transferred back to the wrapper - */ -void nativeRemoveLayer(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jlong layerPtr) { - assert(nativeMapViewPtr != 0); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - mbgl::android::Layer *layer = reinterpret_cast(layerPtr); - - std::unique_ptr coreLayer = nativeMapView->getMap().removeLayer(layer->get().getID()); - if (coreLayer) { - layer->setLayer(std::move(coreLayer)); - } -} - - -jni::jobject* nativeGetSource(JNIEnv *env, jni::jobject* obj, jni::jlong nativeMapViewPtr, jni::jstring* sourceId) { - assert(env); - assert(nativeMapViewPtr != 0); - - // Get the native map peer - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - - // Find the source - mbgl::style::Source* coreSource = nativeMapView->getMap().getSource(std_string_from_jstring(env, sourceId)); - if (!coreSource) { - mbgl::Log::Debug(mbgl::Event::JNI, "No source found"); - return jni::Object(); - } - - // Create and return the source's native peer - return createJavaSourcePeer(*env, nativeMapView->getMap(), *coreSource); -} - -void nativeAddSource(JNIEnv *env, jni::jobject* obj, jni::jlong nativeMapViewPtr, jni::jlong nativeSourcePtr) { - assert(nativeMapViewPtr != 0); - assert(nativeSourcePtr != 0); - - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - - Source *source = reinterpret_cast(nativeSourcePtr); - try { - source->addToMap(nativeMapView->getMap()); - } catch (const std::runtime_error& error) { - jni::ThrowNew(*env, jni::FindClass(*env, "com/mapbox/mapboxsdk/style/sources/CannotAddSourceException"), error.what()); - } -} - -void nativeRemoveSourceById(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jni::jstring* id) { - assert(nativeMapViewPtr != 0); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - nativeMapView->getMap().removeSource(std_string_from_jstring(env, id)); -} - -void nativeRemoveSource(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jlong sourcePtr) { - assert(nativeMapViewPtr != 0); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - mbgl::android::Source *source = reinterpret_cast(sourcePtr); - - std::unique_ptr coreSource = nativeMapView->getMap().removeSource(source->get().getID()); - if (coreSource) { - source->setSource(std::move(coreSource)); - } -} - -void nativeAddImage(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jni::jstring* name, jni::jint width, jni::jint height, jni::jfloat pixelRatio, jni::jarray* data) { - assert(nativeMapViewPtr != 0); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - - // Create Pre-multiplied image from byte[] - NullCheck(*env, data); - std::size_t size = jni::GetArrayLength(*env, *data); - mbgl::PremultipliedImage premultipliedImage( - { static_cast(width), static_cast(height) }); - - if (premultipliedImage.bytes() != uint32_t(size)) { - throw mbgl::util::SpriteImageException("Sprite image pixel count mismatch"); - } - - jni::GetArrayRegion(*env, *data, 0, size, reinterpret_cast(premultipliedImage.data.get())); - - // Wrap in a SpriteImage with the correct pixel ratio - auto spriteImage = std::make_unique(std::move(premultipliedImage), float(pixelRatio)); - - nativeMapView->getMap().addImage(std_string_from_jstring(env, name), std::move(spriteImage)); -} - -void nativeRemoveImage(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jni::jstring* name) { - assert(nativeMapViewPtr != 0); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - nativeMapView->getMap().removeImage(std_string_from_jstring(env, name)); -} - -void nativeScheduleTakeSnapshot(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr) { - assert(nativeMapViewPtr != 0); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - nativeMapView->scheduleTakeSnapshot(); -} - -// Offline calls begin - -jlong sharedDefaultFileSource(JNIEnv *env, jni::jobject* obj, jni::jstring* cachePath_, jni::jstring* assetRoot_) { - return reinterpret_cast(&defaultFileSource(std_string_from_jstring(env, cachePath_), - std_string_from_jstring(env, assetRoot_))); -} - -void setAccessToken(JNIEnv *env, jni::jobject* obj, jlong defaultFileSourcePtr, jni::jstring* accessToken_) { - assert(defaultFileSourcePtr != 0); - std::string accessToken = std_string_from_jstring(env, accessToken_); - mbgl::DefaultFileSource *defaultFileSource = reinterpret_cast(defaultFileSourcePtr); - defaultFileSource->setAccessToken(accessToken); -} - -jni::jstring* getAccessToken(JNIEnv *env, jni::jobject* obj, jlong defaultFileSourcePtr) { - assert(defaultFileSourcePtr != 0); - mbgl::DefaultFileSource *defaultFileSource = reinterpret_cast(defaultFileSourcePtr); - std::string accessToken = defaultFileSource->getAccessToken(); - return std_string_to_jstring(env, accessToken); -} - -void listOfflineRegions(JNIEnv *env, jni::jobject* obj, jlong defaultFileSourcePtr, jni::jobject* listCallback) { - // Checks - assert(defaultFileSourcePtr != 0); - NullCheck(*env, listCallback); - - // Makes sure the objects don't get GC'ed - 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) mutable { - - // Reattach, the callback comes from a different thread - JNIEnv *env2; - jboolean renderDetach = attach_jni_thread(theJVM, &env2, "Offline Thread"); - if (renderDetach) { - mbgl::Log::Debug(mbgl::Event::JNI, "Attached."); - } - - if (error) { - std::string message = mbgl::util::toString(error); - jni::CallMethod(*env2, listCallback, *listOnErrorMethodId, std_string_to_jstring(env2, message)); - } else if (regions) { - // Build jni::jarray* - std::size_t index = 0; - jni::jarray* jregions = &jni::NewObjectArray(*env2, regions->size(), *offlineRegionClass, NULL); - for (auto& region : *regions) { - // Create a new local reference frame (capacity 2 for the NewObject allocations below) - // to avoid a local reference table overflow (#5629) - jni::UniqueLocalFrame frame = jni::PushLocalFrame(*env2, 2); - - // Build the Region object - 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(); - 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 - 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 - jni::SetField(*env2, jregion, *offlineRegionPtrId, - reinterpret_cast(new mbgl::OfflineRegion(std::move(region)))); - - jni::SetObjectArrayElement(*env2, *jregions, index, jregion); - index++; - } - - // Trigger callback - jni::CallMethod(*env2, listCallback, *listOnListMethodId, jregions); - } - - // Delete global refs and detach when we're done - jni::DeleteGlobalRef(*env2, jni::UniqueGlobalRef(obj)); - jni::DeleteGlobalRef(*env2, jni::UniqueGlobalRef(listCallback)); - detach_jni_thread(theJVM, &env2, renderDetach); - }); -} - -void createOfflineRegion(JNIEnv *env, jni::jobject* obj, jlong defaultFileSourcePtr, jni::jobject* definition_, jni::jarray* metadata_, jni::jobject* createCallback) { - // Checks - assert(defaultFileSourcePtr != 0); - NullCheck(*env, createCallback); - - // Definition fields - jni::jstring* jStyleURL = reinterpret_cast(jni::GetField(*env, definition_, *offlineRegionDefinitionStyleURLId)); - std::string styleURL = std_string_from_jstring(env, jStyleURL); - 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); - - // Definition - mbgl::OfflineTilePyramidRegionDefinition definition(styleURL, bounds, jMinZoom, jMaxZoom, jPixelRatio); - - // Metadata - mbgl::OfflineRegionMetadata metadata; - if (metadata_ != nullptr) { - metadata = metadata_from_java(env, *metadata_); - } - - // Makes sure the objects don't get GC'ed - 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) mutable { - - // Reattach, the callback comes from a different thread - JNIEnv *env2; - jboolean renderDetach = attach_jni_thread(theJVM, &env2, "Offline Thread"); - if (renderDetach) { - mbgl::Log::Debug(mbgl::Event::JNI, "Attached."); - } - - if (error) { - std::string message = mbgl::util::toString(error); - jni::CallMethod(*env2, createCallback, *createOnErrorMethodId, std_string_to_jstring(env2, message)); - } else if (region) { - // Build the Region object - jni::jobject* jregion = &jni::NewObject(*env2, *offlineRegionClass, *offlineRegionConstructorId); - jni::SetField(*env2, jregion, *offlineRegionOfflineManagerId, obj); - jni::SetField(*env2, jregion, *offlineRegionIdId, region->getID()); - - // Metadata object - 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 - jni::SetField(*env2, jregion, *offlineRegionPtrId, - reinterpret_cast(new mbgl::OfflineRegion(std::move(*region)))); - - // Invoke Java callback - jni::CallMethod(*env2, createCallback, *createOnCreateMethodId, jregion); - } - - // Delete global refs and detach when we're done - jni::DeleteGlobalRef(*env2, jni::UniqueGlobalRef(obj)); - jni::DeleteGlobalRef(*env2, jni::UniqueGlobalRef(createCallback)); - detach_jni_thread(theJVM, &env2, renderDetach); - }); -} - -// A deleter that doesn't retain an JNIEnv handle but instead tries to attach the JVM. This means -// it can be used on any thread to delete a global ref. -struct GenericGlobalRefDeleter { - void operator()(jni::jobject* p) const { - if (p) { - auto env = AttachEnv(); - env->DeleteGlobalRef(jni::Unwrap(p)); - } - } -}; - -void setResourceTransform(JNIEnv *env, jni::jobject* obj, jlong defaultFileSourcePtr, jni::jobject* transformCallback) { - // Checks - assert(defaultFileSourcePtr != 0); - - mbgl::DefaultFileSource *defaultFileSource = reinterpret_cast(defaultFileSourcePtr); - if (transformCallback) { - // Launch transformCallback - defaultFileSource->setResourceTransform([ - // Capture the OfflineManager and ResourceTransformCallback objects as a managed global into - // the lambda. They are released automatically when we're setting a new ResourceTransform in - // a subsequent call. - // Note: we're converting them to shared_ptrs because this lambda is converted to a std::function, - // which requires copyability of its captured variables. - offlineManager = std::shared_ptr(jni::NewGlobalRef(*env, obj).release(), GenericGlobalRefDeleter()), - callback = std::shared_ptr(jni::NewGlobalRef(*env, transformCallback).release(), GenericGlobalRefDeleter()), - env - ](mbgl::Resource::Kind kind, std::string&& url_) { - auto url = std_string_to_jstring(env, url_); - url = reinterpret_cast(jni::CallMethod( - *env, callback.get(), *transformOnURLMethodId, int(kind), url)); - return std_string_from_jstring(env, url); - }); - } else { - // Reset the callback - defaultFileSource->setResourceTransform(nullptr); - } -} - -void setOfflineMapboxTileCountLimit(JNIEnv *env, jni::jobject* obj, jlong defaultFileSourcePtr, jlong limit) { - // Checks - assert(defaultFileSourcePtr != 0); - assert(limit > 0); - - // Set limit - mbgl::DefaultFileSource *defaultFileSource = reinterpret_cast(defaultFileSourcePtr); - defaultFileSource->setOfflineMapboxTileCountLimit(limit); -} - -mbgl::OfflineRegion* getOfflineRegionPeer(JNIEnv *env, jni::jobject* offlineRegion_) { - jlong offlineRegionPtr = jni::GetField(*env, offlineRegion_, *offlineRegionPtrId); - if (!offlineRegionPtr) { - jni::ThrowNew(*env, jni::FindClass(*env, "java/lang/IllegalStateException"), - "Use of OfflineRegion after OfflineRegion.delete"); - } - return reinterpret_cast(offlineRegionPtr); -} - -void destroyOfflineRegion(JNIEnv *env, jni::jobject* offlineRegion_) { - // Offline region - jlong offlineRegionPtr = jni::GetField(*env, offlineRegion_, *offlineRegionPtrId); - if (!offlineRegionPtr) { - return; // Already deleted - } - - // File source - jni::jobject* jmanager = jni::GetField(*env, offlineRegion_, *offlineRegionOfflineManagerId); - jlong defaultFileSourcePtr = jni::GetField(*env, jmanager, *offlineManagerClassPtrId); - mbgl::DefaultFileSource *defaultFileSource = reinterpret_cast(defaultFileSourcePtr); - - // Release the observer and delete the region - mbgl::OfflineRegion *offlineRegion = reinterpret_cast(offlineRegionPtr); - defaultFileSource->setOfflineRegionObserver(*offlineRegion, nullptr); - jni::SetField(*env, offlineRegion_, *offlineRegionPtrId, 0); - delete offlineRegion; -} - -void setOfflineRegionObserver(JNIEnv *env, jni::jobject* offlineRegion_, jni::jobject* observerCallback) { - // Offline region - mbgl::OfflineRegion* offlineRegion = getOfflineRegionPeer(env, offlineRegion_); - - // File source - 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(jni::UniqueGlobalRef&& observerCallback_) - : observerCallback(std::move(observerCallback_)) { - } - - ~Observer() override { - mbgl::Log::Debug(mbgl::Event::JNI, "~Observer()"); - // Env - JNIEnv* env2; - jboolean renderDetach = attach_jni_thread(theJVM, &env2, "Offline Thread"); - jni::DeleteGlobalRef(*env2, std::move(observerCallback)); - detach_jni_thread(theJVM, &env2, renderDetach); - } - - void statusChanged(mbgl::OfflineRegionStatus status) override { - // Env - JNIEnv* env2; - jboolean renderDetach = attach_jni_thread(theJVM, &env2, "Offline Thread"); - - // Conver to jint - jint downloadState; - switch(status.downloadState) { - case mbgl::OfflineRegionDownloadState::Inactive: - downloadState = 0; - break; - case mbgl::OfflineRegionDownloadState::Active: - downloadState = 1; - break; - } - - // Create a new local reference frame (capacity 1 for the NewObject allocation below) - // to avoid a local reference table overflow (#4706) - jni::UniqueLocalFrame frame = jni::PushLocalFrame(*env2, 1); - - // Stats object - 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, *offlineRegionStatusCompletedTileCountId, status.completedTileCount); - jni::SetField(*env2, jstatus, *offlineRegionStatusCompletedTileSizeId, status.completedTileSize); - jni::SetField(*env2, jstatus, *offlineRegionStatusRequiredResourceCountId, status.requiredResourceCount); - jni::SetField(*env2, jstatus, *offlineRegionStatusRequiredResourceCountIsPreciseId, status.requiredResourceCountIsPrecise); - jni::CallMethod(*env2, observerCallback.get(), *offlineRegionObserveronStatusChangedId, jstatus); - - // Detach when we're done - detach_jni_thread(theJVM, &env2, renderDetach); - } - - void responseError(mbgl::Response::Error error) override { - // Env - JNIEnv* env2; - jboolean renderDetach = attach_jni_thread(theJVM, &env2, "Offline Thread"); - - // Handle the value of reason independently of the underlying int value - std::string errorReason; - switch(error.reason) { - case mbgl::Response::Error::Reason::Success: - errorReason = "REASON_SUCCESS"; - break; - case mbgl::Response::Error::Reason::NotFound: - errorReason = "REASON_NOT_FOUND"; - break; - case mbgl::Response::Error::Reason::Server: - errorReason = "REASON_SERVER"; - break; - case mbgl::Response::Error::Reason::Connection: - errorReason = "REASON_CONNECTION"; - break; - case mbgl::Response::Error::Reason::RateLimit: - errorReason = "REASON_RATE_LIMIT"; - break; - case mbgl::Response::Error::Reason::Other: - errorReason = "REASON_OTHER"; - break; - } - - // Error object - jni::UniqueLocalFrame frame = jni::PushLocalFrame(*env2, 3); - 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.get(), *offlineRegionObserveronErrorId, jerror); - - // Detach when we're done - detach_jni_thread(theJVM, &env2, renderDetach); - } - - void mapboxTileCountLimitExceeded(uint64_t limit) override { - // Env - JNIEnv* env2; - jboolean renderDetach = attach_jni_thread(theJVM, &env2, "Offline Thread"); - - // Send limit - jni::CallMethod(*env2, observerCallback.get(), *offlineRegionObserveronLimitId, jlong(limit)); - - // Detach when we're done - detach_jni_thread(theJVM, &env2, renderDetach); - } - - jni::UniqueGlobalRef observerCallback; - }; - - // Set the observer - defaultFileSource->setOfflineRegionObserver(*offlineRegion, - std::make_unique(jni::NewGlobalRef(*env, observerCallback))); -} - -void setOfflineRegionDownloadState(JNIEnv *env, jni::jobject* offlineRegion_, jint offlineRegionDownloadState) { - // State - mbgl::OfflineRegionDownloadState state; - if (offlineRegionDownloadState == 0) { - state = mbgl::OfflineRegionDownloadState::Inactive; - } else if (offlineRegionDownloadState == 1) { - state = mbgl::OfflineRegionDownloadState::Active; - } else { - mbgl::Log::Error(mbgl::Event::JNI, "State can only be 0 (inactive) or 1 (active)."); - return; - } - - // Offline region - mbgl::OfflineRegion* offlineRegion = getOfflineRegionPeer(env, offlineRegion_); - - // File source - 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, jni::jobject* offlineRegion_, jni::jobject* statusCallback) { - // Offline region - mbgl::OfflineRegion* offlineRegion = getOfflineRegionPeer(env, offlineRegion_); - - // File source - 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 = jni::NewGlobalRef(*env, statusCallback).release(); - - // Set new state - defaultFileSource->getOfflineRegionStatus(*offlineRegion, [statusCallback](std::exception_ptr error, mbgl::optional status) mutable { - - // Reattach, the callback comes from a different thread - JNIEnv *env2; - jboolean renderDetach = attach_jni_thread(theJVM, &env2, "Offline Thread"); - if (renderDetach) { - mbgl::Log::Debug(mbgl::Event::JNI, "Attached."); - } - - if (error) { - std::string message = mbgl::util::toString(error); - jni::CallMethod(*env2, statusCallback, *offlineRegionStatusOnErrorId, std_string_to_jstring(env2, message)); - } else if (status) { - // Conver to jint - jint downloadState = -1; - if (status->downloadState == mbgl::OfflineRegionDownloadState::Inactive) { - downloadState = 0; - } else if (status->downloadState == mbgl::OfflineRegionDownloadState::Active) { - downloadState = 1; - } else { - mbgl::Log::Error(mbgl::Event::JNI, "Unsupported OfflineRegionDownloadState value."); - return; - } - - // Stats object - 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 - jni::DeleteGlobalRef(*env2, jni::UniqueGlobalRef(statusCallback)); - detach_jni_thread(theJVM, &env2, renderDetach); - }); -} - -void deleteOfflineRegion(JNIEnv *env, jni::jobject* offlineRegion_, jni::jobject* deleteCallback) { - // Offline region - mbgl::OfflineRegion* offlineRegion = getOfflineRegionPeer(env, offlineRegion_); - - // File source - 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 = jni::NewGlobalRef(*env, deleteCallback).release(); - - // Set new state - jni::SetField(*env, offlineRegion_, *offlineRegionPtrId, 0); - defaultFileSource->deleteOfflineRegion(std::move(*offlineRegion), [deleteCallback](std::exception_ptr error) mutable { - - // Reattach, the callback comes from a different thread - JNIEnv *env2; - jboolean renderDetach = attach_jni_thread(theJVM, &env2, "Offline Thread"); - if (renderDetach) { - mbgl::Log::Debug(mbgl::Event::JNI, "Attached."); - } - - if (error) { - std::string message = mbgl::util::toString(error); - jni::CallMethod(*env2, deleteCallback, *offlineRegionDeleteOnErrorId, std_string_to_jstring(env2, message)); - } else { - jni::CallMethod(*env2, deleteCallback, *offlineRegionDeleteOnDeleteId); - } - - // Delete global refs and detach when we're done - jni::DeleteGlobalRef(*env2, jni::UniqueGlobalRef(deleteCallback)); - detach_jni_thread(theJVM, &env2, renderDetach); - }); -} - -void updateOfflineRegionMetadata(JNIEnv *env, jni::jobject* offlineRegion_, jni::jarray* metadata_, jni::jobject* updateCallback) { - // Offline region - mbgl::OfflineRegion* offlineRegion = getOfflineRegionPeer(env, offlineRegion_); - - // File source - jni::jobject* jmanager = jni::GetField(*env, offlineRegion_, *offlineRegionOfflineManagerId); - jlong defaultFileSourcePtr = jni::GetField(*env, jmanager, *offlineManagerClassPtrId); - mbgl::DefaultFileSource *defaultFileSource = reinterpret_cast(defaultFileSourcePtr); - - // Id conversion - int64_t id = offlineRegion->getID(); - - // Metadata - mbgl::OfflineRegionMetadata metadata; - if (metadata_ != nullptr) { - metadata = metadata_from_java(env, *metadata_); - } - - // Makes sure the objects don't get GC'ed - updateCallback = jni::NewGlobalRef(*env, updateCallback).release(); - - // Launch updateCallback - defaultFileSource->updateOfflineMetadata(id, metadata, [updateCallback] (std::exception_ptr error, mbgl::optional data) mutable { - // Reattach, the callback comes from a different thread - JNIEnv *env2; - jboolean renderDetach = attach_jni_thread(theJVM, &env2, "Offline Thread"); - if (renderDetach) { - mbgl::Log::Debug(mbgl::Event::JNI, "Attached."); - } - - if (error) { - std::string message = mbgl::util::toString(error); - jni::CallMethod(*env2, updateCallback, *updateMetadataOnErrorMethodId, std_string_to_jstring(env2, message)); - } else if (data) { - jni::jarray* jmetadata = metadata_from_native(env2, *data); - jni::CallMethod(*env2, updateCallback, *updateMetadataOnUpdateMethodId, jmetadata); - } - - // Delete global refs and detach when we're done - jni::DeleteGlobalRef(*env2, jni::UniqueGlobalRef(updateCallback)); - detach_jni_thread(theJVM, &env2, renderDetach); - }); -} - -// Offline calls end - -} // anonymous - -namespace mbgl { -namespace android { - -void registerNatives(JavaVM *vm) { - theJVM = vm; - - jni::JNIEnv& env = jni::GetEnv(*vm, jni::jni_version_1_6); - - static mbgl::util::RunLoop mainRunLoop; - - mbgl::android::RegisterNativeHTTPRequest(env); - - java::registerNatives(env); - Bitmap::registerNative(env); - BitmapFactory::registerNative(env); - registerNativeLayers(env); - registerNativeSources(env); - Stop::registerNative(env); - CategoricalStops::registerNative(env); - ExponentialStops::registerNative(env); - IdentityStops::registerNative(env); - IntervalStops::registerNative(env); + // Connectivity ConnectivityListener::registerNative(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"); - - 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"); - onSnapshotReadyId = &jni::GetMethodID(env, nativeMapViewClass, "onSnapshotReady","(Landroid/graphics/Bitmap;)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(nativeUpdate, "(J)V"), - MAKE_NATIVE_METHOD(nativeRender, "(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(nativeSetStyleUrl, "(JLjava/lang/String;)V"), - MAKE_NATIVE_METHOD(nativeGetStyleUrl, "(J)Ljava/lang/String;"), - MAKE_NATIVE_METHOD(nativeSetStyleJson, "(JLjava/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, "(JDDJ)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(nativeSetFocalBearing, "(JDDDJ)V"), - MAKE_NATIVE_METHOD(nativeSetBearingXY, "(JDDD)V"), - MAKE_NATIVE_METHOD(nativeGetBearing, "(J)D"), - MAKE_NATIVE_METHOD(nativeResetNorth, "(J)V"), - MAKE_NATIVE_METHOD(nativeAddMarkers, "(J[Lcom/mapbox/mapboxsdk/annotations/Marker;)[J"), - MAKE_NATIVE_METHOD(nativeAddPolylines, "(J[Lcom/mapbox/mapboxsdk/annotations/Polyline;)[J"), - MAKE_NATIVE_METHOD(nativeAddPolygons, "(J[Lcom/mapbox/mapboxsdk/annotations/Polygon;)[J"), - MAKE_NATIVE_METHOD(nativeUpdateMarker, "(JJDDLjava/lang/String;)V"), - MAKE_NATIVE_METHOD(nativeUpdatePolygon, "(JJLcom/mapbox/mapboxsdk/annotations/Polygon;)V"), - MAKE_NATIVE_METHOD(nativeUpdatePolyline, "(JJLcom/mapbox/mapboxsdk/annotations/Polyline;)V"), - MAKE_NATIVE_METHOD(nativeRemoveAnnotations, "(J[J)V"), - MAKE_NATIVE_METHOD(nativeQueryPointAnnotations, "(JLandroid/graphics/RectF;)[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, "(JDD)Lcom/mapbox/mapboxsdk/geometry/ProjectedMeters;"), - MAKE_NATIVE_METHOD(nativeLatLngForProjectedMeters, "(JDD)Lcom/mapbox/mapboxsdk/geometry/LatLng;"), - MAKE_NATIVE_METHOD(nativePixelForLatLng, "(JDD)Landroid/graphics/PointF;"), - MAKE_NATIVE_METHOD(nativeLatLngForPixel, "(JFF)Lcom/mapbox/mapboxsdk/geometry/LatLng;"), - MAKE_NATIVE_METHOD(nativeGetTopOffsetPixelsForAnnotationSymbol, "(JLjava/lang/String;)D"), - MAKE_NATIVE_METHOD(nativeJumpTo, "(JDDDDD)V"), - MAKE_NATIVE_METHOD(nativeEaseTo, "(JDDDJDDZ)V"), - MAKE_NATIVE_METHOD(nativeFlyTo, "(JDDDJDD)V"), - MAKE_NATIVE_METHOD(nativeGetTransitionDuration, "(J)J"), - MAKE_NATIVE_METHOD(nativeSetTransitionDuration, "(JJ)V"), - MAKE_NATIVE_METHOD(nativeGetTransitionDelay, "(J)J"), - MAKE_NATIVE_METHOD(nativeSetTransitionDelay, "(JJ)V"), - MAKE_NATIVE_METHOD(nativeGetLayer, "(JLjava/lang/String;)Lcom/mapbox/mapboxsdk/style/layers/Layer;"), - MAKE_NATIVE_METHOD(nativeAddLayer, "(JJLjava/lang/String;)V"), - MAKE_NATIVE_METHOD(nativeRemoveLayerById, "(JLjava/lang/String;)V"), - MAKE_NATIVE_METHOD(nativeRemoveLayer, "(JJ)V"), - MAKE_NATIVE_METHOD(nativeGetSource, "(JLjava/lang/String;)Lcom/mapbox/mapboxsdk/style/sources/Source;"), - MAKE_NATIVE_METHOD(nativeAddSource, "(JJ)V"), - MAKE_NATIVE_METHOD(nativeRemoveSourceById, "(JLjava/lang/String;)V"), - MAKE_NATIVE_METHOD(nativeRemoveSource, "(JJ)V"), - MAKE_NATIVE_METHOD(nativeAddImage, "(JLjava/lang/String;IIF[B)V"), - MAKE_NATIVE_METHOD(nativeRemoveImage, "(JLjava/lang/String;)V"), - MAKE_NATIVE_METHOD(nativeSetContentPadding, "(JDDDD)V"), - MAKE_NATIVE_METHOD(nativeScheduleTakeSnapshot, "(J)V"), - MAKE_NATIVE_METHOD(nativeQueryRenderedFeaturesForPoint, "(JFF[Ljava/lang/String;)[Lcom/mapbox/services/commons/geojson/Feature;"), - MAKE_NATIVE_METHOD(nativeQueryRenderedFeaturesForBox, "(JFFFF[Ljava/lang/String;)[Lcom/mapbox/services/commons/geojson/Feature;"), - MAKE_NATIVE_METHOD(nativeSetAPIBaseURL, "(JLjava/lang/String;)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"; } - }; - - struct ResourceTransformCallback { - static constexpr auto Name() { return "com/mapbox/mapboxsdk/offline/OfflineManager$ResourceTransformCallback"; } - }; - }; - - struct OfflineRegion { - static constexpr auto Name() { return "com/mapbox/mapboxsdk/offline/OfflineRegion"; } - }; - - jni::Class offlineManagerClass = jni::Class::Find(env); - offlineManagerClassPtrId = &jni::GetFieldID(env, offlineManagerClass, "mDefaultFileSourcePtr", "J"); - - jni::RegisterNatives(env, offlineManagerClass, - MAKE_NATIVE_METHOD(sharedDefaultFileSource, "(Ljava/lang/String;Ljava/lang/String;)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(setResourceTransform, "(JLcom/mapbox/mapboxsdk/offline/OfflineManager$ResourceTransformCallback;)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"); - - jni::Class resourceTransformCallbackClass = jni::Class::Find(env); - transformOnURLMethodId = &jni::GetMethodID(env, resourceTransformCallbackClass, "onURL", "(ILjava/lang/String;)Ljava/lang/String;"); - - 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, "()V"), - MAKE_NATIVE_METHOD(setOfflineRegionObserver, "(Lcom/mapbox/mapboxsdk/offline/OfflineRegion$OfflineRegionObserver;)V"), - MAKE_NATIVE_METHOD(setOfflineRegionDownloadState, "(I)V"), - MAKE_NATIVE_METHOD(getOfflineRegionStatus, "(Lcom/mapbox/mapboxsdk/offline/OfflineRegion$OfflineRegionStatusCallback;)V"), - MAKE_NATIVE_METHOD(deleteOfflineRegion, "(Lcom/mapbox/mapboxsdk/offline/OfflineRegion$OfflineRegionDeleteCallback;)V"), - MAKE_NATIVE_METHOD(updateOfflineRegionMetadata, "([BLcom/mapbox/mapboxsdk/offline/OfflineRegion$OfflineRegionUpdateMetadataCallback;)V") - ); - - // 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"); - offlineRegionStatusCompletedTileCountId = &jni::GetFieldID(env, *offlineRegionStatusClass, "completedTileCount", "J"); - offlineRegionStatusCompletedTileSizeId = &jni::GetFieldID(env, *offlineRegionStatusClass, "completedTileSize", "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"); - - jni::jclass* offlineRegionUpdateMetadataCallbackClass = &jni::FindClass(env, "com/mapbox/mapboxsdk/offline/OfflineRegion$OfflineRegionUpdateMetadataCallback"); - updateMetadataOnUpdateMethodId = &jni::GetMethodID(env, *offlineRegionUpdateMetadataCallbackClass, "onUpdate", "([B)V"); - updateMetadataOnErrorMethodId = &jni::GetMethodID(env, *offlineRegionUpdateMetadataCallbackClass, "onError", "(Ljava/lang/String;)V"); - - // Offline end - - char release[PROP_VALUE_MAX] = ""; - __system_property_get("ro.build.version.release", release); - androidRelease = std::string(release); + // Offline + OfflineManager::registerNative(env); + OfflineRegion::registerNative(env); + OfflineRegionDefinition::registerNative(env); + OfflineTilePyramidRegionDefinition::registerNative(env); + OfflineRegionError::registerNative(env); + OfflineRegionStatus::registerNative(env); } } // namespace android -- cgit v1.2.1