#include "offline_manager.hpp" #include #include "../attach_env.hpp" #include "../jni/generic_global_ref_deleter.hpp" namespace mbgl { namespace android { // OfflineManager // OfflineManager::OfflineManager(jni::JNIEnv& env, 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_, jni::Object jFileSource_, jni::Object callback_) { // list regions 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::shared_ptr(callback_.NewGlobalRef(env_).release().Get(), GenericGlobalRefDeleter()), jFileSource = std::shared_ptr(jFileSource_.NewGlobalRef(env_).release().Get(), GenericGlobalRefDeleter()) ](mbgl::expected regions) mutable { // Reattach, the callback comes from a different thread android::UniqueEnv env = android::AttachEnv(); if (regions) { OfflineManager::ListOfflineRegionsCallback::onList( *env, jni::Object(*jFileSource), jni::Object(*callback), std::move(*regions)); } else { OfflineManager::ListOfflineRegionsCallback::onError( *env, jni::Object(*callback), regions.error()); } }); } void OfflineManager::createOfflineRegion(jni::JNIEnv& env_, jni::Object jFileSource_, jni::Object definition_, jni::Array metadata_, jni::Object callback_) { // Convert auto definition = OfflineRegionDefinition::getDefinition(env_, definition_); mbgl::OfflineRegionMetadata metadata; if (metadata_) { metadata = OfflineRegion::metadata(env_, metadata_); } // 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::shared_ptr(callback_.NewGlobalRef(env_).release().Get(), GenericGlobalRefDeleter()), jFileSource = std::shared_ptr(jFileSource_.NewGlobalRef(env_).release().Get(), GenericGlobalRefDeleter()) ](mbgl::expected region) mutable { // Reattach, the callback comes from a different thread android::UniqueEnv env = android::AttachEnv(); if (region) { OfflineManager::CreateOfflineRegionCallback::onCreate( *env, jni::Object(*jFileSource), jni::Object(*callback), std::move(*region) ); } else { OfflineManager::CreateOfflineRegionCallback::onError(*env, jni::Object(*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", std::make_unique>, "initialize", "finalize", METHOD(&OfflineManager::setOfflineMapboxTileCountLimit, "setOfflineMapboxTileCountLimit"), METHOD(&OfflineManager::listOfflineRegions, "listOfflineRegions"), METHOD(&OfflineManager::createOfflineRegion, "createOfflineRegion")); } // OfflineManager::ListOfflineRegionsCallback // void OfflineManager::ListOfflineRegionsCallback::onError(jni::JNIEnv& env, 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::SeizeLocal(env, jni::Make(env, mbgl::util::toString(error)))); } void OfflineManager::ListOfflineRegionsCallback::onList(jni::JNIEnv& env, jni::Object jFileSource, 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::SeizeLocal(env, jni::Array>::New(env, regions->size())); for (auto& region : *regions) { jregions->Set(env, index, *jni::SeizeLocal(env, OfflineRegion::New(env, jFileSource, std::move(region)))); index++; } callback.Call(env, method, *jregions); } // OfflineManager::CreateOfflineRegionCallback // void OfflineManager::CreateOfflineRegionCallback::onError(jni::JNIEnv& env, 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::SeizeLocal(env, jni::Make(env, mbgl::util::toString(error)))); } void OfflineManager::CreateOfflineRegionCallback::onCreate(jni::JNIEnv& env, jni::Object jFileSource, jni::Object callback, mbgl::optional region) { static auto javaClass = jni::Class::Singleton(env); static auto method = javaClass.GetMethod)>(env, "onCreate"); callback.Call(env, method, *jni::SeizeLocal(env, OfflineRegion::New(env, jFileSource, std::move(*region)))); } } // namespace android } // namespace mbgl