#include "file_source.hpp" #include #include #include "jni/generic_global_ref_deleter.hpp" namespace mbgl { namespace android { // FileSource // FileSource::FileSource(jni::JNIEnv& _env, jni::String accessToken, jni::String _cachePath, jni::String _apkPath) { // Create a core default file source fileSource = std::make_unique( jni::Make(_env, _cachePath) + "/mbgl-offline.db", jni::Make(_env, _apkPath)); // 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) { // Launch transformCallback fileSource->setResourceTransform([ // 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()), env ](mbgl::Resource::Kind kind, std::string&& url_) { return FileSource::ResourceTransformCallback::onURL(const_cast(env), jni::Object(*callback), int(kind), url_); }); } else { // Reset the callback fileSource->setResourceTransform(nullptr); } } 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