#include "map_snapshotter.hpp" #include #include #include #include #include #include #include "../attach_env.hpp" #include "map_snapshot.hpp" namespace mbgl { namespace android { MapSnapshotter::MapSnapshotter(jni::JNIEnv& _env, jni::Object _obj, jni::Object _jFileSource, jni::jfloat _pixelRatio, jni::jint width, jni::jint height, jni::String styleURL, jni::Object region, jni::Object position, jni::jboolean _showLogo, jni::String _programCacheDir) : javaPeer(SeizeGenericWeakRef(_env, jni::Object(jni::NewWeakGlobalRef(_env, _obj.Get()).release()))) , pixelRatio(_pixelRatio) , threadPool(sharedThreadPool()) { // Get a reference to the JavaVM for callbacks if (_env.GetJavaVM(&vm) < 0) { _env.ExceptionDescribe(); return; } jFileSource = FileSource::getNativePeer(_env, _jFileSource); auto& fileSource = mbgl::android::FileSource::getDefaultFileSource(_env, _jFileSource); auto size = mbgl::Size { static_cast(width), static_cast(height) }; auto cameraOptions = position ? CameraPosition::getCameraOptions(_env, position) : CameraOptions(); optional bounds; if (region) { bounds = LatLngBounds::getLatLngBounds(_env, region); } showLogo = _showLogo; // Create the core snapshotter snapshotter = std::make_unique(fileSource, *threadPool, jni::Make(_env, styleURL), size, pixelRatio, cameraOptions, bounds, jni::Make(_env, _programCacheDir)); } MapSnapshotter::~MapSnapshotter() = default; void MapSnapshotter::start(JNIEnv& env) { MBGL_VERIFY_THREAD(tid); activateFilesource(env); snapshotCallback = std::make_unique>( *Scheduler::GetCurrent(), [this](std::exception_ptr err, PremultipliedImage image, std::vector attributions, mbgl::MapSnapshotter::PointForFn pointForFn) { MBGL_VERIFY_THREAD(tid); android::UniqueEnv _env = android::AttachEnv(); if (err) { // error handler callback static auto onSnapshotFailed = javaClass.GetMethod(*_env, "onSnapshotFailed"); auto message = jni::Make(*_env, util::toString(err)); javaPeer->Call(*_env, onSnapshotFailed, message); jni::DeleteLocalRef(*_env, message); } else { // Create the wrapper auto mapSnapshot = android::MapSnapshot::New(*_env, std::move(image), pixelRatio, attributions, showLogo, pointForFn); // invoke callback static auto onSnapshotReady = javaClass.GetMethod)>(*_env, "onSnapshotReady"); javaPeer->Call(*_env, onSnapshotReady, mapSnapshot); } deactivateFilesource(*_env); }); snapshotter->snapshot(snapshotCallback->self()); } void MapSnapshotter::cancel(JNIEnv& env) { MBGL_VERIFY_THREAD(tid); snapshotCallback.reset(); deactivateFilesource(env); } void MapSnapshotter::setStyleUrl(JNIEnv& env, jni::String styleURL) { snapshotter->setStyleURL(jni::Make(env, styleURL)); } void MapSnapshotter::setSize(JNIEnv&, jni::jint width, jni::jint height) { auto size = mbgl::Size { static_cast(width), static_cast(height) }; snapshotter->setSize(size); } void MapSnapshotter::setCameraPosition(JNIEnv& env, jni::Object position) { auto options = CameraPosition::getCameraOptions(env, position); snapshotter->setCameraOptions(options); } void MapSnapshotter::setRegion(JNIEnv& env, jni::Object region) { snapshotter->setRegion(LatLngBounds::getLatLngBounds(env, region)); } // Private methods // void MapSnapshotter::activateFilesource(JNIEnv& env) { if (!activatedFilesource) { activatedFilesource = true; jFileSource->resume(env); } } void MapSnapshotter::deactivateFilesource(JNIEnv& env) { if (activatedFilesource) { activatedFilesource = false; jFileSource->pause(env); } } // Static methods // jni::Class MapSnapshotter::javaClass; void MapSnapshotter::registerNative(jni::JNIEnv& env) { // Lookup the class MapSnapshotter::javaClass = *jni::Class::Find(env).NewGlobalRef(env).release(); #define METHOD(MethodPtr, name) jni::MakeNativePeerMethod(name) // Register the peer jni::RegisterNativePeer(env, MapSnapshotter::javaClass, "nativePtr", std::make_unique, jni::Object, jni::jfloat, jni::jint, jni::jint, jni::String, jni::Object, jni::Object, jni::jboolean, jni::String>, "nativeInitialize", "finalize", METHOD(&MapSnapshotter::setStyleUrl, "setStyleUrl"), METHOD(&MapSnapshotter::setSize, "setSize"), METHOD(&MapSnapshotter::setCameraPosition, "setCameraPosition"), METHOD(&MapSnapshotter::setRegion, "setRegion"), METHOD(&MapSnapshotter::start, "nativeStart"), METHOD(&MapSnapshotter::cancel, "nativeCancel") ); } } // namespace android } // namespace mbgl