diff options
| author | JosJuice <josjuice@gmail.com> | 2020-06-25 19:38:02 +0200 |
|---|---|---|
| committer | JosJuice <josjuice@gmail.com> | 2020-09-16 18:38:52 +0200 |
| commit | d9f3e382fe1b2f1c7d9de54cefa920b4f0502af6 (patch) | |
| tree | 7903bb4afe8dc13c5e11da10e5565f2c199f443d /Source/Android | |
| parent | 7d6debb90793dbd34df49d779ea2c34e432094d8 (diff) | |
Android: Add a progress dialog for disc image conversion
Diffstat (limited to 'Source/Android')
7 files changed, 127 insertions, 20 deletions
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/NativeLibrary.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/NativeLibrary.java index 238fb2a769..5655518a71 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/NativeLibrary.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/NativeLibrary.java @@ -12,6 +12,7 @@ import android.view.Surface; import androidx.appcompat.app.AlertDialog; import org.dolphinemu.dolphinemu.activities.EmulationActivity; +import org.dolphinemu.dolphinemu.utils.CompressCallback; import org.dolphinemu.dolphinemu.utils.Log; import org.dolphinemu.dolphinemu.utils.Rumble; @@ -430,7 +431,8 @@ public final class NativeLibrary public static native boolean InstallWAD(String file); public static native boolean ConvertDiscImage(String inPath, String outPath, int platform, - int format, int blockSize, int compression, int compressionLevel, boolean scrub); + int format, int blockSize, int compression, int compressionLevel, boolean scrub, + CompressCallback callback); public static native String FormatSize(long bytes, int decimals); diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/ConvertFragment.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/ConvertFragment.java index a37a9d3874..389ef98f3e 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/ConvertFragment.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/ConvertFragment.java @@ -1,5 +1,6 @@ package org.dolphinemu.dolphinemu.fragments; +import android.app.ProgressDialog; import android.content.Context; import android.os.Bundle; import android.view.LayoutInflater; @@ -108,6 +109,9 @@ public class ConvertFragment extends Fragment implements View.OnClickListener private GameFile gameFile; + private volatile boolean mCanceled; + private volatile Thread mThread = null; + public static ConvertFragment newInstance(String gamePath) { Bundle args = new Bundle(); @@ -181,6 +185,15 @@ public class ConvertFragment extends Fragment implements View.OnClickListener valueWrapper.setPosition(i); } + @Override + public void onStop() + { + super.onStop(); + + mCanceled = true; + joinThread(); + } + private Spinner populateSpinner(int spinnerId, int entriesId, int valuesId, SpinnerValue valueWrapper) { @@ -339,33 +352,88 @@ public class ConvertFragment extends Fragment implements View.OnClickListener private void convert() { + final int PROGRESS_RESOLUTION = 1000; + Context context = requireContext(); // TODO: Let the user select a path String outPath = gameFile.getPath() + ".converted"; - boolean success = NativeLibrary.ConvertDiscImage(gameFile.getPath(), outPath, - gameFile.getPlatform(), mFormat.getValue(context), mBlockSize.getValueOr(context,0), - mCompression.getValueOr(context,0), mCompressionLevel.getValueOr(context,0), - getRemoveJunkData()); + joinThread(); + + mCanceled = false; + + ProgressDialog progressDialog = new ProgressDialog(context, R.style.DolphinDialogBase); + + progressDialog.setTitle(R.string.convert_converting); + + progressDialog.setIndeterminate(false); + progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); + progressDialog.setMax(PROGRESS_RESOLUTION); - AlertDialog.Builder builder = new AlertDialog.Builder(context, R.style.DolphinDialogBase); - if (success) + progressDialog.setCancelable(true); + progressDialog.setOnCancelListener((dialog) -> mCanceled = true); + + progressDialog.show(); + + mThread = new Thread(() -> { - builder.setMessage(R.string.convert_success_message) - .setCancelable(false) - .setPositiveButton(R.string.ok, (dialog, i) -> + boolean success = NativeLibrary.ConvertDiscImage(gameFile.getPath(), outPath, + gameFile.getPlatform(), mFormat.getValue(context), mBlockSize.getValueOr(context, 0), + mCompression.getValueOr(context, 0), mCompressionLevel.getValueOr(context, 0), + getRemoveJunkData(), (text, completion) -> { - dialog.dismiss(); - requireActivity().finish(); + requireActivity().runOnUiThread(() -> + { + progressDialog.setMessage(text); + progressDialog.setProgress((int) (completion * PROGRESS_RESOLUTION)); + }); + + return !mCanceled; }); - } - else + + if (!mCanceled) + { + requireActivity().runOnUiThread(() -> + { + progressDialog.dismiss(); + + AlertDialog.Builder builder = new AlertDialog.Builder(context, R.style.DolphinDialogBase); + if (success) + { + builder.setMessage(R.string.convert_success_message) + .setCancelable(false) + .setPositiveButton(R.string.ok, (dialog, i) -> + { + dialog.dismiss(); + requireActivity().finish(); + }); + } + else + { + builder.setMessage(R.string.convert_failure_message) + .setPositiveButton(R.string.ok, (dialog, i) -> dialog.dismiss()); + } + AlertDialog alert = builder.create(); + alert.show(); + }); + } + }); + + mThread.start(); + } + + private void joinThread() + { + if (mThread != null) { - builder.setMessage(R.string.convert_failure_message) - .setPositiveButton(R.string.ok, (dialog, i) -> dialog.dismiss()); + try + { + mThread.join(); + } + catch (InterruptedException ignored) + { + } } - AlertDialog alert = builder.create(); - alert.show(); } } diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/CompressCallback.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/CompressCallback.java new file mode 100644 index 0000000000..83aa8d7919 --- /dev/null +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/CompressCallback.java @@ -0,0 +1,6 @@ +package org.dolphinemu.dolphinemu.utils; + +public interface CompressCallback +{ + boolean run(String text, float completion); +} diff --git a/Source/Android/app/src/main/res/values/strings.xml b/Source/Android/app/src/main/res/values/strings.xml index 977bd56bd4..95efff4161 100644 --- a/Source/Android/app/src/main/res/values/strings.xml +++ b/Source/Android/app/src/main/res/values/strings.xml @@ -337,6 +337,7 @@ <string name="convert_compression_level">Compression Level</string> <string name="convert_remove_junk_data">Remove Junk Data (Irreversible)</string> <string name="convert_convert">Convert</string> + <string name="convert_converting">Converting</string> <string name="convert_warning_iso">Removing junk data does not save any space when converting to ISO (unless you package the ISO file in a compressed file format such as ZIP afterwards). Do you want to continue anyway?</string> <string name="convert_warning_gcz">Converting Wii disc images to GCZ without removing junk data does not save any noticeable amount of space compared to converting to ISO. Do you want to continue anyway?</string> <string name="convert_success_message">The disc image was successfully converted.</string> diff --git a/Source/Android/jni/AndroidCommon/IDCache.cpp b/Source/Android/jni/AndroidCommon/IDCache.cpp index 8383f8ed68..0e2e9026c6 100644 --- a/Source/Android/jni/AndroidCommon/IDCache.cpp +++ b/Source/Android/jni/AndroidCommon/IDCache.cpp @@ -36,6 +36,9 @@ static jclass s_ini_file_section_class; static jfieldID s_ini_file_section_pointer; static jmethodID s_ini_file_section_constructor; +static jclass s_compress_cb_class; +static jmethodID s_compress_cb_run; + namespace IDCache { JNIEnv* GetEnvForThread() @@ -161,6 +164,16 @@ jmethodID GetIniFileSectionConstructor() return s_ini_file_section_constructor; } +jclass GetCompressCallbackClass() +{ + return s_compress_cb_class; +} + +jmethodID GetCompressCallbackRun() +{ + return s_compress_cb_run; +} + } // namespace IDCache #ifdef __cplusplus @@ -223,6 +236,11 @@ jint JNI_OnLoad(JavaVM* vm, void* reserved) s_linked_hash_map_put = env->GetMethodID( s_linked_hash_map_class, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); + const jclass compress_cb_class = + env->FindClass("org/dolphinemu/dolphinemu/utils/CompressCallback"); + s_compress_cb_class = reinterpret_cast<jclass>(env->NewGlobalRef(compress_cb_class)); + s_compress_cb_run = env->GetMethodID(s_compress_cb_class, "run", "(Ljava/lang/String;F)Z"); + return JNI_VERSION; } @@ -239,6 +257,7 @@ void JNI_OnUnload(JavaVM* vm, void* reserved) env->DeleteGlobalRef(s_linked_hash_map_class); env->DeleteGlobalRef(s_ini_file_class); env->DeleteGlobalRef(s_ini_file_section_class); + env->DeleteGlobalRef(s_compress_cb_class); } #ifdef __cplusplus diff --git a/Source/Android/jni/AndroidCommon/IDCache.h b/Source/Android/jni/AndroidCommon/IDCache.h index 77f49658b8..b3dbd71554 100644 --- a/Source/Android/jni/AndroidCommon/IDCache.h +++ b/Source/Android/jni/AndroidCommon/IDCache.h @@ -38,4 +38,7 @@ jclass GetIniFileSectionClass(); jfieldID GetIniFileSectionPointer(); jmethodID GetIniFileSectionConstructor(); +jclass GetCompressCallbackClass(); +jmethodID GetCompressCallbackRun(); + } // namespace IDCache diff --git a/Source/Android/jni/MainAndroid.cpp b/Source/Android/jni/MainAndroid.cpp index bef78a49b5..4bb72ff2f6 100644 --- a/Source/Android/jni/MainAndroid.cpp +++ b/Source/Android/jni/MainAndroid.cpp @@ -27,6 +27,7 @@ #include "Common/IniFile.h" #include "Common/Logging/LogManager.h" #include "Common/MsgHandler.h" +#include "Common/ScopeGuard.h" #include "Common/Version.h" #include "Common/WindowSystemInfo.h" @@ -668,7 +669,7 @@ JNIEXPORT jboolean JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_InstallW JNIEXPORT jboolean JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_ConvertDiscImage( JNIEnv* env, jobject obj, jstring jInPath, jstring jOutPath, jint jPlatform, jint jFormat, - jint jBlockSize, jint jCompression, jint jCompressionLevel, jboolean jScrub) + jint jBlockSize, jint jCompression, jint jCompressionLevel, jboolean jScrub, jobject jCallback) { const std::string in_path = GetJString(env, jInPath); const std::string out_path = GetJString(env, jOutPath); @@ -687,7 +688,14 @@ JNIEXPORT jboolean JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_ConvertD if (!blob_reader) return static_cast<jboolean>(false); - const auto callback = [](const std::string& text, float percent) { return true; }; + jobject jCallbackGlobal = env->NewGlobalRef(jCallback); + Common::ScopeGuard scope_guard([jCallbackGlobal, env] { env->DeleteGlobalRef(jCallbackGlobal); }); + + const auto callback = [&jCallbackGlobal](const std::string& text, float completion) { + JNIEnv* env = IDCache::GetEnvForThread(); + return static_cast<bool>(env->CallBooleanMethod( + jCallbackGlobal, IDCache::GetCompressCallbackRun(), ToJString(env, text), completion)); + }; bool success = false; |
