diff options
author | Alexander Shalamov <alexander.shalamov@mapbox.com> | 2019-10-07 15:43:09 +0300 |
---|---|---|
committer | Alexander Shalamov <alexander.shalamov@mapbox.com> | 2020-01-13 10:57:23 +0200 |
commit | 6ddff19ceedb8f6cb095792b90121330afcc38cf (patch) | |
tree | 79d2911b5964c8a189eef7bd33618f1270bfa344 /platform/android | |
parent | 1e6ad7651650d39cdfae03bacd74144d25fbbf23 (diff) | |
download | qtlocation-mapboxgl-6ddff19ceedb8f6cb095792b90121330afcc38cf.tar.gz |
[android] Use new FileSourceManager interface
Use new interface for android jni adaptation classes.
Diffstat (limited to 'platform/android')
-rw-r--r-- | platform/android/src/asset_manager_file_source.cpp | 7 | ||||
-rw-r--r-- | platform/android/src/asset_manager_file_source.hpp | 1 | ||||
-rw-r--r-- | platform/android/src/file_source.cpp | 124 | ||||
-rw-r--r-- | platform/android/src/file_source.hpp | 18 | ||||
-rw-r--r-- | platform/android/src/http_file_source.cpp | 5 | ||||
-rw-r--r-- | platform/android/src/jni_native.cpp | 2 | ||||
-rw-r--r-- | platform/android/src/offline/offline_manager.cpp | 9 | ||||
-rw-r--r-- | platform/android/src/offline/offline_manager.hpp | 4 | ||||
-rw-r--r-- | platform/android/src/offline/offline_region.cpp | 26 | ||||
-rw-r--r-- | platform/android/src/offline/offline_region.hpp | 2 |
10 files changed, 133 insertions, 65 deletions
diff --git a/platform/android/src/asset_manager_file_source.cpp b/platform/android/src/asset_manager_file_source.cpp index b9150deef9..73ecec2b05 100644 --- a/platform/android/src/asset_manager_file_source.cpp +++ b/platform/android/src/asset_manager_file_source.cpp @@ -1,10 +1,11 @@ #include "asset_manager_file_source.hpp" #include <mbgl/storage/file_source_request.hpp> +#include <mbgl/storage/resource.hpp> #include <mbgl/storage/response.hpp> -#include <mbgl/util/util.hpp> #include <mbgl/util/thread.hpp> #include <mbgl/util/url.hpp> +#include <mbgl/util/util.hpp> #include <android/asset_manager.h> #include <android/asset_manager_jni.h> @@ -54,4 +55,8 @@ std::unique_ptr<AsyncRequest> AssetManagerFileSource::request(const Resource& re return std::move(req); } +bool AssetManagerFileSource::canRequest(const Resource& resource) const { + return 0 == resource.url.rfind(mbgl::util::ASSET_PROTOCOL, 0); +} + } // namespace mbgl diff --git a/platform/android/src/asset_manager_file_source.hpp b/platform/android/src/asset_manager_file_source.hpp index 4ec5b4c30e..bcbc6f1e9d 100644 --- a/platform/android/src/asset_manager_file_source.hpp +++ b/platform/android/src/asset_manager_file_source.hpp @@ -18,6 +18,7 @@ public: ~AssetManagerFileSource() override; std::unique_ptr<AsyncRequest> request(const Resource&, Callback) override; + bool canRequest(const Resource&) const override; private: class Impl; 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 <mbgl/actor/actor.hpp> #include <mbgl/actor/scheduler.hpp> +#include <mbgl/storage/file_source_manager.hpp> #include <mbgl/storage/resource_options.hpp> #include <mbgl/storage/resource_transform.hpp> #include <mbgl/util/logging.hpp> @@ -14,21 +15,6 @@ #include "asset_manager_file_source.hpp" namespace mbgl { - -std::shared_ptr<FileSource> FileSource::createPlatformFileSource(const ResourceOptions& options) { - auto env{android::AttachEnv()}; - std::shared_ptr<DefaultFileSource> fileSource; - if (android::Mapbox::hasInstance(*env)) { - auto assetManager = android::Mapbox::getAssetManager(*env); - fileSource = std::make_shared<DefaultFileSource>(options.cachePath(), - std::make_unique<AssetManagerFileSource>(*env, assetManager)); - } else { - fileSource = std::make_shared<DefaultFileSource>(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<std::string>(_env, _cachePath); mapbox::sqlite::setTempPath(path); + mbgl::FileSourceManager::get()->registerFileSourceFactory( + mbgl::FileSourceType::Asset, [](const mbgl::ResourceOptions&) { + auto env{android::AttachEnv()}; + std::unique_ptr<mbgl::FileSource> assetFileSource; + if (android::Mapbox::hasInstance(*env)) { + auto assetManager = android::Mapbox::getAssetManager(*env); + assetFileSource = std::make_unique<AssetManagerFileSource>(*env, assetManager); + } + return assetFileSource; + }); + resourceOptions.withAccessToken(accessToken ? jni::Make<std::string>(_env, accessToken) : "") .withCachePath(path + DATABASE_FILE); - // Create a core default file source - fileSource = std::static_pointer_cast<mbgl::DefaultFileSource>(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::DatabaseFileSource>( + mbgl::FileSourceManager::get()->getFileSource(mbgl::FileSourceType::Database, resourceOptions)); + onlineSource = std::static_pointer_cast<mbgl::OnlineFileSource>( + mbgl::FileSourceManager::get()->getFileSource(mbgl::FileSourceType::Network, resourceOptions)); } FileSource::~FileSource() { } jni::Local<jni::String> FileSource::getAccessToken(jni::JNIEnv& env) { - return jni::Make<jni::String>(env, fileSource->getAccessToken()); + if (auto* token = onlineSource->getProperty(mbgl::ACCESS_TOKEN_KEY).getString()) { + return jni::Make<jni::String>(env, *token); + } + + ThrowNew(env, jni::FindClass(env, "java/lang/IllegalStateException"), "Online functionality is disabled."); + return jni::Make<jni::String>(env, ""); } void FileSource::setAccessToken(jni::JNIEnv& env, const jni::String& token) { - fileSource->setAccessToken(token ? jni::Make<std::string>(env, token) : ""); + if (onlineSource) { + onlineSource->setProperty(mbgl::ACCESS_TOKEN_KEY, token ? jni::Make<std::string>(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<std::string>(env, url)); + if (onlineSource) { + onlineSource->setProperty(mbgl::API_BASE_URL_KEY, jni::Make<std::string>(env, url)); + } else { + ThrowNew(env, jni::FindClass(env, "java/lang/IllegalStateException"), "Online functionality is disabled."); + } } void FileSource::setResourceTransform(jni::JNIEnv& env, const jni::Object<FileSource::ResourceTransformCallback>& 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<jni::EnvAttachingDeleter>(env, transformCallback); - resourceTransform = std::make_unique<Actor<ResourceTransform>>( + resourceTransform = std::make_unique<Actor<ResourceTransform::TransformCallback>>( *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<decltype(global)>(std::move(global))](mbgl::Resource::Kind kind, - const std::string& url_) { + [callback = std::make_shared<decltype(global)>(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<FileSource::ResourcesCachePathChangeCallback>& _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<jni::String>(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<jni::EnvAttachingDeleter>(env, _callback); - pathChangeCallback = std::make_unique<Actor<PathChangeCallback>>(*Scheduler::GetCurrent(), - [this, callback = std::make_shared<decltype(global)>(std::move(global)), newPath] { - android::UniqueEnv _env = android::AttachEnv(); - FileSource::ResourcesCachePathChangeCallback::onSuccess(*_env, *callback, jni::Make<jni::String>(*_env, newPath)); - pathChangeCallback.reset(); - }); + pathChangeCallback = Scheduler::GetCurrent()->bindOnce( + [this, callback = std::make_shared<decltype(global)>(std::move(global)), newPath] { + android::UniqueEnv _env = android::AttachEnv(); + FileSource::ResourcesCachePathChangeCallback::onSuccess( + *_env, *callback, jni::Make<jni::String>(*_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<int>(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<FileSo return reinterpret_cast<FileSource *>(jFileSource.Get(env, field)); } -mbgl::ResourceOptions FileSource::getSharedResourceOptions(jni::JNIEnv& env, const jni::Object<FileSource>& jFileSource) { +mbgl::ResourceOptions FileSource::getSharedResourceOptions(jni::JNIEnv& env, + const jni::Object<FileSource>& 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 // diff --git a/platform/android/src/file_source.hpp b/platform/android/src/file_source.hpp index 6a9190fa06..591bfbc93e 100644 --- a/platform/android/src/file_source.hpp +++ b/platform/android/src/file_source.hpp @@ -1,7 +1,9 @@ #pragma once -#include <mbgl/storage/default_file_source.hpp> +#include <mbgl/storage/database_file_source.hpp> +#include <mbgl/storage/online_file_source.hpp> #include <mbgl/storage/resource_options.hpp> +#include <mbgl/storage/resource_transform.hpp> #include "asset_manager.hpp" @@ -10,13 +12,12 @@ namespace mbgl { template <typename T> class Actor; -class ResourceTransform; -using mbgl::PathChangeCallback; namespace android { /** - * Peer class for the Android FileSource holder. Ensures that a single DefaultFileSource is used + * Peer class for the Android FileSource holder. Ensures that a single core FileSource + * of a ResourceLoader type is used. */ class FileSource { public: @@ -71,11 +72,12 @@ private: const std::string DATABASE_FILE = "/mbgl-offline.db"; optional<int> activationCounter; mbgl::ResourceOptions resourceOptions; - std::unique_ptr<Actor<ResourceTransform>> resourceTransform; - std::unique_ptr<Actor<PathChangeCallback>> pathChangeCallback; - std::shared_ptr<mbgl::DefaultFileSource> fileSource; + std::unique_ptr<Actor<ResourceTransform::TransformCallback>> resourceTransform; + std::function<void()> pathChangeCallback; + std::shared_ptr<mbgl::DatabaseFileSource> databaseSource; + std::shared_ptr<mbgl::OnlineFileSource> onlineSource; + std::shared_ptr<mbgl::FileSource> resourceLoader; }; - } // namespace android } // namespace mbgl diff --git a/platform/android/src/http_file_source.cpp b/platform/android/src/http_file_source.cpp index 7066918fef..37f7307373 100644 --- a/platform/android/src/http_file_source.cpp +++ b/platform/android/src/http_file_source.cpp @@ -3,10 +3,11 @@ #include <mbgl/storage/response.hpp> #include <mbgl/util/logging.hpp> +#include <mbgl/util/async_request.hpp> #include <mbgl/util/async_task.hpp> -#include <mbgl/util/util.hpp> -#include <mbgl/util/string.hpp> #include <mbgl/util/http_header.hpp> +#include <mbgl/util/string.hpp> +#include <mbgl/util/util.hpp> #include <jni/jni.hpp> #include "attach_env.hpp" diff --git a/platform/android/src/jni_native.cpp b/platform/android/src/jni_native.cpp index bcbdfcf484..d6b03d981e 100644 --- a/platform/android/src/jni_native.cpp +++ b/platform/android/src/jni_native.cpp @@ -66,7 +66,7 @@ void registerNatives(JavaVM *vm) { jni::JNIEnv& env = jni::GetEnv(*vm, jni::jni_version_1_6); - // For the DefaultFileSource + // For the FileSource static mbgl::util::RunLoop mainRunLoop; FileSource::registerNative(env); diff --git a/platform/android/src/offline/offline_manager.cpp b/platform/android/src/offline/offline_manager.cpp index be864e18aa..98f2b88a7f 100644 --- a/platform/android/src/offline/offline_manager.cpp +++ b/platform/android/src/offline/offline_manager.cpp @@ -1,5 +1,7 @@ #include "offline_manager.hpp" +#include <mbgl/storage/file_source_manager.hpp> +#include <mbgl/storage/resource.hpp> #include <mbgl/util/string.hpp> #include "../attach_env.hpp" @@ -23,7 +25,12 @@ void handleException(std::exception_ptr exception, // OfflineManager // OfflineManager::OfflineManager(jni::JNIEnv& env, const jni::Object<FileSource>& jFileSource) - : fileSource(std::static_pointer_cast<DefaultFileSource>(mbgl::FileSource::getSharedFileSource(FileSource::getSharedResourceOptions(env, jFileSource)))) {} + : fileSource(std::static_pointer_cast<mbgl::DatabaseFileSource>(mbgl::FileSourceManager::get()->getFileSource( + mbgl::FileSourceType::Database, FileSource::getSharedResourceOptions(env, jFileSource)))) { + if (!fileSource) { + ThrowNew(env, jni::FindClass(env, "java/lang/IllegalStateException"), "Offline functionality is disabled."); + } +} OfflineManager::~OfflineManager() {} diff --git a/platform/android/src/offline/offline_manager.hpp b/platform/android/src/offline/offline_manager.hpp index 0af92f8115..84111a7423 100644 --- a/platform/android/src/offline/offline_manager.hpp +++ b/platform/android/src/offline/offline_manager.hpp @@ -12,8 +12,6 @@ namespace mbgl { -class DefaultFileSource; - namespace android { class OfflineManager { @@ -106,7 +104,7 @@ public: void runPackDatabaseAutomatically(jni::JNIEnv&, jboolean autopack); private: - std::shared_ptr<mbgl::DefaultFileSource> fileSource; + std::shared_ptr<mbgl::DatabaseFileSource> fileSource; }; } // namespace android diff --git a/platform/android/src/offline/offline_region.cpp b/platform/android/src/offline/offline_region.cpp index 4276ce8f45..4ee835bab3 100644 --- a/platform/android/src/offline/offline_region.cpp +++ b/platform/android/src/offline/offline_region.cpp @@ -1,5 +1,6 @@ #include "offline_region.hpp" +#include <mbgl/storage/file_source_manager.hpp> #include <mbgl/util/logging.hpp> #include <mbgl/util/string.hpp> @@ -14,8 +15,13 @@ namespace android { // OfflineRegion // OfflineRegion::OfflineRegion(jni::JNIEnv& env, jni::jlong offlineRegionPtr, const jni::Object<FileSource>& jFileSource) - : region(reinterpret_cast<mbgl::OfflineRegion *>(offlineRegionPtr)) - , fileSource(std::static_pointer_cast<DefaultFileSource>(mbgl::FileSource::getSharedFileSource(FileSource::getSharedResourceOptions(env, jFileSource)))) {} + : region(reinterpret_cast<mbgl::OfflineRegion*>(offlineRegionPtr)), + fileSource(std::static_pointer_cast<mbgl::DatabaseFileSource>(mbgl::FileSourceManager::get()->getFileSource( + mbgl::FileSourceType::Database, FileSource::getSharedResourceOptions(env, jFileSource)))) { + if (!fileSource) { + ThrowNew(env, jni::FindClass(env, "java/lang/IllegalStateException"), "Offline functionality is disabled."); + } +} OfflineRegion::~OfflineRegion() {} @@ -159,15 +165,17 @@ void OfflineRegion::updateOfflineRegionMetadata(jni::JNIEnv& env_, const jni::Ar }); } -jni::Local<jni::Object<OfflineRegion>> OfflineRegion::New(jni::JNIEnv& env, const jni::Object<FileSource>& jFileSource, mbgl::OfflineRegion region) { - +jni::Local<jni::Object<OfflineRegion>> OfflineRegion::New(jni::JNIEnv& env, + const jni::Object<FileSource>& jFileSource, + mbgl::OfflineRegion region) { // Definition auto definition = region.getDefinition().match( - [&](const mbgl::OfflineTilePyramidRegionDefinition def) { - return OfflineTilePyramidRegionDefinition::New(env, def); - }, [&](const mbgl::OfflineGeometryRegionDefinition def) { - return OfflineGeometryRegionDefinition::New(env, def); - }); + [&](const mbgl::OfflineTilePyramidRegionDefinition def) { + return OfflineTilePyramidRegionDefinition::New(env, def); + }, + [&](const mbgl::OfflineGeometryRegionDefinition def) { + return OfflineGeometryRegionDefinition::New(env, def); + }); // Create region java object static auto& javaClass = jni::Class<OfflineRegion>::Singleton(env); diff --git a/platform/android/src/offline/offline_region.hpp b/platform/android/src/offline/offline_region.hpp index dda253469e..6844008bb4 100644 --- a/platform/android/src/offline/offline_region.hpp +++ b/platform/android/src/offline/offline_region.hpp @@ -85,7 +85,7 @@ public: private: std::unique_ptr<mbgl::OfflineRegion> region; - std::shared_ptr<mbgl::DefaultFileSource> fileSource; + std::shared_ptr<mbgl::DatabaseFileSource> fileSource; }; } // namespace android |