#include #include #include #include #include #include #include #include #include #include "log.h" #include "NativeMapView.hpp" #pragma clang diagnostic ignored "-Wunused-parameter" namespace mbgl { namespace android { jmethodID on_map_changed_id = nullptr; jclass lon_lat_class = nullptr; jmethodID lon_lat_constructor_id = nullptr; jfieldID lon_lat_lon_id = nullptr; jfieldID lon_lat_lat_id = nullptr; jclass lon_lat_zoom_class = nullptr; jmethodID lon_lat_zoom_constructor_id = nullptr; jfieldID lon_lat_zoom_lon_id = nullptr; jfieldID lon_lat_zoom_lat_id = nullptr; jfieldID lon_lat_zoom_zoom_id = nullptr; jclass runtime_exception_class = nullptr; jmethodID set_to_array_id = nullptr; jclass tree_set_class = nullptr; jmethodID tree_set_constructor_id = nullptr; jmethodID tree_set_add_id = nullptr; bool throw_error(JNIEnv* env, const char* msg) { if (env->ThrowNew(runtime_exception_class, msg) < 0) { env->ExceptionDescribe(); return false; } return true; } std::string std_string_from_jstring(JNIEnv* env, jstring jstr) { std::string str; jsize len = env->GetStringLength(jstr); if (len < 0) { env->ExceptionDescribe(); return str; } const jchar* chars = env->GetStringChars(jstr, nullptr); if (chars == nullptr) { env->ExceptionDescribe(); return str; } std::u16string ustr(reinterpret_cast(chars), len); env->ReleaseStringChars(jstr, chars); chars = nullptr; str = std::wstring_convert,char16_t>().to_bytes(ustr); return str; } jstring std_string_to_jstring(JNIEnv* env, std::string str) { std::u16string ustr = std::wstring_convert,char16_t>().from_bytes(str); jstring jstr = env->NewString(reinterpret_cast(ustr.c_str()), ustr.size()); if (jstr == nullptr) { env->ExceptionDescribe(); return nullptr; } return jstr; } // TODO: change from Java TreeSet to ArrayList std::vector std_vector_string_from_jobject(JNIEnv* env, jobject jset) { std::vector vector; jobjectArray array = reinterpret_cast(env->CallObjectMethod(jset, set_to_array_id)); if (env->ExceptionCheck() || (array == nullptr)) { env->ExceptionDescribe(); return vector; } jsize len = env->GetArrayLength(array); if (len < 0) { env->ExceptionDescribe(); return vector; } for (jsize i = 0; i < len; i++) { jstring jstr = reinterpret_cast(env->GetObjectArrayElement(array, i)); if (jstr == nullptr) { env->ExceptionDescribe(); return vector; } vector.push_back(std_string_from_jstring(env, jstr)); } return vector; } // TODO: change from Java TreeSet to ArrayList jobject std_vector_string_to_jobject(JNIEnv* env, std::vector vector) { jobject jset = env->NewObject(tree_set_class, tree_set_constructor_id); if (jset == nullptr) { env->ExceptionDescribe(); return nullptr; } for (std::string str : vector) { env->CallBooleanMethod(jset, tree_set_add_id, std_string_to_jstring(env, str)); if (env->ExceptionCheck()) { env->ExceptionDescribe(); return nullptr; } } return jset; } } // namespace android } // namespace mbgl namespace { using namespace mbgl::android; // TODO: wrap C++ exceptions? // TODO: wrap other sorts of exceptions? eg coffee catch jlong JNICALL nativeCreate(JNIEnv* env, jobject obj, jstring default_style_json) { VERBOSE("nativeCreate"); NativeMapView* native_map_view = new NativeMapView(env, obj, std_string_from_jstring(env, default_style_json)); if (native_map_view == nullptr) { throw_error(env, "Unable to create NativeMapView."); return 0; } jlong map_view_ptr = reinterpret_cast(native_map_view); return map_view_ptr; } void JNICALL nativeDestroy(JNIEnv* env, jobject obj, jlong native_map_view_ptr) { VERBOSE("nativeDestroy"); ASSERT(native_map_view_ptr != 0); NativeMapView* native_map_view = reinterpret_cast(native_map_view_ptr); delete native_map_view; native_map_view = nullptr; } void JNICALL nativeInitializeDisplay(JNIEnv* env, jobject obj, jlong native_map_view_ptr) { VERBOSE("nativeInitializeDisplay"); ASSERT(native_map_view_ptr != 0); NativeMapView* native_map_view = reinterpret_cast(native_map_view_ptr); if (!native_map_view->initializeDisplay()) { throw_error(env, "Unable to initialize GL display."); } } void JNICALL nativeTerminateDisplay(JNIEnv* env, jobject obj, jlong native_map_view_ptr) { VERBOSE("nativeTerminateDisplay"); ASSERT(native_map_view_ptr != 0); NativeMapView* native_map_view = reinterpret_cast(native_map_view_ptr); native_map_view->terminateDisplay(); } void JNICALL nativeInitializeContext(JNIEnv* env, jobject obj, jlong native_map_view_ptr) { VERBOSE("nativeInitializeContext"); ASSERT(native_map_view_ptr != 0); NativeMapView* native_map_view = reinterpret_cast(native_map_view_ptr); if (!native_map_view->initializeContext()) { throw_error(env, "Unable to initialize GL context."); } } void JNICALL nativeTerminateContext(JNIEnv* env, jobject obj, jlong native_map_view_ptr) { VERBOSE("nativeTerminateContext"); ASSERT(native_map_view_ptr != 0); NativeMapView* native_map_view = reinterpret_cast(native_map_view_ptr); native_map_view->terminateContext(); } void JNICALL nativeCreateSurface(JNIEnv* env, jobject obj, jlong native_map_view_ptr, jobject surface) { VERBOSE("nativeCreateSurface"); ASSERT(native_map_view_ptr != 0); NativeMapView* native_map_view = reinterpret_cast(native_map_view_ptr); if (!native_map_view->createSurface(ANativeWindow_fromSurface(env, surface))) { throw_error(env, "Unable to create GL surface."); } } void JNICALL nativeDestroySurface(JNIEnv* env, jobject obj, jlong native_map_view_ptr) { VERBOSE("nativeDestroySurface"); ASSERT(native_map_view_ptr != 0); NativeMapView* native_map_view = reinterpret_cast(native_map_view_ptr); native_map_view->destroySurface(); } void JNICALL nativeStart(JNIEnv* env, jobject obj, jlong native_map_view_ptr) { VERBOSE("nativeStart"); ASSERT(native_map_view_ptr != 0); NativeMapView* native_map_view = reinterpret_cast(native_map_view_ptr); native_map_view->start(); } void JNICALL nativeStop(JNIEnv* env, jobject obj, jlong native_map_view_ptr) { VERBOSE("nativeStop"); ASSERT(native_map_view_ptr != 0); NativeMapView* native_map_view = reinterpret_cast(native_map_view_ptr); native_map_view->stop(); } void JNICALL nativeRerender(JNIEnv* env, jobject obj, jlong native_map_view_ptr) { VERBOSE("nativeRerender"); ASSERT(native_map_view_ptr != 0); NativeMapView* native_map_view = reinterpret_cast(native_map_view_ptr); native_map_view->getMap()->rerender(); } void JNICALL nativeUpdate(JNIEnv* env, jobject obj, jlong native_map_view_ptr) { VERBOSE("nativeUpdate"); ASSERT(native_map_view_ptr != 0); NativeMapView* native_map_view = reinterpret_cast(native_map_view_ptr); native_map_view->getMap()->update(); } void JNICALL nativeCleanup(JNIEnv* env, jobject obj, jlong native_map_view_ptr) { VERBOSE("nativeCleanup"); ASSERT(native_map_view_ptr != 0); NativeMapView* native_map_view = reinterpret_cast(native_map_view_ptr); native_map_view->getMap()->cleanup(); } // TODO remove these? void JNICALL nativeAddDefaultSource(JNIEnv* env, jobject obj, jlong native_map_view_ptr) { VERBOSE("nativeAddDefaultSource"); ASSERT(native_map_view_ptr != 0); // NativeMapView* native_map_view = reinterpret_cast(native_map_view_ptr); // native_map_view->getMap()->addDefaultSource(); } void JNICALL nativeRemoveDefaultSource(JNIEnv* env, jobject obj, jlong native_map_view_ptr) { VERBOSE("nativeRemoveDefaultSource"); ASSERT(native_map_view_ptr != 0); // NativeMapView* native_map_view = reinterpret_cast(native_map_view_ptr); // native_map_view->getMap()->removeDefaultSource(); } void JNICALL nativeAddSource(JNIEnv* env, jobject obj, jlong native_map_view_ptr, jstring name, jstring url) { VERBOSE("nativeAddSource"); ASSERT(native_map_view_ptr != 0); // NativeMapView* native_map_view = reinterpret_cast(native_map_view_ptr); // native_map_view->getMap()->addSource(std_string_from_jstring(env, name), std_string_from_jstring(env, url)); } void JNICALL nativeRemoveSource(JNIEnv* env, jobject obj, jlong native_map_view_ptr, jstring name) { VERBOSE("nativeRemoveSource"); ASSERT(native_map_view_ptr != 0); // NativeMapView* native_map_view = reinterpret_cast(native_map_view_ptr); // native_map_view->getMap()->removeSource(std_string_from_jstring(env, name)); } void JNICALL nativeResize(JNIEnv* env, jobject obj, jlong native_map_view_ptr, jint width, jint height, jfloat ratio) { VERBOSE("nativeResize"); ASSERT(native_map_view_ptr != 0); ASSERT(width >= 0); ASSERT(height >= 0); ASSERT(width <= UINT16_MAX); ASSERT(height <= UINT16_MAX); NativeMapView* native_map_view = reinterpret_cast(native_map_view_ptr); native_map_view->getMap()->resize(width, height, ratio); } void JNICALL nativeResize(JNIEnv* env, jobject obj, jlong native_map_view_ptr, jint width, jint height, jfloat ratio, jint fb_width, jint fb_height) { VERBOSE("nativeResize"); ASSERT(native_map_view_ptr != 0); ASSERT(width >= 0); ASSERT(height >= 0); ASSERT(width <= UINT16_MAX); ASSERT(height <= UINT16_MAX); ASSERT(fb_width >= 0); ASSERT(fb_height >= 0); ASSERT(fb_width <= UINT16_MAX); ASSERT(fb_height <= UINT16_MAX); NativeMapView* native_map_view = reinterpret_cast(native_map_view_ptr); native_map_view->getMap()->resize(width, height, ratio, fb_width, fb_height); } void JNICALL nativeSetAppliedClasses(JNIEnv* env, jobject obj, jlong native_map_view_ptr, jobject applied_classes) { VERBOSE("nativeSetAppliedClasses"); ASSERT(native_map_view_ptr != 0); NativeMapView* native_map_view = reinterpret_cast(native_map_view_ptr); native_map_view->getMap()->setAppliedClasses(std_vector_string_from_jobject(env, applied_classes)); } jobject JNICALL nativeGetAppliedClasses(JNIEnv* env, jobject obj, jlong native_map_view_ptr) { VERBOSE("nativeGetAppliedClasses"); ASSERT(native_map_view_ptr != 0); NativeMapView* native_map_view = reinterpret_cast(native_map_view_ptr); return std_vector_string_to_jobject(env, native_map_view->getMap()->getAppliedClasses()); } void JNICALL nativeSetDefaultTransitionDuration(JNIEnv* env, jobject obj, jlong native_map_view_ptr, jlong duration_milliseconds) { VERBOSE("nativeSetDefaultTransitionDuration"); ASSERT(native_map_view_ptr != 0); ASSERT(duration_milliseconds >= 0); //ASSERT(duration_milliseconds <= UINT64_MAX); NativeMapView* native_map_view = reinterpret_cast(native_map_view_ptr); native_map_view->getMap()->setDefaultTransitionDuration(duration_milliseconds); } void JNICALL nativeSetStyleJSON(JNIEnv* env, jobject obj, jlong native_map_view_ptr, jstring new_style_json) { VERBOSE("nativeSetStyleJSON"); ASSERT(native_map_view_ptr != 0); NativeMapView* native_map_view = reinterpret_cast(native_map_view_ptr); native_map_view->getMap()->setStyleJSON(std_string_from_jstring(env, new_style_json)); } jstring JNICALL nativeGetStyleJSON(JNIEnv* env, jobject obj, jlong native_map_view_ptr) { VERBOSE("nativeGetStyleJSON"); ASSERT(native_map_view_ptr != 0); NativeMapView* native_map_view = reinterpret_cast(native_map_view_ptr); return std_string_to_jstring(env, native_map_view->getMap()->getStyleJSON()); } void JNICALL nativeCancelTransitions(JNIEnv* env, jobject obj, jlong native_map_view_ptr) { VERBOSE("nativeCancelTransitions"); ASSERT(native_map_view_ptr != 0); NativeMapView* native_map_view = reinterpret_cast(native_map_view_ptr); native_map_view->getMap()->cancelTransitions(); } void JNICALL nativeMoveBy(JNIEnv* env, jobject obj, jlong native_map_view_ptr, jdouble dx, jdouble dy, jdouble duration) { VERBOSE("nativeMoveBy"); ASSERT(native_map_view_ptr != 0); NativeMapView* native_map_view = reinterpret_cast(native_map_view_ptr); native_map_view->getMap()->moveBy(dx, dy, duration); } void JNICALL nativeSetLonLat(JNIEnv* env, jobject obj, jlong native_map_view_ptr, jobject lon_lat, jdouble duration) { VERBOSE("nativeSetLonLat"); ASSERT(native_map_view_ptr != 0); NativeMapView* native_map_view = reinterpret_cast(native_map_view_ptr); double lon = env->GetDoubleField(lon_lat, lon_lat_lon_id); if (env->ExceptionCheck()) { env->ExceptionDescribe(); return; } double lat = env->GetDoubleField(lon_lat, lon_lat_lat_id); if (env->ExceptionCheck()) { env->ExceptionDescribe(); return; } // TODO remove when fixed DEBUG("lon lat %f %f", lon, lat); native_map_view->getMap()->setLonLat(lon, lat, duration); } jobject JNICALL nativeGetLonLat(JNIEnv* env, jobject obj, jlong native_map_view_ptr) { VERBOSE("nativeGetLonLat"); ASSERT(native_map_view_ptr != 0); NativeMapView* native_map_view = reinterpret_cast(native_map_view_ptr); double lon, lat; native_map_view->getMap()->getLonLat(lon, lat); jobject ret = env->NewObject(lon_lat_class, lon_lat_constructor_id, lon, lat); if (ret == nullptr) { env->ExceptionDescribe(); return nullptr; } return ret; } void JNICALL nativeStartPanning(JNIEnv* env, jobject obj, jlong native_map_view_ptr) { VERBOSE("nativeStartPanning"); ASSERT(native_map_view_ptr != 0); NativeMapView* native_map_view = reinterpret_cast(native_map_view_ptr); native_map_view->getMap()->startPanning(); } void JNICALL nativeStopPanning(JNIEnv* env, jobject obj, jlong native_map_view_ptr) { VERBOSE("nativeStopPanning"); ASSERT(native_map_view_ptr != 0); NativeMapView* native_map_view = reinterpret_cast(native_map_view_ptr); native_map_view->getMap()->stopPanning(); } void JNICALL nativeResetPosition(JNIEnv* env, jobject obj, jlong native_map_view_ptr) { VERBOSE("nativeResetPosition"); ASSERT(native_map_view_ptr != 0); NativeMapView* native_map_view = reinterpret_cast(native_map_view_ptr); native_map_view->getMap()->resetPosition(); } void JNICALL nativeScaleBy(JNIEnv* env, jobject obj, jlong native_map_view_ptr, jdouble ds, jdouble cx, jdouble cy, jdouble duration) { VERBOSE("nativeScaleBy"); ASSERT(native_map_view_ptr != 0); NativeMapView* native_map_view = reinterpret_cast(native_map_view_ptr); native_map_view->getMap()->scaleBy(ds, cx, cy, duration); } void JNICALL nativeSetScale(JNIEnv* env, jobject obj, jlong native_map_view_ptr, jdouble scale, jdouble cx, jdouble cy, jdouble duration) { VERBOSE("nativeSetScale"); ASSERT(native_map_view_ptr != 0); NativeMapView* native_map_view = reinterpret_cast(native_map_view_ptr); native_map_view->getMap()->setScale(scale, cx, cy, duration); } jdouble JNICALL nativeGetScale(JNIEnv* env, jobject obj, jlong native_map_view_ptr) { VERBOSE("nativeGetScale"); ASSERT(native_map_view_ptr != 0); NativeMapView* native_map_view = reinterpret_cast(native_map_view_ptr); return native_map_view->getMap()->getScale(); } void JNICALL nativeSetZoom(JNIEnv* env, jobject obj, jlong native_map_view_ptr, jdouble zoom, jdouble duration) { VERBOSE("nativeSetZoom"); ASSERT(native_map_view_ptr != 0); NativeMapView* native_map_view = reinterpret_cast(native_map_view_ptr); native_map_view->getMap()->setZoom(zoom, duration); } jdouble JNICALL nativeGetZoom(JNIEnv* env, jobject obj, jlong native_map_view_ptr) { VERBOSE("nativeGetZoom"); ASSERT(native_map_view_ptr != 0); NativeMapView* native_map_view = reinterpret_cast(native_map_view_ptr); return native_map_view->getMap()->getZoom(); } void JNICALL nativeSetLonLatZoom(JNIEnv* env, jobject obj, jlong native_map_view_ptr, jobject lon_lat_zoom, jdouble duration) { VERBOSE("nativeSetLonLatZoom"); ASSERT(native_map_view_ptr != 0); NativeMapView* native_map_view = reinterpret_cast(native_map_view_ptr); double lon = env->GetDoubleField(lon_lat_zoom, lon_lat_zoom_lon_id); if (env->ExceptionCheck()) { env->ExceptionDescribe(); return; } double lat = env->GetDoubleField(lon_lat_zoom, lon_lat_zoom_lat_id); if (env->ExceptionCheck()) { env->ExceptionDescribe(); return; } double zoom = env->GetDoubleField(lon_lat_zoom, lon_lat_zoom_zoom_id); if (env->ExceptionCheck()) { env->ExceptionDescribe(); return; } native_map_view->getMap()->setLonLatZoom(lon, lat, zoom, duration); } jobject JNICALL nativeGetLonLatZoom(JNIEnv* env, jobject obj, jlong native_map_view_ptr) { VERBOSE("nativeGetLonLatZoom"); ASSERT(native_map_view_ptr != 0); NativeMapView* native_map_view = reinterpret_cast(native_map_view_ptr); double lon, lat, zoom; native_map_view->getMap()->getLonLatZoom(lon, lat, zoom); jobject ret = env->NewObject(lon_lat_zoom_class, lon_lat_zoom_constructor_id, lon, lat, zoom); if (ret == nullptr) { env->ExceptionDescribe(); return nullptr; } return ret; } void JNICALL nativeResetZoom(JNIEnv* env, jobject obj, jlong native_map_view_ptr) { VERBOSE("nativeResetZoom"); ASSERT(native_map_view_ptr != 0); NativeMapView* native_map_view = reinterpret_cast(native_map_view_ptr); native_map_view->getMap()->resetZoom(); } void JNICALL nativeStartScaling(JNIEnv* env, jobject obj, jlong native_map_view_ptr) { VERBOSE("nativeStartScaling"); ASSERT(native_map_view_ptr != 0); NativeMapView* native_map_view = reinterpret_cast(native_map_view_ptr); native_map_view->getMap()->startScaling(); } void JNICALL nativeStopScaling(JNIEnv* env, jobject obj, jlong native_map_view_ptr) { VERBOSE("nativeStopScaling"); ASSERT(native_map_view_ptr != 0); NativeMapView* native_map_view = reinterpret_cast(native_map_view_ptr); native_map_view->getMap()->stopScaling(); } jdouble JNICALL nativeGetMinZoom(JNIEnv* env, jobject obj, jlong native_map_view_ptr) { VERBOSE("nativeGetMinZoom"); ASSERT(native_map_view_ptr != 0); NativeMapView* native_map_view = reinterpret_cast(native_map_view_ptr); return native_map_view->getMap()->getMinZoom(); } jdouble JNICALL nativeGetMaxZoom(JNIEnv* env, jobject obj, jlong native_map_view_ptr) { VERBOSE("nativeGetMaxZoom"); ASSERT(native_map_view_ptr != 0); NativeMapView* native_map_view = reinterpret_cast(native_map_view_ptr); return native_map_view->getMap()->getMaxZoom(); } void JNICALL nativeRotateBy(JNIEnv* env, jobject obj, jlong native_map_view_ptr, jdouble sx, jdouble sy, jdouble ex, jdouble ey, jdouble duration) { VERBOSE("nativeRotateBy"); ASSERT(native_map_view_ptr != 0); NativeMapView* native_map_view = reinterpret_cast(native_map_view_ptr); native_map_view->getMap()->rotateBy(sx, sy, ex, ey, duration); } void JNICALL nativeSetAngle(JNIEnv* env, jobject obj, jlong native_map_view_ptr, jdouble angle, jdouble duration) { VERBOSE("nativeSetAngle"); ASSERT(native_map_view_ptr != 0); NativeMapView* native_map_view = reinterpret_cast(native_map_view_ptr); // TODO update java class //native_map_view->getMap()->setAngle(angle, duration); double degrees = -angle / M_PI * 180; native_map_view->getMap()->setBearing(degrees, duration); } void JNICALL nativeSetAngle(JNIEnv* env, jobject obj, jlong native_map_view_ptr, jdouble angle, jdouble cx, jdouble cy) { VERBOSE("nativeSetAngle"); ASSERT(native_map_view_ptr != 0); NativeMapView* native_map_view = reinterpret_cast(native_map_view_ptr); // TODO update java class //native_map_view->getMap()->setAngle(angle, cx, cy); double degrees = -angle / M_PI * 180; native_map_view->getMap()->setBearing(degrees, cx, cy); } jdouble JNICALL nativeGetAngle(JNIEnv* env, jobject obj, jlong native_map_view_ptr) { VERBOSE("nativeGetAngle"); ASSERT(native_map_view_ptr != 0); NativeMapView* native_map_view = reinterpret_cast(native_map_view_ptr); // TODO update java class //return native_map_view->getMap()->getAngle(); double degrees = native_map_view->getMap()->getBearing(); return -degrees * M_PI / 180; } void JNICALL nativeResetNorth(JNIEnv* env, jobject obj, jlong native_map_view_ptr) { VERBOSE("nativeResetNorth"); ASSERT(native_map_view_ptr != 0); NativeMapView* native_map_view = reinterpret_cast(native_map_view_ptr); native_map_view->getMap()->resetNorth(); } void JNICALL nativeStartRotating(JNIEnv* env, jobject obj, jlong native_map_view_ptr) { VERBOSE("nativeStartRotating"); ASSERT(native_map_view_ptr != 0); NativeMapView* native_map_view = reinterpret_cast(native_map_view_ptr); native_map_view->getMap()->startRotating(); } void JNICALL nativeStopRotating(JNIEnv* env, jobject obj, jlong native_map_view_ptr) { VERBOSE("nativeStopRotating"); ASSERT(native_map_view_ptr != 0); NativeMapView* native_map_view = reinterpret_cast(native_map_view_ptr); native_map_view->getMap()->stopRotating(); } jboolean JNICALL nativeCanRotate(JNIEnv* env, jobject obj, jlong native_map_view_ptr) { VERBOSE("nativeCanRotate"); ASSERT(native_map_view_ptr != 0); NativeMapView* native_map_view = reinterpret_cast(native_map_view_ptr); return native_map_view->getMap()->canRotate(); } void JNICALL nativeSetDebug(JNIEnv* env, jobject obj, jlong native_map_view_ptr, jboolean debug) { VERBOSE("nativeSetDebug"); ASSERT(native_map_view_ptr != 0); NativeMapView* native_map_view = reinterpret_cast(native_map_view_ptr); native_map_view->getMap()->setDebug(debug); } void JNICALL nativeToggleDebug(JNIEnv* env, jobject obj, jlong native_map_view_ptr) { VERBOSE("nativeToggleDebug"); ASSERT(native_map_view_ptr != 0); NativeMapView* native_map_view = reinterpret_cast(native_map_view_ptr); native_map_view->getMap()->toggleDebug(); } jboolean JNICALL nativeGetDebug(JNIEnv* env, jobject obj, jlong native_map_view_ptr) { VERBOSE("nativeGetDebug"); ASSERT(native_map_view_ptr != 0); NativeMapView* native_map_view = reinterpret_cast(native_map_view_ptr); return native_map_view->getMap()->getDebug(); } } // namespace extern "C" { extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) { VERBOSE("JNI_OnLoad"); JNIEnv* env = nullptr; if (vm->GetEnv(reinterpret_cast(&env), JNI_VERSION_1_6) != JNI_OK) { ERROR("GetEnv() failed"); return JNI_ERR; } lon_lat_class = env->FindClass("com/mapbox/mapboxgl/lib/LonLat"); if (lon_lat_class == nullptr) { env->ExceptionDescribe(); return JNI_ERR; } lon_lat_constructor_id = env->GetMethodID(lon_lat_class, "", "(DD)V"); if (lon_lat_constructor_id == nullptr) { env->ExceptionDescribe(); return JNI_ERR; } lon_lat_lon_id = env->GetFieldID(lon_lat_class, "lon", "D"); if (lon_lat_lon_id == nullptr) { env->ExceptionDescribe(); return JNI_ERR; } lon_lat_lat_id = env->GetFieldID(lon_lat_class, "lat", "D"); if (lon_lat_lat_id == nullptr) { env->ExceptionDescribe(); return JNI_ERR; } lon_lat_zoom_class = env->FindClass("com/mapbox/mapboxgl/lib/LonLatZoom"); if (lon_lat_class == nullptr) { env->ExceptionDescribe(); return JNI_ERR; } lon_lat_zoom_constructor_id = env->GetMethodID(lon_lat_zoom_class, "", "(DDD)V"); if (lon_lat_zoom_constructor_id == nullptr) { env->ExceptionDescribe(); return JNI_ERR; } lon_lat_zoom_lon_id = env->GetFieldID(lon_lat_zoom_class, "lon", "D"); if (lon_lat_zoom_lon_id == nullptr) { env->ExceptionDescribe(); return JNI_ERR; } lon_lat_zoom_lat_id = env->GetFieldID(lon_lat_zoom_class, "lat", "D"); if (lon_lat_zoom_lat_id == nullptr) { env->ExceptionDescribe(); return JNI_ERR; } lon_lat_zoom_zoom_id = env->GetFieldID(lon_lat_zoom_class, "zoom", "D"); if (lon_lat_zoom_zoom_id == nullptr) { env->ExceptionDescribe(); return JNI_ERR; } jclass native_map_view_class = env->FindClass("com/mapbox/mapboxgl/lib/NativeMapView"); if (native_map_view_class == nullptr) { env->ExceptionDescribe(); return JNI_ERR; } on_map_changed_id = env->GetMethodID(native_map_view_class, "onMapChanged", "()V"); if (on_map_changed_id == nullptr) { env->ExceptionDescribe(); return JNI_ERR; } runtime_exception_class = env->FindClass("java/lang/RuntimeException"); if (runtime_exception_class == nullptr) { env->ExceptionDescribe(); return JNI_ERR; } jclass set_class = env->FindClass("java/util/Set"); if (set_class == nullptr) { env->ExceptionDescribe(); return JNI_ERR; } set_to_array_id = env->GetMethodID(set_class, "toArray", "()[Ljava/lang/Object;"); if (set_to_array_id == nullptr) { env->ExceptionDescribe(); return JNI_ERR; } tree_set_class = env->FindClass("java/util/TreeSet"); if (tree_set_class == nullptr) { env->ExceptionDescribe(); return JNI_ERR; } tree_set_constructor_id = env->GetMethodID(tree_set_class, "", "()V"); if (tree_set_constructor_id == nullptr) { env->ExceptionDescribe(); return JNI_ERR; } tree_set_add_id = env->GetMethodID(tree_set_class, "add", "(Ljava/lang/Object;)Z"); if (tree_set_add_id == nullptr) { env->ExceptionDescribe(); return JNI_ERR; } std::array methods = {{ // Can remove the extra brace in C++14 { "nativeCreate", "(Ljava/lang/String;)J", reinterpret_cast(&nativeCreate) }, { "nativeDestroy", "(J)V", reinterpret_cast(&nativeDestroy) }, { "nativeInitializeDisplay", "(J)V", reinterpret_cast(&nativeInitializeDisplay) }, { "nativeTerminateDisplay", "(J)V", reinterpret_cast(&nativeTerminateDisplay) }, { "nativeInitializeContext", "(J)V", reinterpret_cast(&nativeInitializeContext) }, { "nativeTerminateContext", "(J)V", reinterpret_cast(&nativeTerminateContext) }, { "nativeCreateSurface", "(JLandroid/view/Surface;)V", reinterpret_cast(&nativeCreateSurface) }, { "nativeDestroySurface", "(J)V", reinterpret_cast(&nativeDestroySurface) }, { "nativeStart", "(J)V", reinterpret_cast(&nativeStart) }, { "nativeStop", "(J)V", reinterpret_cast(&nativeStop) }, { "nativeRerender", "(J)V", reinterpret_cast(&nativeRerender) }, { "nativeUpdate", "(J)V", reinterpret_cast(&nativeUpdate) }, { "nativeCleanup", "(J)V", reinterpret_cast(&nativeCleanup) }, { "nativeAddDefaultSource", "(J)V", reinterpret_cast(&nativeAddDefaultSource) }, { "nativeRemoveDefaultSource", "(J)V", reinterpret_cast(&nativeRemoveDefaultSource) }, { "nativeAddSource", "(JLjava/lang/String;Ljava/lang/String;)V", reinterpret_cast(&nativeAddSource) }, { "nativeRemoveSource", "(JLjava/lang/String;)V", reinterpret_cast(&nativeRemoveSource) }, { "nativeResize", "(JIIF)V", reinterpret_cast(static_cast(&nativeResize)) }, { "nativeResize", "(JIIFII)V", reinterpret_cast(static_cast(&nativeResize)) }, { "nativeSetAppliedClasses", "(JLjava/util/Set;)V", reinterpret_cast(&nativeSetAppliedClasses) }, { "nativeGetAppliedClasses", "(J)Ljava/util/Set;", reinterpret_cast(&nativeGetAppliedClasses) }, { "nativeSetDefaultTransitionDuration", "(JJ)V", reinterpret_cast(&nativeSetDefaultTransitionDuration) }, { "nativeSetStyleJSON", "(JLjava/lang/String;)V", reinterpret_cast(&nativeSetStyleJSON) }, { "nativeGetStyleJSON", "(J)Ljava/lang/String;", reinterpret_cast(&nativeGetStyleJSON) }, { "nativeCancelTransitions", "(J)V", reinterpret_cast(&nativeCancelTransitions) }, { "nativeMoveBy", "(JDDD)V", reinterpret_cast(&nativeMoveBy) }, { "nativeSetLonLat", "(JLcom/mapbox/mapboxgl/lib/LonLat;D)V", reinterpret_cast(&nativeSetLonLat) }, { "nativeGetLonLat", "(J)Lcom/mapbox/mapboxgl/lib/LonLat;", reinterpret_cast(&nativeGetLonLat) }, { "nativeStartPanning", "(J)V", reinterpret_cast(&nativeStartPanning) }, { "nativeStopPanning", "(J)V", reinterpret_cast(&nativeStopPanning) }, { "nativeResetPosition", "(J)V", reinterpret_cast(&nativeResetPosition) }, { "nativeScaleBy", "(JDDDD)V", reinterpret_cast(&nativeScaleBy) }, { "nativeSetScale", "(JDDDD)V", reinterpret_cast(&nativeSetScale) }, { "nativeGetScale", "(J)D", reinterpret_cast(&nativeGetScale) }, { "nativeSetZoom", "(JDD)V", reinterpret_cast(&nativeSetZoom) }, { "nativeGetZoom", "(J)D", reinterpret_cast(&nativeGetZoom) }, { "nativeSetLonLatZoom", "(JLcom/mapbox/mapboxgl/lib/LonLatZoom;D)V", reinterpret_cast(&nativeSetLonLatZoom) }, { "nativeGetLonLatZoom", "(J)Lcom/mapbox/mapboxgl/lib/LonLatZoom;", reinterpret_cast(&nativeGetLonLatZoom) }, { "nativeResetZoom", "(J)V", reinterpret_cast(&nativeResetZoom) }, { "nativeStartPanning", "(J)V", reinterpret_cast(&nativeStartScaling) }, { "nativeStopPanning", "(J)V", reinterpret_cast(&nativeStopScaling) }, { "nativeGetMinZoom", "(J)D", reinterpret_cast(&nativeGetMinZoom) }, { "nativeGetMaxZoom", "(J)D", reinterpret_cast(&nativeGetMaxZoom) }, { "nativeRotateBy", "(JDDDDD)V", reinterpret_cast(&nativeRotateBy) }, { "nativeSetAngle", "(JDD)V", reinterpret_cast(static_cast(&nativeSetAngle)) }, { "nativeSetAngle", "(JDDD)V", reinterpret_cast(static_cast(&nativeSetAngle)) }, { "nativeGetAngle", "(J)D", reinterpret_cast(&nativeGetAngle) }, { "nativeResetNorth", "(J)V", reinterpret_cast(&nativeResetNorth) }, { "nativeStartRotating", "(J)V", reinterpret_cast(&nativeStartRotating) }, { "nativeStopRotating", "(J)V", reinterpret_cast(&nativeStopRotating) }, { "nativeCanRotate", "(J)Z", reinterpret_cast(&nativeCanRotate) }, { "nativeSetDebug", "(JZ)V", reinterpret_cast(&nativeSetDebug) }, { "nativeToggleDebug", "(J)V", reinterpret_cast(&nativeToggleDebug) }, { "nativeGetDebug", "(J)Z", reinterpret_cast(&nativeGetDebug) } }}; if (env->RegisterNatives(native_map_view_class, methods.data(), methods.size()) < 0) { env->ExceptionDescribe(); return JNI_ERR; } lon_lat_class = reinterpret_cast(env->NewGlobalRef(lon_lat_class)); if (lon_lat_class == nullptr) { env->ExceptionDescribe(); return JNI_ERR; } lon_lat_zoom_class = reinterpret_cast(env->NewGlobalRef(lon_lat_zoom_class)); if (lon_lat_zoom_class == nullptr) { env->ExceptionDescribe(); env->DeleteGlobalRef(lon_lat_class); return JNI_ERR; } runtime_exception_class = reinterpret_cast(env->NewGlobalRef(runtime_exception_class)); if (runtime_exception_class == nullptr) { env->ExceptionDescribe(); env->DeleteGlobalRef(lon_lat_class); env->DeleteGlobalRef(lon_lat_zoom_class); return JNI_ERR; } tree_set_class = reinterpret_cast(env->NewGlobalRef(tree_set_class)); if (tree_set_class == nullptr) { env->ExceptionDescribe(); env->DeleteGlobalRef(lon_lat_class); env->DeleteGlobalRef(lon_lat_zoom_class); env->DeleteGlobalRef(runtime_exception_class); return JNI_ERR; } return JNI_VERSION_1_6; } extern "C" JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *vm, void *reserved) { VERBOSE("JNI_OnUnload"); JNIEnv* env = nullptr; if (vm->GetEnv(reinterpret_cast(&env), JNI_VERSION_1_6) != JNI_OK) { ERROR("GetEnv() failed"); return; } env->DeleteGlobalRef(lon_lat_class); lon_lat_class = nullptr; lon_lat_constructor_id = nullptr; lon_lat_lon_id = nullptr; lon_lat_lat_id = nullptr; env->DeleteGlobalRef(lon_lat_zoom_class); lon_lat_zoom_class = nullptr; lon_lat_zoom_constructor_id = nullptr; lon_lat_zoom_lon_id = nullptr; lon_lat_zoom_lat_id = nullptr; lon_lat_zoom_zoom_id = nullptr; on_map_changed_id = nullptr; env->DeleteGlobalRef(runtime_exception_class); runtime_exception_class = nullptr; set_to_array_id = nullptr; env->DeleteGlobalRef(tree_set_class); tree_set_class = nullptr; tree_set_constructor_id = nullptr; tree_set_add_id = nullptr; } } // extern "C"