From ada86fd62f91ce7f48bdb13804c91e602773df57 Mon Sep 17 00:00:00 2001 From: "r.kuznetsov" Date: Tue, 3 Apr 2018 11:58:49 +0300 Subject: [PATCH] Added JNI for cloud restoring --- .../maps/bookmarks/data/BookmarkManager.cpp | 95 ++++++++++++- .../maps/bookmarks/data/BookmarkManager.java | 134 ++++++++++++++++++ map/bookmark_manager.cpp | 15 ++ map/bookmark_manager.hpp | 4 + 4 files changed, 242 insertions(+), 6 deletions(-) diff --git a/android/jni/com/mapswithme/maps/bookmarks/data/BookmarkManager.cpp b/android/jni/com/mapswithme/maps/bookmarks/data/BookmarkManager.cpp index 2deead9894..3aeb4b8915 100644 --- a/android/jni/com/mapswithme/maps/bookmarks/data/BookmarkManager.cpp +++ b/android/jni/com/mapswithme/maps/bookmarks/data/BookmarkManager.cpp @@ -20,6 +20,10 @@ jmethodID g_onBookmarksLoadingFinishedMethod; jmethodID g_onBookmarksFileLoadedMethod; jmethodID g_onFinishKmlConversionMethod; jmethodID g_onPreparedFileForSharingMethod; +jmethodID g_onSynchronizationStartedMethod; +jmethodID g_onSynchronizationFinishedMethod; +jmethodID g_onRestoreRequestedMethod; +jmethodID g_onRestoredFilesPreparedMethod; void PrepareClassRefs(JNIEnv * env) { @@ -45,11 +49,20 @@ void PrepareClassRefs(JNIEnv * env) g_onPreparedFileForSharingMethod = jni::GetMethodID(env, bookmarkManagerInstance, "onPreparedFileForSharing", "(Lcom/mapswithme/maps/bookmarks/data/BookmarkSharingResult;)V"); + g_onSynchronizationStartedMethod = + jni::GetMethodID(env, bookmarkManagerInstance, "onSynchronizationStarted", "(I)V"); + g_onSynchronizationFinishedMethod = + jni::GetMethodID(env, bookmarkManagerInstance, + "onSynchronizationFinished", "(IILjava/lang/String;)V"); + g_onRestoreRequestedMethod = + jni::GetMethodID(env, bookmarkManagerInstance, "onRestoreRequested", "(IJ)V"); + g_onRestoredFilesPreparedMethod = + jni::GetMethodID(env, bookmarkManagerInstance, "onRestoredFilesPrepared", "()V"); } void OnAsyncLoadingStarted(JNIEnv * env) { - ASSERT(g_bookmarkManagerClass != nullptr, ()); + ASSERT(g_bookmarkManagerClass, ()); jobject bookmarkManagerInstance = env->GetStaticObjectField(g_bookmarkManagerClass, g_bookmarkManagerInstanceField); env->CallVoidMethod(bookmarkManagerInstance, g_onBookmarksLoadingStartedMethod); @@ -58,7 +71,7 @@ void OnAsyncLoadingStarted(JNIEnv * env) void OnAsyncLoadingFinished(JNIEnv * env) { - ASSERT(g_bookmarkManagerClass != nullptr, ()); + ASSERT(g_bookmarkManagerClass, ()); jobject bookmarkManagerInstance = env->GetStaticObjectField(g_bookmarkManagerClass, g_bookmarkManagerInstanceField); env->CallVoidMethod(bookmarkManagerInstance, g_onBookmarksLoadingFinishedMethod); @@ -67,7 +80,7 @@ void OnAsyncLoadingFinished(JNIEnv * env) void OnAsyncLoadingFileSuccess(JNIEnv * env, std::string const & fileName, bool isTemporaryFile) { - ASSERT(g_bookmarkManagerClass != nullptr, ()); + ASSERT(g_bookmarkManagerClass, ()); jobject bookmarkManagerInstance = env->GetStaticObjectField(g_bookmarkManagerClass, g_bookmarkManagerInstanceField); jni::TScopedLocalRef jFileName(env, jni::ToJavaString(env, fileName)); @@ -78,7 +91,7 @@ void OnAsyncLoadingFileSuccess(JNIEnv * env, std::string const & fileName, bool void OnAsyncLoadingFileError(JNIEnv * env, std::string const & fileName, bool isTemporaryFile) { - ASSERT(g_bookmarkManagerClass != nullptr, ()); + ASSERT(g_bookmarkManagerClass, ()); jobject bookmarkManagerInstance = env->GetStaticObjectField(g_bookmarkManagerClass, g_bookmarkManagerInstanceField); jni::TScopedLocalRef jFileName(env, jni::ToJavaString(env, fileName)); @@ -89,7 +102,7 @@ void OnAsyncLoadingFileError(JNIEnv * env, std::string const & fileName, bool is void OnFinishKmlConversion(JNIEnv * env, bool success) { - ASSERT(g_bookmarkManagerClass != nullptr, ()); + ASSERT(g_bookmarkManagerClass, ()); jobject bookmarkManagerInstance = env->GetStaticObjectField(g_bookmarkManagerClass, g_bookmarkManagerInstanceField); env->CallVoidMethod(bookmarkManagerInstance, g_onFinishKmlConversionMethod, success); @@ -98,7 +111,7 @@ void OnFinishKmlConversion(JNIEnv * env, bool success) void OnPreparedFileForSharing(JNIEnv * env, BookmarkManager::SharingResult const & result) { - ASSERT(g_bookmarkManagerClass != nullptr, ()); + ASSERT(g_bookmarkManagerClass, ()); jobject bookmarkManagerInstance = env->GetStaticObjectField(g_bookmarkManagerClass, g_bookmarkManagerInstanceField); @@ -120,6 +133,49 @@ void OnPreparedFileForSharing(JNIEnv * env, BookmarkManager::SharingResult const sharingResult.get()); jni::HandleJavaException(env); } + +void OnSynchronizationStarted(JNIEnv * env, Cloud::SynchronizationType type) +{ + ASSERT(g_bookmarkManagerClass, ()); + jobject bookmarkManagerInstance = env->GetStaticObjectField(g_bookmarkManagerClass, + g_bookmarkManagerInstanceField); + env->CallVoidMethod(bookmarkManagerInstance, g_onSynchronizationStartedMethod, + static_cast(type)); + jni::HandleJavaException(env); +} + +void OnSynchronizationFinished(JNIEnv * env, Cloud::SynchronizationType type, + Cloud::SynchronizationResult result, + std::string const & errorStr) +{ + ASSERT(g_bookmarkManagerClass, ()); + jobject bookmarkManagerInstance = env->GetStaticObjectField(g_bookmarkManagerClass, + g_bookmarkManagerInstanceField); + env->CallVoidMethod(bookmarkManagerInstance, g_onSynchronizationFinishedMethod, + static_cast(type), static_cast(result), + jni::ToJavaString(env, errorStr)); + jni::HandleJavaException(env); +} + +void OnRestoreRequested(JNIEnv * env, Cloud::RestoringRequestResult result, + uint64_t backupTimestampInMs) +{ + ASSERT(g_bookmarkManagerClass, ()); + jobject bookmarkManagerInstance = env->GetStaticObjectField(g_bookmarkManagerClass, + g_bookmarkManagerInstanceField); + env->CallVoidMethod(bookmarkManagerInstance, g_onRestoreRequestedMethod, + static_cast(result), static_cast(backupTimestampInMs)); + jni::HandleJavaException(env); +} + +void OnRestoredFilesPrepared(JNIEnv * env) +{ + ASSERT(g_bookmarkManagerClass, ()); + jobject bookmarkManagerInstance = env->GetStaticObjectField(g_bookmarkManagerClass, + g_bookmarkManagerInstanceField); + env->CallVoidMethod(bookmarkManagerInstance, g_onRestoredFilesPreparedMethod); + jni::HandleJavaException(env); +} } // namespace extern "C" @@ -144,6 +200,12 @@ Java_com_mapswithme_maps_bookmarks_data_BookmarkManager_nativeLoadBookmarks(JNIE callbacks.m_onFileError = std::bind(&OnAsyncLoadingFileError, env, _1, _2); frm()->GetBookmarkManager().SetAsyncLoadingCallbacks(std::move(callbacks)); + frm()->GetBookmarkManager().SetCloudHandlers( + std::bind(&OnSynchronizationStarted, env, _1), + std::bind(&OnSynchronizationFinished, env, _1, _2, _3), + std::bind(&OnRestoreRequested, env, _1, _2), + std::bind(&OnRestoredFilesPrepared, env)); + frm()->LoadBookmarks(); } @@ -446,4 +508,25 @@ Java_com_mapswithme_maps_bookmarks_data_BookmarkManager_nativeIsCategoryEmpty( return static_cast(frm()->GetBookmarkManager().IsCategoryEmpty( static_cast(catId))); } + +JNIEXPORT void JNICALL +Java_com_mapswithme_maps_bookmarks_data_BookmarkManager_nativeRequestRestoring( + JNIEnv * env, jobject thiz) +{ + frm()->GetBookmarkManager().RequestCloudRestoring(); +} + +JNIEXPORT void JNICALL +Java_com_mapswithme_maps_bookmarks_data_BookmarkManager_nativeApplyRestoring( + JNIEnv * env, jobject thiz) +{ + frm()->GetBookmarkManager().ApplyCloudRestoring(); +} + +JNIEXPORT void JNICALL +Java_com_mapswithme_maps_bookmarks_data_BookmarkManager_nativeCancelRestoring( + JNIEnv * env, jobject thiz) +{ + frm()->GetBookmarkManager().CancelCloudRestoring(); +} } // extern "C" diff --git a/android/src/com/mapswithme/maps/bookmarks/data/BookmarkManager.java b/android/src/com/mapswithme/maps/bookmarks/data/BookmarkManager.java index 9333bb399d..5057b2675e 100644 --- a/android/src/com/mapswithme/maps/bookmarks/data/BookmarkManager.java +++ b/android/src/com/mapswithme/maps/bookmarks/data/BookmarkManager.java @@ -1,5 +1,6 @@ package com.mapswithme.maps.bookmarks.data; +import android.support.annotation.IntDef; import android.support.annotation.MainThread; import android.support.annotation.NonNull; @@ -7,6 +8,8 @@ import com.mapswithme.maps.R; import com.mapswithme.util.statistics.Statistics; import java.io.File; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.List; @@ -15,6 +18,32 @@ public enum BookmarkManager { INSTANCE; + @Retention(RetentionPolicy.SOURCE) + @IntDef({ CLOUD_BACKUP, CLOUD_RESTORE }) + public @interface SynchronizationType {} + + public static final int CLOUD_BACKUP = 0; + public static final int CLOUD_RESTORE = 1; + + @Retention(RetentionPolicy.SOURCE) + @IntDef({ CLOUD_SUCCESS, CLOUD_AUTH_ERROR, CLOUD_NETWORK_ERROR, + CLOUD_DISK_ERROR, CLOUD_USER_INTERRUPTED }) + public @interface SynchronizationResult {} + + public static final int CLOUD_SUCCESS = 0; + public static final int CLOUD_AUTH_ERROR = 1; + public static final int CLOUD_NETWORK_ERROR = 2; + public static final int CLOUD_DISK_ERROR = 3; + public static final int CLOUD_USER_INTERRUPTED = 4; + + @Retention(RetentionPolicy.SOURCE) + @IntDef({ CLOUD_BACKUP_EXISTS, CLOUD_NO_BACKUP, CLOUD_NOT_ENOUGH_DISK_SPACE }) + public @interface RestoringRequestResult {} + + public static final int CLOUD_BACKUP_EXISTS = 0; + public static final int CLOUD_NO_BACKUP = 1; + public static final int CLOUD_NOT_ENOUGH_DISK_SPACE = 2; + public static final List ICONS = new ArrayList<>(); @NonNull @@ -26,6 +55,9 @@ public enum BookmarkManager @NonNull private List mSharingListeners = new ArrayList<>(); + @NonNull + private List mCloudListeners = new ArrayList<>(); + static { ICONS.add(new Icon("placemark-red", "placemark-red", R.drawable.ic_bookmark_marker_red_off, R.drawable.ic_bookmark_marker_red_on)); @@ -93,6 +125,16 @@ public enum BookmarkManager mSharingListeners.remove(listener); } + public void addCloudListener(@NonNull BookmarksCloudListener listener) + { + mCloudListeners.add(listener); + } + + public void removeCloudListener(@NonNull BookmarksCloudListener listener) + { + mCloudListeners.remove(listener); + } + // Called from JNI. @MainThread public void onBookmarksLoadingStarted() @@ -142,6 +184,41 @@ public enum BookmarkManager listener.onPreparedFileForSharing(result); } + // Called from JNI. + @MainThread + public void onSynchronizationStarted(@SynchronizationType int type) + { + for (BookmarksCloudListener listener : mCloudListeners) + listener.onSynchronizationStarted(type); + } + + // Called from JNI. + @MainThread + public void onSynchronizationFinished(@SynchronizationType int type, + @SynchronizationResult int result, + @NonNull String errorString) + { + for (BookmarksCloudListener listener : mCloudListeners) + listener.onSynchronizationFinished(type, result, errorString); + } + + // Called from JNI. + @MainThread + public void onRestoreRequested(@RestoringRequestResult int result, + long backupTimestampInMs) + { + for (BookmarksCloudListener listener : mCloudListeners) + listener.onRestoreRequested(result, backupTimestampInMs); + } + + // Called from JNI. + @MainThread + public void onRestoredFilesPrepared() + { + for (BookmarksCloudListener listener : mCloudListeners) + listener.onRestoredFilesPrepared(); + } + public boolean isVisible(long catId) { return nativeIsVisible(catId); @@ -317,6 +394,21 @@ public enum BookmarkManager nativePrepareFileForSharing(catId); } + public void requestRestoring() + { + nativeRequestRestoring(); + } + + public void applyRestoring() + { + nativeApplyRestoring(); + } + + public void cancelRestoring() + { + nativeCancelRestoring(); + } + private native int nativeGetCategoriesCount(); private native int nativeGetCategoryPositionById(long catId); @@ -398,6 +490,12 @@ public enum BookmarkManager private static native boolean nativeIsCategoryEmpty(long catId); + private static native void nativeRequestRestoring(); + + private static native void nativeApplyRestoring(); + + private static native void nativeCancelRestoring(); + public interface BookmarksLoadingListener { void onBookmarksLoadingStarted(); @@ -414,4 +512,40 @@ public enum BookmarkManager { void onPreparedFileForSharing(@NonNull BookmarkSharingResult result); } + + public interface BookmarksCloudListener + { + /** + * The method is called when the synchronization started. + * + * @param type determines type of synchronization (backup or restoring). + */ + void onSynchronizationStarted(@SynchronizationType int type); + + /** + * The method is called when the synchronization finished. + * + * @param type determines type of synchronization (backup or restoring). + * @param result is one of possible results of the synchronization. + * @param errorString contains detailed description in case of unsuccessful completion. + */ + void onSynchronizationFinished(@SynchronizationType int type, + @SynchronizationResult int result, + @NonNull String errorString); + + /** + * The method is called after restoring request. + * + * @param result By result you can determine if the restoring is possible. + * @param backupTimestampInMs contains timestamp of the backup on the server (in milliseconds). + */ + void onRestoreRequested(@RestoringRequestResult int result, long backupTimestampInMs); + + /** + * Restored bookmark files are prepared to substitute for the current ones. + * After this callback any cached bookmarks data become invalid. Also after this + * callback the restoring process can not be cancelled. + */ + void onRestoredFilesPrepared(); + } } diff --git a/map/bookmark_manager.cpp b/map/bookmark_manager.cpp index 87fdbe4e3b..cf05e17cbf 100644 --- a/map/bookmark_manager.cpp +++ b/map/bookmark_manager.cpp @@ -1749,6 +1749,21 @@ void BookmarkManager::OnRestoredFilesPrepared() LOG(LINFO, ("Cloud Restore Files: Prepared")); } +void BookmarkManager::RequestCloudRestoring() +{ + m_bookmarkCloud.RequestRestoring(); +} + +void BookmarkManager::ApplyCloudRestoring() +{ + m_bookmarkCloud.ApplyRestoring(); +} + +void BookmarkManager::CancelCloudRestoring() +{ + m_bookmarkCloud.CancelRestoring(); +} + df::GroupIDSet BookmarkManager::MarksChangesTracker::GetAllGroupIds() const { auto const & groupIds = m_bmManager.GetBmGroupsIdList(); diff --git a/map/bookmark_manager.hpp b/map/bookmark_manager.hpp index 2bb00245bc..ccb07d7cce 100644 --- a/map/bookmark_manager.hpp +++ b/map/bookmark_manager.hpp @@ -249,6 +249,10 @@ public: Cloud::RestoreRequestedHandler && onRestoreRequested, Cloud::RestoredFilesPreparedHandler && onRestoredFilesPrepared); + void RequestCloudRestoring(); + void ApplyCloudRestoring(); + void CancelCloudRestoring(); + /// These functions are public for unit tests only. You shouldn't call them from client code. void SaveToKML(df::MarkGroupID groupId, std::ostream & s); void CreateCategories(KMLDataCollection && dataCollection, bool autoSave = true);