#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, const jni::Object& _obj, const jni::Object& _jFileSource, jni::jfloat _pixelRatio, jni::jint width, jni::jint height, const jni::String& styleURL, const jni::String& styleJSON, const jni::Object& region, const jni::Object& position, jni::jboolean _showLogo, const jni::String& _programCacheDir, const jni::String& _localIdeographFontFamily) : javaPeer(_env, _obj) , 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) }; optional cameraOptions; if (position) { cameraOptions = CameraPosition::getCameraOptions(_env, position); } optional bounds; if (region) { bounds = LatLngBounds::getLatLngBounds(_env, region); } std::pair style; if (styleJSON) { style = std::make_pair(true, jni::Make(_env, styleJSON)); } else { style = std::make_pair(false, jni::Make(_env, styleURL)); } showLogo = _showLogo; // Create the core snapshotter snapshotter = std::make_unique(&fileSource, threadPool, style, size, pixelRatio, cameraOptions, bounds, jni::Make(_env, _programCacheDir), _localIdeographFontFamily ? jni::Make(_env, _localIdeographFontFamily) : optional{}); } 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::MapSnapshotter::LatLngForFn latLngForFn) { MBGL_VERIFY_THREAD(tid); android::UniqueEnv _env = android::AttachEnv(); static auto& javaClass = jni::Class::Singleton(*_env); if (err) { // error handler callback static auto onSnapshotFailed = javaClass.GetMethod(*_env, "onSnapshotFailed"); auto weakReference = javaPeer.get(*_env); if (weakReference) { weakReference.Call(*_env, onSnapshotFailed, jni::Make(*_env, util::toString(err))); } } else { // Create the wrapper auto mapSnapshot = android::MapSnapshot::New(*_env, std::move(image), pixelRatio, attributions, showLogo, pointForFn, latLngForFn); // invoke callback static auto onSnapshotReady = javaClass.GetMethod)>(*_env, "onSnapshotReady"); auto weakReference = javaPeer.get(*_env); if (weakReference) { weakReference.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, const jni::String& styleURL) { snapshotter->setStyleURL(jni::Make(env, styleURL)); } void MapSnapshotter::setStyleJson(JNIEnv& env, const jni::String& styleJSON) { snapshotter->setStyleJSON(jni::Make(env, styleJSON)); } 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, const jni::Object& position) { auto options = CameraPosition::getCameraOptions(env, position); snapshotter->setCameraOptions(options); } void MapSnapshotter::setRegion(JNIEnv& env, const 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 // void MapSnapshotter::registerNative(jni::JNIEnv& env) { // Lookup the class static auto& javaClass = jni::Class::Singleton(env); #define METHOD(MethodPtr, name) jni::MakeNativePeerMethod(name) // Register the peer jni::RegisterNativePeer(env, javaClass, "nativePtr", jni::MakePeer&, const jni::Object&, jni::jfloat, jni::jint, jni::jint, const jni::String&, const jni::String&, const jni::Object&, const jni::Object&, jni::jboolean, const jni::String&, const jni::String&>, "nativeInitialize", "finalize", METHOD(&MapSnapshotter::setStyleUrl, "setStyleUrl"), METHOD(&MapSnapshotter::setStyleJson, "setStyleJson"), METHOD(&MapSnapshotter::setSize, "setSize"), METHOD(&MapSnapshotter::setCameraPosition, "setCameraPosition"), METHOD(&MapSnapshotter::setRegion, "setRegion"), METHOD(&MapSnapshotter::start, "nativeStart"), METHOD(&MapSnapshotter::cancel, "nativeCancel") ); } } // namespace android } // namespace mbgl