summaryrefslogtreecommitdiff
path: root/platform
diff options
context:
space:
mode:
authorKonstantin Käfer <mail@kkaefer.com>2017-04-11 17:18:09 +0200
committerKonstantin Käfer <mail@kkaefer.com>2017-04-24 10:42:10 +0200
commit197f0ca6b418a27412bfcc7e891ab80949fd8833 (patch)
treebb7dd2400bfc002dc5794466d3a74d39a80f8b00 /platform
parenteed7dedf030ed71aac6d004becef42dbec5606bf (diff)
downloadqtlocation-mapboxgl-197f0ca6b418a27412bfcc7e891ab80949fd8833.tar.gz
[android] use AAssetManager instead of libzip
Diffstat (limited to 'platform')
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/storage/FileSource.java10
-rw-r--r--platform/android/config.cmake11
-rw-r--r--platform/android/src/asset_file_source.cpp113
-rw-r--r--platform/android/src/asset_manager.hpp14
-rw-r--r--platform/android/src/asset_manager_file_source.cpp53
-rw-r--r--platform/android/src/asset_manager_file_source.hpp28
-rw-r--r--platform/android/src/file_source.cpp13
-rw-r--r--platform/android/src/file_source.hpp4
-rw-r--r--platform/android/src/jni.hpp1
-rw-r--r--platform/default/default_file_source.cpp8
10 files changed, 122 insertions, 133 deletions
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/storage/FileSource.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/storage/FileSource.java
index a12d8f9954..06676d76a1 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/storage/FileSource.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/storage/FileSource.java
@@ -5,6 +5,7 @@ import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.Environment;
import android.support.annotation.NonNull;
+import android.content.res.AssetManager;
import com.mapbox.mapboxsdk.Mapbox;
import com.mapbox.mapboxsdk.constants.MapboxConstants;
@@ -40,8 +41,7 @@ public class FileSource {
public static synchronized FileSource getInstance(Context context) {
if (INSTANCE == null) {
String cachePath = getCachePath(context);
- String apkPath = context.getPackageCodePath();
- INSTANCE = new FileSource(cachePath, apkPath);
+ INSTANCE = new FileSource(cachePath, context.getResources().getAssets());
}
return INSTANCE;
@@ -107,8 +107,8 @@ public class FileSource {
private long nativePtr;
- private FileSource(String cachePath, String apkPath) {
- initialize(Mapbox.getAccessToken(), cachePath, apkPath);
+ private FileSource(String cachePath, AssetManager assetManager) {
+ initialize(Mapbox.getAccessToken(), cachePath, assetManager);
}
public native void setAccessToken(@NonNull String accessToken);
@@ -127,7 +127,7 @@ public class FileSource {
*/
public native void setResourceTransform(final ResourceTransformCallback callback);
- private native void initialize(String accessToken, String cachePath, String apkPath);
+ private native void initialize(String accessToken, String cachePath, AssetManager assetManager);
@Override
protected native void finalize() throws Throwable;
diff --git a/platform/android/config.cmake b/platform/android/config.cmake
index 2e39437109..7c10ba96f8 100644
--- a/platform/android/config.cmake
+++ b/platform/android/config.cmake
@@ -16,7 +16,6 @@ if ((ANDROID_ABI STREQUAL "armeabi") OR (ANDROID_ABI STREQUAL "armeabi-v7a") OR
endif()
mason_use(jni.hpp VERSION 3.0.0 HEADER_ONLY)
-mason_use(libzip VERSION 1.1.3)
mason_use(nunicode VERSION 1.7.1)
mason_use(sqlite VERSION 3.14.2)
mason_use(gtest VERSION 1.8.0)
@@ -34,8 +33,11 @@ macro(mbgl_platform_core)
# File source
PRIVATE platform/android/src/http_file_source.cpp
- PRIVATE platform/android/src/asset_file_source.cpp
+ PRIVATE platform/android/src/asset_manager.hpp
+ PRIVATE platform/android/src/asset_manager_file_source.cpp
+ PRIVATE platform/android/src/asset_manager_file_source.hpp
PRIVATE platform/default/default_file_source.cpp
+ PRIVATE platform/default/asset_file_source.cpp
PRIVATE platform/default/local_file_source.cpp
PRIVATE platform/default/online_file_source.cpp
@@ -76,7 +78,6 @@ macro(mbgl_platform_core)
target_add_mason_package(mbgl-core PUBLIC sqlite)
target_add_mason_package(mbgl-core PUBLIC nunicode)
- target_add_mason_package(mbgl-core PUBLIC libzip)
target_add_mason_package(mbgl-core PUBLIC geojson)
target_add_mason_package(mbgl-core PUBLIC jni.hpp)
target_add_mason_package(mbgl-core PUBLIC rapidjson)
@@ -305,10 +306,6 @@ macro(mbgl_platform_test)
PRIVATE -fvisibility=hidden
)
- target_compile_definitions(mbgl-test
- PRIVATE MBGL_ASSET_ZIP=1
- )
-
target_link_libraries(mbgl-test
PRIVATE mbgl-android
PRIVATE -Wl,--gc-sections
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);
diff --git a/platform/default/default_file_source.cpp b/platform/default/default_file_source.cpp
index 20a3eadc8b..27c3950e2a 100644
--- a/platform/default/default_file_source.cpp
+++ b/platform/default/default_file_source.cpp
@@ -167,9 +167,15 @@ private:
DefaultFileSource::DefaultFileSource(const std::string& cachePath,
const std::string& assetRoot,
uint64_t maximumCacheSize)
+ : DefaultFileSource(cachePath, std::make_unique<AssetFileSource>(assetRoot), maximumCacheSize) {
+}
+
+DefaultFileSource::DefaultFileSource(const std::string& cachePath,
+ std::unique_ptr<FileSource>&& assetFileSource_,
+ uint64_t maximumCacheSize)
: thread(std::make_unique<util::Thread<Impl>>(util::ThreadContext{"DefaultFileSource", util::ThreadPriority::Low},
cachePath, maximumCacheSize)),
- assetFileSource(std::make_unique<AssetFileSource>(assetRoot)),
+ assetFileSource(std::move(assetFileSource_)),
localFileSource(std::make_unique<LocalFileSource>()) {
}