From 6ddff19ceedb8f6cb095792b90121330afcc38cf Mon Sep 17 00:00:00 2001 From: Alexander Shalamov Date: Mon, 7 Oct 2019 15:43:09 +0300 Subject: [android] Use new FileSourceManager interface Use new interface for android jni adaptation classes. --- platform/android/src/file_source.cpp | 124 ++++++++++++++++++++++++----------- 1 file changed, 85 insertions(+), 39 deletions(-) (limited to 'platform/android/src/file_source.cpp') diff --git a/platform/android/src/file_source.cpp b/platform/android/src/file_source.cpp index a002d6616f..8bbe9acbd2 100644 --- a/platform/android/src/file_source.cpp +++ b/platform/android/src/file_source.cpp @@ -5,6 +5,7 @@ #include #include +#include #include #include #include @@ -14,21 +15,6 @@ #include "asset_manager_file_source.hpp" namespace mbgl { - -std::shared_ptr FileSource::createPlatformFileSource(const ResourceOptions& options) { - auto env{android::AttachEnv()}; - std::shared_ptr fileSource; - if (android::Mapbox::hasInstance(*env)) { - auto assetManager = android::Mapbox::getAssetManager(*env); - fileSource = std::make_shared(options.cachePath(), - std::make_unique(*env, assetManager)); - } else { - fileSource = std::make_shared(options.cachePath(), options.assetPath()); - } - fileSource->setAccessToken(options.accessToken()); - return fileSource; -} - namespace android { // FileSource // @@ -37,53 +23,99 @@ FileSource::FileSource(jni::JNIEnv& _env, const jni::String& accessToken, const std::string path = jni::Make(_env, _cachePath); mapbox::sqlite::setTempPath(path); + mbgl::FileSourceManager::get()->registerFileSourceFactory( + mbgl::FileSourceType::Asset, [](const mbgl::ResourceOptions&) { + auto env{android::AttachEnv()}; + std::unique_ptr assetFileSource; + if (android::Mapbox::hasInstance(*env)) { + auto assetManager = android::Mapbox::getAssetManager(*env); + assetFileSource = std::make_unique(*env, assetManager); + } + return assetFileSource; + }); + resourceOptions.withAccessToken(accessToken ? jni::Make(_env, accessToken) : "") .withCachePath(path + DATABASE_FILE); - // Create a core default file source - fileSource = std::static_pointer_cast(mbgl::FileSource::getSharedFileSource(resourceOptions)); + // Create a core file sources + // TODO: Split Android FileSource API to smaller interfaces + resourceLoader = + mbgl::FileSourceManager::get()->getFileSource(mbgl::FileSourceType::ResourceLoader, resourceOptions); + databaseSource = std::static_pointer_cast( + mbgl::FileSourceManager::get()->getFileSource(mbgl::FileSourceType::Database, resourceOptions)); + onlineSource = std::static_pointer_cast( + mbgl::FileSourceManager::get()->getFileSource(mbgl::FileSourceType::Network, resourceOptions)); } FileSource::~FileSource() { } jni::Local FileSource::getAccessToken(jni::JNIEnv& env) { - return jni::Make(env, fileSource->getAccessToken()); + if (auto* token = onlineSource->getProperty(mbgl::ACCESS_TOKEN_KEY).getString()) { + return jni::Make(env, *token); + } + + ThrowNew(env, jni::FindClass(env, "java/lang/IllegalStateException"), "Online functionality is disabled."); + return jni::Make(env, ""); } void FileSource::setAccessToken(jni::JNIEnv& env, const jni::String& token) { - fileSource->setAccessToken(token ? jni::Make(env, token) : ""); + if (onlineSource) { + onlineSource->setProperty(mbgl::ACCESS_TOKEN_KEY, token ? jni::Make(env, token) : ""); + } else { + ThrowNew(env, jni::FindClass(env, "java/lang/IllegalStateException"), "Online functionality is disabled."); + } } void FileSource::setAPIBaseUrl(jni::JNIEnv& env, const jni::String& url) { - fileSource->setAPIBaseURL(jni::Make(env, url)); + if (onlineSource) { + onlineSource->setProperty(mbgl::API_BASE_URL_KEY, jni::Make(env, url)); + } else { + ThrowNew(env, jni::FindClass(env, "java/lang/IllegalStateException"), "Online functionality is disabled."); + } } void FileSource::setResourceTransform(jni::JNIEnv& env, const jni::Object& transformCallback) { + // Core could be built without support for network resource provider. + if (!onlineSource) { + ThrowNew(env, jni::FindClass(env, "java/lang/IllegalStateException"), "Online functionality is disabled."); + return; + } + if (transformCallback) { auto global = jni::NewGlobal(env, transformCallback); - resourceTransform = std::make_unique>( + resourceTransform = std::make_unique>( *Scheduler::GetCurrent(), // 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::make_shared(std::move(global))](mbgl::Resource::Kind kind, - const std::string& url_) { + [callback = std::make_shared(std::move(global))]( + mbgl::Resource::Kind kind, const std::string& url_, ResourceTransform::FinishedCallback cb) { android::UniqueEnv _env = android::AttachEnv(); - return FileSource::ResourceTransformCallback::onURL(*_env, *callback, int(kind), url_); + cb(FileSource::ResourceTransformCallback::onURL(*_env, *callback, int(kind), url_)); }); - fileSource->setResourceTransform(resourceTransform->self()); + onlineSource->setResourceTransform( + {[actorRef = resourceTransform->self()]( + Resource::Kind kind, const std::string& url, ResourceTransform::FinishedCallback cb) { + actorRef.invoke(&ResourceTransform::TransformCallback::operator(), kind, url, std::move(cb)); + }}); } else { // Reset the callback resourceTransform.reset(); - fileSource->setResourceTransform({}); + onlineSource->setResourceTransform({}); } } -void FileSource::setResourceCachePath(jni::JNIEnv& env, const jni::String& path, +void FileSource::setResourceCachePath(jni::JNIEnv& env, + const jni::String& path, const jni::Object& _callback) { + if (!databaseSource) { + ThrowNew(env, jni::FindClass(env, "java/lang/IllegalStateException"), "Offline functionality is disabled."); + return; + } + if (pathChangeCallback) { FileSource::ResourcesCachePathChangeCallback::onError(env, _callback, jni::Make(env, "Another resources cache path change is in progress")); return; @@ -93,17 +125,22 @@ void FileSource::setResourceCachePath(jni::JNIEnv& env, const jni::String& path, mapbox::sqlite::setTempPath(newPath); auto global = jni::NewGlobal(env, _callback); - pathChangeCallback = std::make_unique>(*Scheduler::GetCurrent(), - [this, callback = std::make_shared(std::move(global)), newPath] { - android::UniqueEnv _env = android::AttachEnv(); - FileSource::ResourcesCachePathChangeCallback::onSuccess(*_env, *callback, jni::Make(*_env, newPath)); - pathChangeCallback.reset(); - }); + pathChangeCallback = Scheduler::GetCurrent()->bindOnce( + [this, callback = std::make_shared(std::move(global)), newPath] { + android::UniqueEnv _env = android::AttachEnv(); + FileSource::ResourcesCachePathChangeCallback::onSuccess( + *_env, *callback, jni::Make(*_env, newPath)); + pathChangeCallback = {}; + }); - fileSource->setResourceCachePath(newPath + DATABASE_FILE, pathChangeCallback->self()); + databaseSource->setDatabasePath(newPath + DATABASE_FILE, pathChangeCallback); } void FileSource::resume(jni::JNIEnv&) { + if (!resourceLoader) { + return; + } + if (!activationCounter) { activationCounter = optional(1) ; return; @@ -111,15 +148,19 @@ void FileSource::resume(jni::JNIEnv&) { activationCounter.value()++; if (activationCounter == 1) { - fileSource->resume(); + resourceLoader->resume(); } } void FileSource::pause(jni::JNIEnv&) { + if (!resourceLoader) { + return; + } + if (activationCounter) { activationCounter.value()--; if (activationCounter == 0) { - fileSource->pause(); + resourceLoader->pause(); } } } @@ -137,10 +178,15 @@ FileSource* FileSource::getNativePeer(jni::JNIEnv& env, const jni::Object(jFileSource.Get(env, field)); } -mbgl::ResourceOptions FileSource::getSharedResourceOptions(jni::JNIEnv& env, const jni::Object& jFileSource) { +mbgl::ResourceOptions FileSource::getSharedResourceOptions(jni::JNIEnv& env, + const jni::Object& jFileSource) { FileSource* fileSource = FileSource::getNativePeer(env, jFileSource); - assert(fileSource != nullptr); - return fileSource->resourceOptions.clone(); + // Core could be compiled without support for any sources. + if (fileSource) { + return fileSource->resourceOptions.clone(); + } + + return {}; } // FileSource::ResourcesCachePathChangeCallback // -- cgit v1.2.1