#include "offline_manager.hpp" #include #include "../attach_env.hpp" namespace mbgl { namespace android { // OfflineManager // OfflineManager::OfflineManager(jni::JNIEnv& env, const jni::Object& jFileSource) : fileSource(mbgl::android::FileSource::getDefaultFileSource(env, jFileSource)) { } OfflineManager::~OfflineManager() {} void OfflineManager::setOfflineMapboxTileCountLimit(jni::JNIEnv&, jni::jlong limit) { fileSource.setOfflineMapboxTileCountLimit(limit); } void OfflineManager::listOfflineRegions(jni::JNIEnv& env_, const jni::Object& jFileSource_, const jni::Object& callback_) { auto globalCallback = jni::NewGlobal(env_, callback_); auto globalFilesource = jni::NewGlobal(env_, jFileSource_); fileSource.listOfflineRegions([ //Keep a shared ptr to a global reference of the callback and file source so they are not GC'd in the meanwhile callback = std::make_shared(std::move(globalCallback)), jFileSource = std::make_shared(std::move(globalFilesource)) ](mbgl::expected regions) mutable { // Reattach, the callback comes from a different thread android::UniqueEnv env = android::AttachEnv(); if (regions) { OfflineManager::ListOfflineRegionsCallback::onList( *env, *jFileSource, *callback, std::move(*regions)); } else { OfflineManager::ListOfflineRegionsCallback::onError( *env, *callback, regions.error()); } }); } void OfflineManager::createOfflineRegion(jni::JNIEnv& env_, const jni::Object& jFileSource_, const jni::Object& definition_, const jni::Array& metadata_, const jni::Object& callback_) { // Convert auto definition = OfflineRegionDefinition::getDefinition(env_, definition_); mbgl::OfflineRegionMetadata metadata; if (metadata_) { metadata = OfflineRegion::metadata(env_, metadata_); } auto globalCallback = jni::NewGlobal(env_, callback_); auto globalFilesource = jni::NewGlobal(env_, jFileSource_); // Create region fileSource.createOfflineRegion(definition, metadata, [ //Keep a shared ptr to a global reference of the callback and file source so they are not GC'd in the meanwhile callback = std::make_shared(std::move(globalCallback)), jFileSource = std::make_shared(std::move(globalFilesource)) ](mbgl::expected region) mutable { // Reattach, the callback comes from a different thread android::UniqueEnv env = android::AttachEnv(); if (region) { OfflineManager::CreateOfflineRegionCallback::onCreate( *env, *jFileSource, *callback, std::move(*region) ); } else { OfflineManager::CreateOfflineRegionCallback::onError( *env, *callback, region.error()); } }); } void OfflineManager::registerNative(jni::JNIEnv& env) { jni::Class::Singleton(env); jni::Class::Singleton(env); static auto& javaClass = jni::Class::Singleton(env); #define METHOD(MethodPtr, name) jni::MakeNativePeerMethod(name) jni::RegisterNativePeer( env, javaClass, "nativePtr", jni::MakePeer&>, "initialize", "finalize", METHOD(&OfflineManager::setOfflineMapboxTileCountLimit, "setOfflineMapboxTileCountLimit"), METHOD(&OfflineManager::listOfflineRegions, "listOfflineRegions"), METHOD(&OfflineManager::createOfflineRegion, "createOfflineRegion")); } // OfflineManager::ListOfflineRegionsCallback // void OfflineManager::ListOfflineRegionsCallback::onError(jni::JNIEnv& env, const jni::Object& callback, std::exception_ptr error) { static auto& javaClass = jni::Class::Singleton(env); static auto method = javaClass.GetMethod(env, "onError"); callback.Call(env, method, jni::Make(env, mbgl::util::toString(error))); } void OfflineManager::ListOfflineRegionsCallback::onList(jni::JNIEnv& env, const jni::Object& jFileSource, const jni::Object& callback, mbgl::optional> regions) { static auto& javaClass = jni::Class::Singleton(env); static auto method = javaClass.GetMethod>)>(env, "onList"); std::size_t index = 0; auto jregions = jni::Array>::New(env, regions->size()); for (auto& region : *regions) { jregions.Set(env, index, OfflineRegion::New(env, jFileSource, std::move(region))); index++; } callback.Call(env, method, jregions); } // OfflineManager::CreateOfflineRegionCallback // void OfflineManager::CreateOfflineRegionCallback::onError(jni::JNIEnv& env, const jni::Object& callback, std::exception_ptr error) { static auto& javaClass = jni::Class::Singleton(env); static auto method = javaClass.GetMethod(env, "onError"); callback.Call(env, method, jni::Make(env, mbgl::util::toString(error))); } void OfflineManager::CreateOfflineRegionCallback::onCreate(jni::JNIEnv& env, const jni::Object& jFileSource, const jni::Object& callback, mbgl::optional region) { static auto& javaClass = jni::Class::Singleton(env); static auto method = javaClass.GetMethod)>(env, "onCreate"); callback.Call(env, method, OfflineRegion::New(env, jFileSource, std::move(*region))); } } // namespace android } // namespace mbgl