From ed5ed8f083398efff49a4dae1d0f1833f63a0fe6 Mon Sep 17 00:00:00 2001 From: Mikhail Pozdnyakov Date: Fri, 8 Nov 2019 18:14:35 +0200 Subject: [android] Add OfflineRegion.deleteAndSkipPackDatabase --- .../mapbox/mapboxsdk/offline/OfflineRegion.java | 52 ++++++++++++++- platform/android/src/offline/offline_region.cpp | 77 +++++++++++++--------- platform/android/src/offline/offline_region.hpp | 2 +- 3 files changed, 96 insertions(+), 35 deletions(-) diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineRegion.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineRegion.java index f13128da63..b188d60a9e 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineRegion.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineRegion.java @@ -401,7 +401,55 @@ public class OfflineRegion { if (!isDeleted) { isDeleted = true; fileSource.activate(); - deleteOfflineRegion(new OfflineRegionDeleteCallback() { + deleteOfflineRegion(true /*pack*/, new OfflineRegionDeleteCallback() { + @Override + public void onDelete() { + handler.post(new Runnable() { + @Override + public void run() { + fileSource.deactivate(); + callback.onDelete(); + OfflineRegion.this.finalize(); + } + }); + } + + @Override + public void onError(final String error) { + handler.post(new Runnable() { + @Override + public void run() { + isDeleted = false; + fileSource.deactivate(); + callback.onError(error); + } + }); + } + }); + } + } + + /** + * Same as {@link OfflineRegion#delete} but skipping database file packing for performance reasons. + *

+ * Database file packing can be done later with {@link OfflineManager#packDatabase}. + * This method is a useful optimization e.g. when several regions should be deleted in a row. + *

+ *

+ * When the operation is complete or encounters an error, the given callback will be + * executed on the main thread. + *

+ *

+ * After you call this method, you may not call any additional methods on this object. + *

+ * + * @param callback the callback to be invoked + */ + public void deleteAndSkipPackDatabase(@NonNull final OfflineRegionDeleteCallback callback) { + if (!isDeleted) { + isDeleted = true; + fileSource.activate(); + deleteOfflineRegion(false /*pack*/, new OfflineRegionDeleteCallback() { @Override public void onDelete() { handler.post(new Runnable() { @@ -521,7 +569,7 @@ public class OfflineRegion { private native void getOfflineRegionStatus(OfflineRegionStatusCallback callback); @Keep - private native void deleteOfflineRegion(OfflineRegionDeleteCallback callback); + private native void deleteOfflineRegion(boolean pack, OfflineRegionDeleteCallback callback); @Keep private native void updateOfflineRegionMetadata(byte[] metadata, OfflineRegionUpdateMetadataCallback callback); diff --git a/platform/android/src/offline/offline_region.cpp b/platform/android/src/offline/offline_region.cpp index ac9f491ab6..264b821636 100644 --- a/platform/android/src/offline/offline_region.cpp +++ b/platform/android/src/offline/offline_region.cpp @@ -101,40 +101,51 @@ void OfflineRegion::getOfflineRegionStatus(jni::JNIEnv& env_, const jni::Object< }); } -void OfflineRegion::deleteOfflineRegion(jni::JNIEnv& env_, const jni::Object& callback_) { - auto globalCallback = jni::NewGlobal(env_, callback_); +namespace { +// Reattach, the callback comes from a different thread +void handleException(std::exception_ptr exception, + const jni::Object& callback, + android::UniqueEnv env = android::AttachEnv()) { + if (exception) { + OfflineRegion::OfflineRegionDeleteCallback::onError(*env, callback, exception); + } else { + OfflineRegion::OfflineRegionDeleteCallback::onDelete(*env, callback); + } +} +} // namespace - fileSource->deleteOfflineRegion(std::move(*region), [ - //Ensure the object is not gc'd in the meanwhile - callback = std::make_shared(std::move(globalCallback)) - ](std::exception_ptr error) mutable { - // Reattach, the callback comes from a different thread - android::UniqueEnv env = android::AttachEnv(); +void OfflineRegion::deleteOfflineRegion(jni::JNIEnv& env_, + jni::jboolean pack, + const jni::Object& callback_) { + auto globalCallback = jni::NewGlobal(env_, callback_); - if (error) { - OfflineRegionDeleteCallback::onError(*env, *callback, error); - } else { - OfflineRegionDeleteCallback::onDelete(*env, *callback); - } - }); + fileSource->deleteOfflineRegion( + std::move(*region), + [ + // Ensure the object is not gc'd in the meanwhile + callback = std::make_shared(std::move(globalCallback))]( + std::exception_ptr error) mutable { handleException(error, *callback); }, + pack); } -void OfflineRegion::invalidateOfflineRegion(jni::JNIEnv& env_, const jni::Object& callback_) { +void OfflineRegion::invalidateOfflineRegion(jni::JNIEnv& env_, + const jni::Object& callback_) { auto globalCallback = jni::NewGlobal(env_, callback_); - fileSource->invalidateOfflineRegion(*region, [ - //Ensure the object is not gc'd in the meanwhile - callback = std::make_shared(std::move(globalCallback)) - ](std::exception_ptr error) mutable { - // Reattach, the callback comes from a different thread - android::UniqueEnv env = android::AttachEnv(); - - if (error) { - OfflineRegionInvalidateCallback::onError(*env, *callback, error); - } else { - OfflineRegionInvalidateCallback::onInvalidate(*env, *callback); - } - }); + fileSource->invalidateOfflineRegion(*region, + [ + // Ensure the object is not gc'd in the meanwhile + callback = std::make_shared( + std::move(globalCallback))](std::exception_ptr error) mutable { + // Reattach, the callback comes from a different thread + android::UniqueEnv env = android::AttachEnv(); + + if (error) { + OfflineRegionInvalidateCallback::onError(*env, *callback, error); + } else { + OfflineRegionInvalidateCallback::onInvalidate(*env, *callback); + } + }); } void OfflineRegion::updateOfflineRegionMetadata(jni::JNIEnv& env_, const jni::Array& jMetadata, const jni::Object& callback_) { @@ -206,7 +217,10 @@ void OfflineRegion::registerNative(jni::JNIEnv& env) { #define METHOD(MethodPtr, name) jni::MakeNativePeerMethod(name) - jni::RegisterNativePeer( env, javaClass, "nativePtr", + jni::RegisterNativePeer( + env, + javaClass, + "nativePtr", jni::MakePeer&>, "initialize", "finalize", @@ -215,8 +229,7 @@ void OfflineRegion::registerNative(jni::JNIEnv& env) { METHOD(&OfflineRegion::getOfflineRegionStatus, "getOfflineRegionStatus"), METHOD(&OfflineRegion::deleteOfflineRegion, "deleteOfflineRegion"), METHOD(&OfflineRegion::invalidateOfflineRegion, "invalidateOfflineRegion"), - METHOD(&OfflineRegion::updateOfflineRegionMetadata, "updateOfflineRegionMetadata") - ); + METHOD(&OfflineRegion::updateOfflineRegionMetadata, "updateOfflineRegionMetadata")); } // OfflineRegionObserver // @@ -227,7 +240,7 @@ void OfflineRegion::OfflineRegionStatusCallback::onError(jni::JNIEnv& env, const jni::Object& callback, std::exception_ptr error) { static auto& javaClass = jni::Class::Singleton(env); - static auto method = javaClass.GetMethod(env, "onError"); + static auto method = javaClass.GetMethod(env, "onError"); callback.Call(env, method, jni::Make(env, mbgl::util::toString(error))); } diff --git a/platform/android/src/offline/offline_region.hpp b/platform/android/src/offline/offline_region.hpp index dda253469e..2c92951f69 100644 --- a/platform/android/src/offline/offline_region.hpp +++ b/platform/android/src/offline/offline_region.hpp @@ -69,7 +69,7 @@ public: void getOfflineRegionStatus(jni::JNIEnv&, const jni::Object&); - void deleteOfflineRegion(jni::JNIEnv&, const jni::Object&); + void deleteOfflineRegion(jni::JNIEnv&, jni::jboolean pack, const jni::Object&); void invalidateOfflineRegion(jni::JNIEnv&, const jni::Object&); -- cgit v1.2.1