#include "file_source.hpp" #include #include #include #include #include "asset_manager_file_source.hpp" #include "jni/generic_global_ref_deleter.hpp" #include namespace mbgl { namespace android { // FileSource // FileSource::FileSource(jni::JNIEnv& _env, jni::String accessToken, jni::String _cachePath, jni::Object assetManager) { // Create a core default file source fileSource = std::make_unique( jni::Make(_env, _cachePath) + "/mbgl-offline.db", std::make_unique(_env, assetManager)); // Set access token fileSource->setAccessToken(jni::Make(_env, accessToken)); } FileSource::~FileSource() { } jni::String FileSource::getAccessToken(jni::JNIEnv& env) { return jni::Make(env, fileSource->getAccessToken()); } void FileSource::setAccessToken(jni::JNIEnv& env, jni::String token) { fileSource->setAccessToken(jni::Make(env, token)); } void FileSource::setAPIBaseUrl(jni::JNIEnv& env, jni::String url) { fileSource->setAPIBaseURL(jni::Make(env, url)); } void FileSource::setResourceTransform(jni::JNIEnv& env, jni::Object transformCallback) { if (transformCallback) { resourceTransform = std::make_unique>(*util::RunLoop::Get(), // Capture the ResourceTransformCallback object as a managed global into // the lambda. It is released automatically when we're setting a new ResourceTransform in // a subsequent call. // Note: we're converting it to shared_ptr because this lambda is converted to a std::function, // which requires copyability of its captured variables. [callback = std::shared_ptr(transformCallback.NewGlobalRef(env).release()->Get(), GenericGlobalRefDeleter())] (mbgl::Resource::Kind kind, const std::string&& url_) { android::UniqueEnv _env = android::AttachEnv(); return FileSource::ResourceTransformCallback::onURL(*_env, jni::Object(*callback), int(kind), url_); }); fileSource->setResourceTransform(resourceTransform->self()); } else { // Reset the callback resourceTransform.reset(); fileSource->setResourceTransform({}); } } jni::Class FileSource::javaClass; FileSource* FileSource::getNativePeer(jni::JNIEnv& env, jni::Object jFileSource) { static auto field = FileSource::javaClass.GetField(env, "nativePtr"); return reinterpret_cast(jFileSource.Get(env, field)); } mbgl::DefaultFileSource& FileSource::getDefaultFileSource(jni::JNIEnv& env, jni::Object jFileSource) { FileSource* fileSource = FileSource::getNativePeer(env, jFileSource); assert(fileSource != nullptr); return *fileSource->fileSource; } void FileSource::registerNative(jni::JNIEnv& env) { //Register classes FileSource::javaClass = *jni::Class::Find(env).NewGlobalRef(env).release(); FileSource::ResourceTransformCallback::javaClass = *jni::Class::Find(env).NewGlobalRef(env).release(); #define METHOD(MethodPtr, name) jni::MakeNativePeerMethod(name) // Register the peer jni::RegisterNativePeer( env, FileSource::javaClass, "nativePtr", std::make_unique>, "initialize", "finalize", METHOD(&FileSource::getAccessToken, "getAccessToken"), METHOD(&FileSource::setAccessToken, "setAccessToken"), METHOD(&FileSource::setAPIBaseUrl, "setApiBaseUrl"), METHOD(&FileSource::setResourceTransform, "setResourceTransform") ); } // FileSource::ResourceTransformCallback // jni::Class FileSource::ResourceTransformCallback::javaClass; std::string FileSource::ResourceTransformCallback::onURL(jni::JNIEnv& env, jni::Object callback, int kind, std::string url_) { static auto method = FileSource::ResourceTransformCallback::javaClass.GetMethod(env, "onURL"); auto url = jni::Make(env, url_); url = callback.Call(env, method, kind, url); return jni::Make(env, url); } } // namespace android } // namespace mbgl