diff options
author | Konstantin Käfer <mail@kkaefer.com> | 2017-04-11 17:18:09 +0200 |
---|---|---|
committer | Konstantin Käfer <mail@kkaefer.com> | 2017-04-24 10:42:10 +0200 |
commit | 197f0ca6b418a27412bfcc7e891ab80949fd8833 (patch) | |
tree | bb7dd2400bfc002dc5794466d3a74d39a80f8b00 /platform/android/src | |
parent | eed7dedf030ed71aac6d004becef42dbec5606bf (diff) | |
download | qtlocation-mapboxgl-197f0ca6b418a27412bfcc7e891ab80949fd8833.tar.gz |
[android] use AAssetManager instead of libzip
Diffstat (limited to 'platform/android/src')
-rw-r--r-- | platform/android/src/asset_file_source.cpp | 113 | ||||
-rw-r--r-- | platform/android/src/asset_manager.hpp | 14 | ||||
-rw-r--r-- | platform/android/src/asset_manager_file_source.cpp | 53 | ||||
-rw-r--r-- | platform/android/src/asset_manager_file_source.hpp | 28 | ||||
-rw-r--r-- | platform/android/src/file_source.cpp | 13 | ||||
-rw-r--r-- | platform/android/src/file_source.hpp | 4 | ||||
-rw-r--r-- | platform/android/src/jni.hpp | 1 |
7 files changed, 106 insertions, 120 deletions
diff --git a/platform/android/src/asset_file_source.cpp b/platform/android/src/asset_file_source.cpp deleted file mode 100644 index c72b86af5c..0000000000 --- a/platform/android/src/asset_file_source.cpp +++ /dev/null @@ -1,113 +0,0 @@ -#include <mbgl/storage/asset_file_source.hpp> -#include <mbgl/storage/response.hpp> -#include <mbgl/util/util.hpp> -#include <mbgl/util/thread.hpp> -#include <mbgl/util/url.hpp> - -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wshadow" -#include <zip.h> -#pragma GCC diagnostic pop - -namespace { - -struct ZipHolder { - ZipHolder(struct zip* archive_) : archive(archive_) {} - - ~ZipHolder() { - if (archive) ::zip_close(archive); - } - - struct zip* archive; -}; - -struct ZipFileHolder { - ZipFileHolder(struct zip_file* file_) : file(file_) {} - - ~ZipFileHolder() { - if (file) ::zip_fclose(file); - } - - struct zip_file* file; -}; - -} - -namespace mbgl { - -class AssetFileRequest : public AsyncRequest { -public: - AssetFileRequest(std::unique_ptr<WorkRequest> workRequest_) - : workRequest(std::move(workRequest_)) { - } - - std::unique_ptr<WorkRequest> workRequest; -}; - -class AssetFileSource::Impl { -public: - Impl(const std::string& root_) - : root(root_) { - } - - void request(const std::string& url, FileSource::Callback callback) { - ZipHolder archive = ::zip_open(root.c_str(), 0, nullptr); - if (!archive.archive) { - reportError(Response::Error::Reason::Other, "Could not open zip archive", callback); - return; - } - - struct zip_stat stat; - ::zip_stat_init(&stat); - - std::string path = std::string("assets/") + mbgl::util::percentDecode(url.substr(8)); - - int ret = ::zip_stat(archive.archive, path.c_str(), 0, &stat); - if (ret < 0 || !(stat.valid & ZIP_STAT_SIZE)) { - reportError(Response::Error::Reason::NotFound, "Could not stat file in zip archive", callback); - return; - } - - ZipFileHolder file = ::zip_fopen(archive.archive, path.c_str(), 0); - if (!file.file) { - reportError(Response::Error::Reason::NotFound, "Could not open file in zip archive", callback); - return; - } - - std::shared_ptr<std::string> buf = std::make_shared<std::string>(); - buf->resize(stat.size); - - ret = ::zip_fread(file.file, &buf->front(), stat.size); - if (ret < 0) { - reportError(Response::Error::Reason::Other, "Could not read file in zip archive", callback); - return; - } - - Response response; - response.data = buf; - callback(response); - } - - void reportError(Response::Error::Reason reason, const char * message, FileSource::Callback callback) { - Response response; - response.error = std::make_unique<Response::Error>(reason, message); - callback(response); - } - -private: - std::string root; -}; - -AssetFileSource::AssetFileSource(const std::string& root) - : thread(std::make_unique<util::Thread<Impl>>( - util::ThreadContext{"AssetFileSource", util::ThreadPriority::Low}, - root)) { -} - -AssetFileSource::~AssetFileSource() = default; - -std::unique_ptr<AsyncRequest> AssetFileSource::request(const Resource& resource, Callback callback) { - return thread->invokeWithCallback(&Impl::request, resource.url, callback); -} - -} diff --git a/platform/android/src/asset_manager.hpp b/platform/android/src/asset_manager.hpp new file mode 100644 index 0000000000..b87d189514 --- /dev/null +++ b/platform/android/src/asset_manager.hpp @@ -0,0 +1,14 @@ +#pragma once + +namespace mbgl { +namespace android { + +class AssetManager { +public: + static constexpr auto Name() { + return "android/content/res/AssetManager"; + }; +}; + +} // namespace android +} // namespace mbgl diff --git a/platform/android/src/asset_manager_file_source.cpp b/platform/android/src/asset_manager_file_source.cpp new file mode 100644 index 0000000000..6a3113d696 --- /dev/null +++ b/platform/android/src/asset_manager_file_source.cpp @@ -0,0 +1,53 @@ +#include "asset_manager_file_source.hpp" + +#include <mbgl/storage/response.hpp> +#include <mbgl/util/util.hpp> +#include <mbgl/util/thread.hpp> +#include <mbgl/util/url.hpp> + +#include <android/asset_manager.h> +#include <android/asset_manager_jni.h> + +namespace mbgl { + +class AssetManagerFileSource::Impl { +public: + Impl(AAssetManager* assetManager_) : assetManager(assetManager_) { + } + + void request(const std::string& url, FileSource::Callback callback) { + // Note: AssetManager already prepends "assets" to the filename. + const std::string path = mbgl::util::percentDecode(url.substr(8)); + + Response response; + + if (AAsset* asset = AAssetManager_open(assetManager, path.c_str(), AASSET_MODE_BUFFER)) { + response.data = std::make_shared<std::string>( + reinterpret_cast<const char*>(AAsset_getBuffer(asset)), AAsset_getLength64(asset)); + AAsset_close(asset); + } else { + response.error = std::make_unique<Response::Error>(Response::Error::Reason::NotFound, + "Could not read asset"); + } + + callback(response); + } + +private: + AAssetManager* assetManager; +}; + +AssetManagerFileSource::AssetManagerFileSource(jni::JNIEnv& env, jni::Object<android::AssetManager> assetManager_) + : assetManager(assetManager_.NewGlobalRef(env)), + thread(std::make_unique<util::Thread<Impl>>( + util::ThreadContext{"AssetManagerFileSource", util::ThreadPriority::Low}, + AAssetManager_fromJava(&env, jni::Unwrap(**assetManager)))) { +} + +AssetManagerFileSource::~AssetManagerFileSource() = default; + +std::unique_ptr<AsyncRequest> AssetManagerFileSource::request(const Resource& resource, Callback callback) { + return thread->invokeWithCallback(&Impl::request, resource.url, callback); +} + +} // namespace mbgl diff --git a/platform/android/src/asset_manager_file_source.hpp b/platform/android/src/asset_manager_file_source.hpp new file mode 100644 index 0000000000..7a447a2c61 --- /dev/null +++ b/platform/android/src/asset_manager_file_source.hpp @@ -0,0 +1,28 @@ +#pragma once + +#include <mbgl/storage/file_source.hpp> + +#include "asset_manager.hpp" + +#include <jni/jni.hpp> + +namespace mbgl { + +namespace util { +template <typename T> class Thread; +} // namespace util + +class AssetManagerFileSource : public FileSource { +public: + AssetManagerFileSource(jni::JNIEnv&, jni::Object<android::AssetManager>); + ~AssetManagerFileSource() override; + + std::unique_ptr<AsyncRequest> request(const Resource&, Callback) override; + +private: + jni::UniqueObject<android::AssetManager> assetManager; + class Impl; + std::unique_ptr<util::Thread<Impl>> thread; +}; + +} // namespace mbgl diff --git a/platform/android/src/file_source.cpp b/platform/android/src/file_source.cpp index 20715bf920..16c09b7b52 100644 --- a/platform/android/src/file_source.cpp +++ b/platform/android/src/file_source.cpp @@ -2,21 +2,24 @@ #include <mbgl/util/logging.hpp> -#include <string> - +#include "asset_manager_file_source.hpp" #include "jni/generic_global_ref_deleter.hpp" +#include <string> namespace mbgl { namespace android { // FileSource // -FileSource::FileSource(jni::JNIEnv& _env, jni::String accessToken, jni::String _cachePath, jni::String _apkPath) { +FileSource::FileSource(jni::JNIEnv& _env, + jni::String accessToken, + jni::String _cachePath, + jni::Object<AssetManager> assetManager) { // Create a core default file source fileSource = std::make_unique<mbgl::DefaultFileSource>( jni::Make<std::string>(_env, _cachePath) + "/mbgl-offline.db", - jni::Make<std::string>(_env, _apkPath)); + std::make_unique<AssetManagerFileSource>(_env, assetManager)); // Set access token fileSource->setAccessToken(jni::Make<std::string>(_env, accessToken)); @@ -80,7 +83,7 @@ void FileSource::registerNative(jni::JNIEnv& env) { // Register the peer jni::RegisterNativePeer<FileSource>( env, FileSource::javaClass, "nativePtr", - std::make_unique<FileSource, JNIEnv&, jni::String, jni::String, jni::String>, + std::make_unique<FileSource, JNIEnv&, jni::String, jni::String, jni::Object<AssetManager>>, "initialize", "finalize", METHOD(&FileSource::getAccessToken, "getAccessToken"), diff --git a/platform/android/src/file_source.hpp b/platform/android/src/file_source.hpp index 073e393e05..55e70f34d9 100644 --- a/platform/android/src/file_source.hpp +++ b/platform/android/src/file_source.hpp @@ -2,6 +2,8 @@ #include <mbgl/storage/default_file_source.hpp> +#include "asset_manager.hpp" + #include <jni/jni.hpp> namespace mbgl { @@ -23,7 +25,7 @@ public: static jni::Class<ResourceTransformCallback> javaClass; }; - FileSource(jni::JNIEnv&, jni::String, jni::String, jni::String); + FileSource(jni::JNIEnv&, jni::String, jni::String, jni::Object<AssetManager>); ~FileSource(); diff --git a/platform/android/src/jni.hpp b/platform/android/src/jni.hpp index f0c113f754..e5df92e701 100644 --- a/platform/android/src/jni.hpp +++ b/platform/android/src/jni.hpp @@ -13,7 +13,6 @@ extern JavaVM* theJVM; extern std::string cachePath; extern std::string dataPath; -extern std::string apkPath; bool attach_jni_thread(JavaVM* vm, JNIEnv** env, std::string threadName); void detach_jni_thread(JavaVM* vm, JNIEnv** env, bool detach); |