summaryrefslogtreecommitdiff
path: root/platform/android
diff options
context:
space:
mode:
authorKonstantin Käfer <mail@kkaefer.com>2018-02-20 15:06:26 +0100
committerKonstantin Käfer <mail@kkaefer.com>2018-02-21 14:50:13 +0100
commit021e1ae596440cfdee5ffe75907b76069ae44307 (patch)
treeebf15ff8a72e5f14291ba37b6f297ca9a738eea4 /platform/android
parent06213d9145d3b20b63e235cc25678fd76dc296d0 (diff)
downloadqtlocation-mapboxgl-upstream/blob.tar.gz
[core] introduce Blob for compressed and uncompressed dataupstream/blob
- Blob is a wrapper type for a shared_ptr<const string> that has accessor functions for getting compressed and uncompressed data - Moved util::writeFile, util::readFile, util::compress, util::uncompress, decodeImage, and encodePNG to the Blob interface - Added Blob support to Request and file sources - Added Blob support to VectorTile objects - Added support for gzip decoding to util::uncompress - We're no longer compressing WebP, PNG, and JPEG data when storing in the OfflineDatabase - Android's HTTPRequest returns compressed Blobs by default One caveat is that our previous decompress function didn't support gzip, so once users upgrade to this version, their offline cache may contain both zlib-compressed data and gzip-compressed data, but older versions won't be able to decompress gzip data. On the other hand, we don't support downgrading SDKs anyway, so this shouldn't be a problem. To be on the safe side, we could bump the user_version of the SQLite DB.
Diffstat (limited to 'platform/android')
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/UnknownContentEncodingException.java12
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/http/HTTPRequest.java19
-rw-r--r--platform/android/src/asset_manager_file_source.cpp5
-rw-r--r--platform/android/src/http_file_source.cpp14
-rw-r--r--platform/android/src/image.cpp12
-rwxr-xr-xplatform/android/src/native_map_view.cpp4
6 files changed, 49 insertions, 17 deletions
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/UnknownContentEncodingException.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/UnknownContentEncodingException.java
new file mode 100644
index 0000000000..4debc33ee4
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/UnknownContentEncodingException.java
@@ -0,0 +1,12 @@
+package com.mapbox.mapboxsdk.exceptions;
+
+/**
+ * An UnknownContentEncodingException is thrown by HTTPRequest
+ * when there aren't enough LatLng to create a bounds.
+ */
+public class UnknownContentEncodingException extends RuntimeException {
+
+ public UnknownContentEncodingException(String encoding) {
+ super("Unknown content encoding '" + encoding + "'");
+ }
+}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/http/HTTPRequest.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/http/HTTPRequest.java
index caee493e6f..942b88f1fb 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/http/HTTPRequest.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/http/HTTPRequest.java
@@ -9,6 +9,7 @@ import android.text.TextUtils;
import com.mapbox.mapboxsdk.BuildConfig;
import com.mapbox.mapboxsdk.Mapbox;
import com.mapbox.mapboxsdk.constants.MapboxConstants;
+import com.mapbox.mapboxsdk.exceptions.UnknownContentEncodingException;
import java.io.IOException;
import java.io.InterruptedIOException;
@@ -66,7 +67,7 @@ class HTTPRequest implements Callback {
private native void nativeOnFailure(int type, String message);
private native void nativeOnResponse(int code, String etag, String modified, String cacheControl, String expires,
- String retryAfter, String xRateLimitReset, byte[] body);
+ String retryAfter, String xRateLimitReset, byte[] body, boolean gzip);
private HTTPRequest(long nativePtr, String resourceUrl, String etag, String modified) {
mNativePtr = nativePtr;
@@ -93,6 +94,7 @@ class HTTPRequest implements Callback {
Request.Builder builder = new Request.Builder()
.url(resourceUrl)
.tag(resourceUrl.toLowerCase(MapboxConstants.MAPBOX_LOCALE))
+ .addHeader("Accept-Encoding", "gzip, deflate")
.addHeader("User-Agent", getUserAgent());
if (etag.length() > 0) {
builder = builder.addHeader("If-None-Match", etag);
@@ -149,6 +151,18 @@ class HTTPRequest implements Callback {
mLock.lock();
if (mNativePtr != 0) {
+ String encoding = response.header("Content-Encoding");
+ boolean compressed = false;
+ if (encoding != null) {
+ if (encoding.equals("gzip") || encoding.equals("deflate")) {
+ compressed = true;
+ } else if (!encoding.equals("identity")) {
+ mLock.unlock();
+ handleFailure(call, new UnknownContentEncodingException(encoding));
+ return;
+ }
+ }
+
nativeOnResponse(response.code(),
response.header("ETag"),
response.header("Last-Modified"),
@@ -156,7 +170,8 @@ class HTTPRequest implements Callback {
response.header("Expires"),
response.header("Retry-After"),
response.header("x-rate-limit-reset"),
- body);
+ body,
+ compressed);
}
mLock.unlock();
}
diff --git a/platform/android/src/asset_manager_file_source.cpp b/platform/android/src/asset_manager_file_source.cpp
index aa65e3ff48..404177ba95 100644
--- a/platform/android/src/asset_manager_file_source.cpp
+++ b/platform/android/src/asset_manager_file_source.cpp
@@ -23,8 +23,9 @@ public:
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));
+ response.data = { { reinterpret_cast<const char*>(AAsset_getBuffer(asset)),
+ static_cast<size_t>(AAsset_getLength64(asset)) },
+ false };
AAsset_close(asset);
} else {
response.error = std::make_unique<Response::Error>(Response::Error::Reason::NotFound,
diff --git a/platform/android/src/http_file_source.cpp b/platform/android/src/http_file_source.cpp
index 8eb9416e9d..7602c1914e 100644
--- a/platform/android/src/http_file_source.cpp
+++ b/platform/android/src/http_file_source.cpp
@@ -30,7 +30,8 @@ public:
jni::String etag, jni::String modified,
jni::String cacheControl, jni::String expires,
jni::String retryAfter, jni::String xRateLimitReset,
- jni::Array<jni::jbyte> body);
+ jni::Array<jni::jbyte> body,
+ jni::jboolean compressed);
static jni::Class<HTTPRequest> javaClass;
jni::UniqueObject<HTTPRequest> javaRequest;
@@ -104,7 +105,8 @@ void HTTPRequest::onResponse(jni::JNIEnv& env, int code,
jni::String etag, jni::String modified,
jni::String cacheControl, jni::String expires,
jni::String jRetryAfter, jni::String jXRateLimitReset,
- jni::Array<jni::jbyte> body) {
+ jni::Array<jni::jbyte> body,
+ jni::jboolean compressed) {
using Error = Response::Error;
@@ -128,11 +130,11 @@ void HTTPRequest::onResponse(jni::JNIEnv& env, int code,
if (code == 200) {
if (body) {
- auto data = std::make_shared<std::string>(body.Length(env), char());
- jni::GetArrayRegion(env, *body, 0, data->size(), reinterpret_cast<jbyte*>(&(*data)[0]));
- response.data = data;
+ std::string data(static_cast<size_t>(body.Length(env)), char());
+ jni::GetArrayRegion(env, *body, 0, data.size(), reinterpret_cast<jbyte*>(&data[0]));
+ response.data = Blob{ std::move(data), static_cast<bool>(compressed) };
} else {
- response.data = std::make_shared<std::string>();
+ response.data = {};
}
} else if (code == 204 || (code == 404 && resource.kind == Resource::Kind::Tile)) {
response.noContent = true;
diff --git a/platform/android/src/image.cpp b/platform/android/src/image.cpp
index 2a33944b18..dd98a3a6c8 100644
--- a/platform/android/src/image.cpp
+++ b/platform/android/src/image.cpp
@@ -8,14 +8,16 @@
namespace mbgl {
-PremultipliedImage decodeImage(const std::string& string) {
+PremultipliedImage decodeImage(Blob blob) {
auto env{ android::AttachEnv() };
- auto array = jni::Array<jni::jbyte>::New(*env, string.size());
- jni::SetArrayRegion(*env, *array, 0, string.size(),
- reinterpret_cast<const signed char*>(string.data()));
+ const auto string = blob.uncompressedData();
- auto bitmap = android::BitmapFactory::DecodeByteArray(*env, array, 0, string.size());
+ auto array = jni::Array<jni::jbyte>::New(*env, string->size());
+ jni::SetArrayRegion(*env, *array, 0, string->size(),
+ reinterpret_cast<const signed char*>(string->data()));
+
+ auto bitmap = android::BitmapFactory::DecodeByteArray(*env, array, 0, string->size());
return android::Bitmap::GetImage(*env, bitmap);
}
diff --git a/platform/android/src/native_map_view.cpp b/platform/android/src/native_map_view.cpp
index 67fc132204..c52aad6405 100755
--- a/platform/android/src/native_map_view.cpp
+++ b/platform/android/src/native_map_view.cpp
@@ -188,11 +188,11 @@ void NativeMapView::setStyleUrl(jni::JNIEnv& env, jni::String url) {
}
jni::String NativeMapView::getStyleJson(jni::JNIEnv& env) {
- return jni::Make<jni::String>(env, map->getStyle().getJSON());
+ return jni::Make<jni::String>(env, *map->getStyle().getJSON().uncompressedData());
}
void NativeMapView::setStyleJson(jni::JNIEnv& env, jni::String json) {
- map->getStyle().loadJSON(jni::Make<std::string>(env, json));
+ map->getStyle().loadJSON(Blob{ jni::Make<std::string>(env, json), false });
}
void NativeMapView::setLatLngBounds(jni::JNIEnv& env, jni::Object<mbgl::android::LatLngBounds> jBounds) {