summaryrefslogtreecommitdiff
path: root/Source/Android
diff options
context:
space:
mode:
authorJosJuice <josjuice@gmail.com>2020-06-25 19:38:02 +0200
committerJosJuice <josjuice@gmail.com>2020-09-16 18:38:52 +0200
commitd9f3e382fe1b2f1c7d9de54cefa920b4f0502af6 (patch)
tree7903bb4afe8dc13c5e11da10e5565f2c199f443d /Source/Android
parent7d6debb90793dbd34df49d779ea2c34e432094d8 (diff)
Android: Add a progress dialog for disc image conversion
Diffstat (limited to 'Source/Android')
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/NativeLibrary.java4
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/ConvertFragment.java102
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/CompressCallback.java6
-rw-r--r--Source/Android/app/src/main/res/values/strings.xml1
-rw-r--r--Source/Android/jni/AndroidCommon/IDCache.cpp19
-rw-r--r--Source/Android/jni/AndroidCommon/IDCache.h3
-rw-r--r--Source/Android/jni/MainAndroid.cpp12
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;