summaryrefslogtreecommitdiff
path: root/platform/android/src/offline/offline_region.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'platform/android/src/offline/offline_region.cpp')
-rw-r--r--platform/android/src/offline/offline_region.cpp203
1 files changed, 73 insertions, 130 deletions
diff --git a/platform/android/src/offline/offline_region.cpp b/platform/android/src/offline/offline_region.cpp
index 5ed37eda73..1cd73a7c76 100644
--- a/platform/android/src/offline/offline_region.cpp
+++ b/platform/android/src/offline/offline_region.cpp
@@ -7,81 +7,62 @@
#include "offline_region_error.hpp"
#include "offline_region_status.hpp"
#include "../attach_env.hpp"
-#include "../jni/generic_global_ref_deleter.hpp"
namespace mbgl {
namespace android {
// OfflineRegion //
-OfflineRegion::OfflineRegion(jni::JNIEnv& env, jni::jlong offlineRegionPtr, jni::Object<FileSource> jFileSource)
+OfflineRegion::OfflineRegion(jni::JNIEnv& env, jni::jlong offlineRegionPtr, const jni::Object<FileSource>& jFileSource)
: region(reinterpret_cast<mbgl::OfflineRegion *>(offlineRegionPtr)),
fileSource(mbgl::android::FileSource::getDefaultFileSource(env, jFileSource)) {}
OfflineRegion::~OfflineRegion() {}
-void OfflineRegion::setOfflineRegionObserver(jni::JNIEnv& env_, jni::Object<OfflineRegion::OfflineRegionObserver> callback) {
+void OfflineRegion::setOfflineRegionObserver(jni::JNIEnv& env_, const jni::Object<OfflineRegion::OfflineRegionObserver>& callback) {
// Define the observer
class Observer : public mbgl::OfflineRegionObserver {
public:
- Observer(jni::UniqueObject<OfflineRegion::OfflineRegionObserver>&& callback_)
- //TODO add a generic deleter for jni::Object
- : callback(callback_.release()->Get()) {
- }
-
- ~Observer() override {
- android::UniqueEnv env = android::AttachEnv();
- env->DeleteGlobalRef(Unwrap(*callback));
+ Observer(jni::Global<jni::Object<OfflineRegion::OfflineRegionObserver>, jni::EnvAttachingDeleter> callback_)
+ : callback(std::move(callback_)) {
}
void statusChanged(mbgl::OfflineRegionStatus status) override {
// Reattach, the callback comes from a different thread
android::UniqueEnv env = android::AttachEnv();
- // Status object
- auto jStatus = OfflineRegionStatus::New(*env, status);
+ static auto& javaClass = jni::Class<OfflineRegion::OfflineRegionObserver>::Singleton(*env);
+ static auto method = javaClass.GetMethod<void (jni::Object<OfflineRegionStatus>)>(*env, "onStatusChanged");
- // Call
- static auto method = OfflineRegion::OfflineRegionObserver::javaClass
- .GetMethod<void (jni::Object<OfflineRegionStatus>)>(*env, "onStatusChanged");
- callback.Call(*env, method, jStatus);
-
- // Delete references
- jni::DeleteLocalRef(*env, jStatus);
+ callback.Call(*env, method, OfflineRegionStatus::New(*env, status));
}
void responseError(mbgl::Response::Error error) override {
// Reattach, the callback comes from a different thread
android::UniqueEnv env = android::AttachEnv();
- // Error object
- auto jError = OfflineRegionError::New(*env, error);
-
- // Call
- static auto method = OfflineRegion::OfflineRegionObserver::javaClass
- .GetMethod<void (jni::Object<mbgl::android::OfflineRegionError>)>(*env, "onError");
- callback.Call(*env, method, jError);
+ static auto& javaClass = jni::Class<OfflineRegion::OfflineRegionObserver>::Singleton(*env);
+ static auto method = javaClass.GetMethod<void (jni::Object<mbgl::android::OfflineRegionError>)>(*env, "onError");
- // Delete references
- jni::DeleteLocalRef(*env, jError);
+ callback.Call(*env, method, OfflineRegionError::New(*env, error));
}
void mapboxTileCountLimitExceeded(uint64_t limit) override {
// Reattach, the callback comes from a different thread
android::UniqueEnv env = android::AttachEnv();
- // Send limit
- static auto method = OfflineRegion::OfflineRegionObserver::javaClass
- .GetMethod<void (jni::jlong)>(*env, "mapboxTileCountLimitExceeded");
+ static auto& javaClass = jni::Class<OfflineRegion::OfflineRegionObserver>::Singleton(*env);
+ static auto method = javaClass.GetMethod<void (jni::jlong)>(*env, "mapboxTileCountLimitExceeded");
+
callback.Call(*env, method, jlong(limit));
}
- jni::Object<OfflineRegion::OfflineRegionObserver> callback;
+ jni::Global<jni::Object<OfflineRegion::OfflineRegionObserver>, jni::EnvAttachingDeleter> callback;
};
// Set the observer
- fileSource.setOfflineRegionObserver(*region, std::make_unique<Observer>(callback.NewGlobalRef(env_)));
+ fileSource.setOfflineRegionObserver(*region, std::make_unique<Observer>(jni::NewGlobal<jni::EnvAttachingDeleter>(env_, callback)));
}
void OfflineRegion::setOfflineRegionDownloadState(jni::JNIEnv&, jni::jint jState) {
@@ -102,89 +83,84 @@ void OfflineRegion::setOfflineRegionDownloadState(jni::JNIEnv&, jni::jint jState
fileSource.setOfflineRegionDownloadState(*region, state);
}
-void OfflineRegion::getOfflineRegionStatus(jni::JNIEnv& env_, jni::Object<OfflineRegionStatusCallback> callback_) {
+void OfflineRegion::getOfflineRegionStatus(jni::JNIEnv& env_, const jni::Object<OfflineRegionStatusCallback>& callback_) {
+ auto globalCallback = jni::NewGlobal<jni::EnvAttachingDeleter>(env_, callback_);
fileSource.getOfflineRegionStatus(*region, [
//Ensure the object is not gc'd in the meanwhile
- callback = std::shared_ptr<jni::jobject>(callback_.NewGlobalRef(env_).release()->Get(), GenericGlobalRefDeleter())
+ callback = std::make_shared<decltype(globalCallback)>(std::move(globalCallback))
](mbgl::expected<mbgl::OfflineRegionStatus, std::exception_ptr> status) mutable {
// Reattach, the callback comes from a different thread
android::UniqueEnv env = android::AttachEnv();
if (status) {
- OfflineRegionStatusCallback::onStatus(*env, jni::Object<OfflineRegionStatusCallback>(*callback), std::move(*status));
+ OfflineRegionStatusCallback::onStatus(*env, *callback, std::move(*status));
} else {
- OfflineRegionStatusCallback::onError(*env, jni::Object<OfflineRegionStatusCallback>(*callback), status.error());
+ OfflineRegionStatusCallback::onError(*env, *callback, status.error());
}
});
}
-void OfflineRegion::deleteOfflineRegion(jni::JNIEnv& env_, jni::Object<OfflineRegionDeleteCallback> callback_) {
- // Delete
+void OfflineRegion::deleteOfflineRegion(jni::JNIEnv& env_, const jni::Object<OfflineRegionDeleteCallback>& callback_) {
+ auto globalCallback = jni::NewGlobal<jni::EnvAttachingDeleter>(env_, callback_);
+
fileSource.deleteOfflineRegion(std::move(*region), [
//Ensure the object is not gc'd in the meanwhile
- callback = std::shared_ptr<jni::jobject>(callback_.NewGlobalRef(env_).release()->Get(), GenericGlobalRefDeleter())
+ callback = std::make_shared<decltype(globalCallback)>(std::move(globalCallback))
](std::exception_ptr error) mutable {
// Reattach, the callback comes from a different thread
android::UniqueEnv env = android::AttachEnv();
if (error) {
- OfflineRegionDeleteCallback::onError(*env, jni::Object<OfflineRegionDeleteCallback>(*callback), error);
+ OfflineRegionDeleteCallback::onError(*env, *callback, error);
} else {
- OfflineRegionDeleteCallback::onDelete(*env, jni::Object<OfflineRegionDeleteCallback>(*callback));
+ OfflineRegionDeleteCallback::onDelete(*env, *callback);
}
});
}
-void OfflineRegion::updateOfflineRegionMetadata(jni::JNIEnv& env_, jni::Array<jni::jbyte> jMetadata, jni::Object<OfflineRegionUpdateMetadataCallback> callback_) {
-
- // Convert
+void OfflineRegion::updateOfflineRegionMetadata(jni::JNIEnv& env_, const jni::Array<jni::jbyte>& jMetadata, const jni::Object<OfflineRegionUpdateMetadataCallback>& callback_) {
auto metadata = OfflineRegion::metadata(env_, jMetadata);
+ auto globalCallback = jni::NewGlobal<jni::EnvAttachingDeleter>(env_, callback_);
fileSource.updateOfflineMetadata(region->getID(), metadata, [
//Ensure the object is not gc'd in the meanwhile
- callback = std::shared_ptr<jni::jobject>(callback_.NewGlobalRef(env_).release()->Get(), GenericGlobalRefDeleter())
+ callback = std::make_shared<decltype(globalCallback)>(std::move(globalCallback))
](mbgl::expected<mbgl::OfflineRegionMetadata, std::exception_ptr> data) mutable {
// Reattach, the callback comes from a different thread
android::UniqueEnv env = android::AttachEnv();
if (data) {
- OfflineRegionUpdateMetadataCallback::onUpdate(*env, jni::Object<OfflineRegionUpdateMetadataCallback>(*callback), std::move(*data));
+ OfflineRegionUpdateMetadataCallback::onUpdate(*env, *callback, std::move(*data));
} else {
- OfflineRegionUpdateMetadataCallback::onError(*env, jni::Object<OfflineRegionUpdateMetadataCallback>(*callback), data.error());
+ OfflineRegionUpdateMetadataCallback::onError(*env, *callback, data.error());
}
});
}
-jni::Object<OfflineRegion> OfflineRegion::New(jni::JNIEnv& env, 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 jni::Object<OfflineRegionDefinition>(
- *OfflineTilePyramidRegionDefinition::New(env, def));
+ return OfflineTilePyramidRegionDefinition::New(env, def);
}, [&](const mbgl::OfflineGeometryRegionDefinition def) {
- return jni::Object<OfflineRegionDefinition>(
- *OfflineGeometryRegionDefinition::New(env, def));
+ return OfflineGeometryRegionDefinition::New(env, def);
});
- // Metadata
- auto metadata = OfflineRegion::metadata(env, region.getMetadata());
-
// Create region java object
- static auto constructor = OfflineRegion::javaClass.GetConstructor<jni::jlong, jni::Object<FileSource>, jni::jlong, jni::Object<OfflineRegionDefinition>, jni::Array<jni::jbyte>>(env);
- auto jregion = OfflineRegion::javaClass.New(env, constructor,
- reinterpret_cast<jni::jlong>(new mbgl::OfflineRegion(std::move(region))), //Copy a region to the heap
- jFileSource, jni::jlong(region.getID()), definition, metadata);
-
- //Delete references
- jni::DeleteLocalRef(env, definition);
- jni::DeleteLocalRef(env, metadata);
+ static auto& javaClass = jni::Class<OfflineRegion>::Singleton(env);
+ static auto constructor = javaClass.GetConstructor<jni::jlong, jni::Object<FileSource>, jni::jlong, jni::Object<OfflineRegionDefinition>, jni::Array<jni::jbyte>>(env);
- return jregion;
+ return javaClass.New(env, constructor,
+ reinterpret_cast<jni::jlong>(new mbgl::OfflineRegion(std::move(region))), //Copy a region to the heap
+ jFileSource,
+ jni::jlong(region.getID()),
+ definition,
+ OfflineRegion::metadata(env, region.getMetadata()));
}
-jni::Array<jni::jbyte> OfflineRegion::metadata(jni::JNIEnv& env, mbgl::OfflineRegionMetadata metadata_) {
+jni::Local<jni::Array<jni::jbyte>> OfflineRegion::metadata(jni::JNIEnv& env, mbgl::OfflineRegionMetadata metadata_) {
std::vector<jni::jbyte> convertedMetadata(metadata_.begin(), metadata_.end());
std::size_t length = static_cast<std::size_t>(convertedMetadata.size());
auto metadata = jni::Array<jni::jbyte>::New(env, length);
@@ -192,7 +168,7 @@ jni::Array<jni::jbyte> OfflineRegion::metadata(jni::JNIEnv& env, mbgl::OfflineRe
return metadata;
}
-mbgl::OfflineRegionMetadata OfflineRegion::metadata(jni::JNIEnv& env, jni::Array<jni::jbyte> metadata_) {
+mbgl::OfflineRegionMetadata OfflineRegion::metadata(jni::JNIEnv& env, const jni::Array<jni::jbyte>& metadata_) {
std::size_t length = metadata_.Length(env);
auto metadata_tmp = std::vector<jni::jbyte>();
metadata_tmp.resize(length);
@@ -201,20 +177,18 @@ mbgl::OfflineRegionMetadata OfflineRegion::metadata(jni::JNIEnv& env, jni::Array
return metadata;
}
-jni::Class<OfflineRegion> OfflineRegion::javaClass;
-
void OfflineRegion::registerNative(jni::JNIEnv& env) {
- OfflineRegion::OfflineRegionObserver::registerNative(env);
- OfflineRegion::OfflineRegionStatusCallback::registerNative(env);
- OfflineRegion::OfflineRegionDeleteCallback::registerNative(env);
- OfflineRegion::OfflineRegionUpdateMetadataCallback::registerNative(env);
+ jni::Class<OfflineRegionObserver>::Singleton(env);
+ jni::Class<OfflineRegionStatusCallback>::Singleton(env);
+ jni::Class<OfflineRegionDeleteCallback>::Singleton(env);
+ jni::Class<OfflineRegionUpdateMetadataCallback>::Singleton(env);
- javaClass = *jni::Class<OfflineRegion>::Find(env).NewGlobalRef(env).release();
+ static auto& javaClass = jni::Class<OfflineRegion>::Singleton(env);
#define METHOD(MethodPtr, name) jni::MakeNativePeerMethod<decltype(MethodPtr), (MethodPtr)>(name)
jni::RegisterNativePeer<OfflineRegion>( env, javaClass, "nativePtr",
- std::make_unique<OfflineRegion, JNIEnv&, jni::jlong, jni::Object<FileSource>>,
+ jni::MakePeer<OfflineRegion, jni::jlong, const jni::Object<FileSource>&>,
"initialize",
"finalize",
METHOD(&OfflineRegion::setOfflineRegionObserver, "setOfflineRegionObserver"),
@@ -227,94 +201,63 @@ void OfflineRegion::registerNative(jni::JNIEnv& env) {
// OfflineRegionObserver //
-jni::Class<OfflineRegion::OfflineRegionObserver> OfflineRegion::OfflineRegionObserver::javaClass;
-
-void OfflineRegion::OfflineRegionObserver::registerNative(jni::JNIEnv& env) {
- javaClass = *jni::Class<OfflineRegion::OfflineRegionObserver>::Find(env).NewGlobalRef(env).release();
-}
-
// OfflineRegionStatusCallback //
-jni::Class<OfflineRegion::OfflineRegionStatusCallback> OfflineRegion::OfflineRegionStatusCallback::javaClass;
-
-void OfflineRegion::OfflineRegionStatusCallback::registerNative(jni::JNIEnv& env) {
- javaClass = *jni::Class<OfflineRegionStatusCallback>::Find(env).NewGlobalRef(env).release();
-}
-
void OfflineRegion::OfflineRegionStatusCallback::onError(jni::JNIEnv& env,
- jni::Object<OfflineRegion::OfflineRegionStatusCallback> callback,
+ const jni::Object<OfflineRegion::OfflineRegionStatusCallback>& callback,
std::exception_ptr error) {
+ static auto& javaClass = jni::Class<OfflineRegion::OfflineRegionStatusCallback>::Singleton(env);
static auto method = javaClass.GetMethod<void (jni::String)>(env, "onError");
- std::string message = mbgl::util::toString(error);
- auto jmessage = jni::Make<jni::String>(env, message);
- callback.Call(env, method, jmessage);
- jni::DeleteLocalRef(env, jmessage);
+
+ callback.Call(env, method, jni::Make<jni::String>(env, mbgl::util::toString(error)));
}
void OfflineRegion::OfflineRegionStatusCallback::onStatus(jni::JNIEnv& env,
- jni::Object<OfflineRegion::OfflineRegionStatusCallback> callback,
+ const jni::Object<OfflineRegion::OfflineRegionStatusCallback>& callback,
mbgl::optional<mbgl::OfflineRegionStatus> status) {
- //Convert to java peer object
- auto jStatus = OfflineRegionStatus::New(env, std::move(*status));
-
- // Trigger callback
+ static auto& javaClass = jni::Class<OfflineRegion::OfflineRegionStatusCallback>::Singleton(env);
static auto method = javaClass.GetMethod<void (jni::Object<OfflineRegionStatus>)>(env, "onStatus");
- callback.Call(env, method, jStatus);
- jni::DeleteLocalRef(env, jStatus);
+
+ callback.Call(env, method, OfflineRegionStatus::New(env, std::move(*status)));
}
// OfflineRegionDeleteCallback //
-jni::Class<OfflineRegion::OfflineRegionDeleteCallback> OfflineRegion::OfflineRegionDeleteCallback::javaClass;
-
-void OfflineRegion::OfflineRegionDeleteCallback::registerNative(jni::JNIEnv& env) {
- javaClass = *jni::Class<OfflineRegionDeleteCallback>::Find(env).NewGlobalRef(env).release();
-}
-
void OfflineRegion::OfflineRegionDeleteCallback::onError(jni::JNIEnv& env,
- jni::Object<OfflineRegion::OfflineRegionDeleteCallback> callback,
+ const jni::Object<OfflineRegion::OfflineRegionDeleteCallback>& callback,
std::exception_ptr error) {
+ static auto& javaClass = jni::Class<OfflineRegion::OfflineRegionDeleteCallback>::Singleton(env);
static auto method = javaClass.GetMethod<void (jni::String)>(env, "onError");
- std::string message = mbgl::util::toString(error);
- auto jmessage = jni::Make<jni::String>(env, message);
- callback.Call(env, method, jmessage);
- jni::DeleteLocalRef(env, jmessage);
+
+ callback.Call(env, method, jni::Make<jni::String>(env, mbgl::util::toString(error)));
}
-void OfflineRegion::OfflineRegionDeleteCallback::onDelete(jni::JNIEnv& env, jni::Object<OfflineRegion::OfflineRegionDeleteCallback> callback) {
+void OfflineRegion::OfflineRegionDeleteCallback::onDelete(jni::JNIEnv& env, const jni::Object<OfflineRegion::OfflineRegionDeleteCallback>& callback) {
// Trigger callback
+ static auto& javaClass = jni::Class<OfflineRegion::OfflineRegionDeleteCallback>::Singleton(env);
static auto method = javaClass.GetMethod<void ()>(env, "onDelete");
+
callback.Call(env, method);
}
// OfflineRegionUpdateMetadataCallback //
-jni::Class<OfflineRegion::OfflineRegionUpdateMetadataCallback> OfflineRegion::OfflineRegionUpdateMetadataCallback::javaClass;
-
-void OfflineRegion::OfflineRegionUpdateMetadataCallback::registerNative(jni::JNIEnv& env) {
- javaClass = *jni::Class<OfflineRegionUpdateMetadataCallback>::Find(env).NewGlobalRef(env).release();
-}
-
void OfflineRegion::OfflineRegionUpdateMetadataCallback::onError(jni::JNIEnv& env,
- jni::Object<OfflineRegion::OfflineRegionUpdateMetadataCallback> callback,
+ const jni::Object<OfflineRegion::OfflineRegionUpdateMetadataCallback>& callback,
std::exception_ptr error) {
+ static auto& javaClass = jni::Class<OfflineRegion::OfflineRegionUpdateMetadataCallback>::Singleton(env);
static auto method = javaClass.GetMethod<void (jni::String)>(env, "onError");
- std::string message = mbgl::util::toString(error);
- auto jmessage = jni::Make<jni::String>(env, message);
- callback.Call(env, method, jmessage);
- jni::DeleteLocalRef(env, jmessage);
+
+ callback.Call(env, method, jni::Make<jni::String>(env, mbgl::util::toString(error)));
}
void OfflineRegion::OfflineRegionUpdateMetadataCallback::onUpdate(jni::JNIEnv& env,
- jni::Object<OfflineRegion::OfflineRegionUpdateMetadataCallback> callback,
+ const jni::Object<OfflineRegion::OfflineRegionUpdateMetadataCallback>& callback,
mbgl::optional<mbgl::OfflineRegionMetadata> metadata) {
- //Convert to java peer object
- auto jMetadata = OfflineRegion::metadata(env, std::move(*metadata));
-
- // Trigger callback
+ static auto& javaClass = jni::Class<OfflineRegion::OfflineRegionUpdateMetadataCallback>::Singleton(env);
static auto method = javaClass.GetMethod<void (jni::Array<jni::jbyte>)>(env, "onUpdate");
- callback.Call(env, method, jMetadata);
- jni::DeleteLocalRef(env, jMetadata);
+
+ callback.Call(env, method, OfflineRegion::metadata(env, std::move(*metadata)));
}
} // namespace android