summaryrefslogtreecommitdiff
path: root/Source/Android/app/src/main/java
diff options
context:
space:
mode:
authorLéo Lam <leo@leolam.fr>2021-01-27 23:00:47 +0100
committerGitHub <noreply@github.com>2021-01-27 23:00:47 +0100
commit96e3360f054c40c76a1e94162162e4ab22b60051 (patch)
tree06689227b07e674909145636dba195189c00f6ed /Source/Android/app/src/main/java
parent7290cd003210164dcbf77b96af36ffeda2a67af9 (diff)
parent12aa1071cbb30269cd6526cfbbcd3c4143d584ac (diff)
Merge pull request #9452 from JosJuice/android-wii-saves
Android: Add "Import Wii Save"
Diffstat (limited to 'Source/Android/app/src/main/java')
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/NativeLibrary.java2
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/MainActivity.java18
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/MainPresenter.java123
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/MainView.java4
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/TvMainActivity.java22
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/BooleanSupplier.java6
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/CompletableFuture.java95
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/FileBrowserHelper.java3
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/WiiUtils.java14
9 files changed, 236 insertions, 51 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 425551ff77..9a779e7f6b 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
@@ -444,8 +444,6 @@ public final class NativeLibrary
public static native void ReloadLoggerConfig();
- 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,
CompressCallback callback);
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/MainActivity.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/MainActivity.java
index 7b4f886d87..2beb2112f2 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/MainActivity.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/MainActivity.java
@@ -175,21 +175,12 @@ public final class MainActivity extends AppCompatActivity implements MainView
}
@Override
- public void launchOpenFileActivity()
+ public void launchOpenFileActivity(int requestCode)
{
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("*/*");
- startActivityForResult(intent, MainPresenter.REQUEST_GAME_FILE);
- }
-
- @Override
- public void launchInstallWAD()
- {
- Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
- intent.addCategory(Intent.CATEGORY_OPENABLE);
- intent.setType("*/*");
- startActivityForResult(intent, MainPresenter.REQUEST_WAD_FILE);
+ startActivityForResult(intent, requestCode);
}
/**
@@ -229,6 +220,11 @@ public final class MainActivity extends AppCompatActivity implements MainView
FileBrowserHelper.runAfterExtensionCheck(this, uri, FileBrowserHelper.WAD_EXTENSION,
() -> mPresenter.installWAD(result.getData().toString()));
break;
+
+ case MainPresenter.REQUEST_WII_SAVE_FILE:
+ FileBrowserHelper.runAfterExtensionCheck(this, uri, FileBrowserHelper.BIN_EXTENSION,
+ () -> mPresenter.importWiiSave(result.getData().toString()));
+ break;
}
}
else
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/MainPresenter.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/MainPresenter.java
index 1ded576794..ebd43513ab 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/MainPresenter.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/MainPresenter.java
@@ -7,24 +7,26 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.Uri;
-import android.widget.Toast;
import androidx.appcompat.app.AlertDialog;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import org.dolphinemu.dolphinemu.BuildConfig;
-import org.dolphinemu.dolphinemu.NativeLibrary;
import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.features.settings.model.BooleanSetting;
import org.dolphinemu.dolphinemu.features.settings.ui.MenuTag;
import org.dolphinemu.dolphinemu.model.GameFileCache;
import org.dolphinemu.dolphinemu.services.GameFileCacheService;
import org.dolphinemu.dolphinemu.utils.AfterDirectoryInitializationRunner;
+import org.dolphinemu.dolphinemu.utils.BooleanSupplier;
+import org.dolphinemu.dolphinemu.utils.CompletableFuture;
import org.dolphinemu.dolphinemu.utils.ContentHandler;
import org.dolphinemu.dolphinemu.utils.FileBrowserHelper;
+import org.dolphinemu.dolphinemu.utils.WiiUtils;
import java.util.Arrays;
-import java.util.Set;
+import java.util.concurrent.ExecutionException;
+import java.util.function.Supplier;
public final class MainPresenter
{
@@ -32,6 +34,7 @@ public final class MainPresenter
public static final int REQUEST_GAME_FILE = 2;
public static final int REQUEST_SD_FILE = 3;
public static final int REQUEST_WAD_FILE = 4;
+ public static final int REQUEST_WII_SAVE_FILE = 5;
private final MainView mView;
private final Context mContext;
@@ -92,11 +95,17 @@ public final class MainPresenter
return true;
case R.id.menu_open_file:
- mView.launchOpenFileActivity();
+ mView.launchOpenFileActivity(REQUEST_GAME_FILE);
return true;
case R.id.menu_install_wad:
- new AfterDirectoryInitializationRunner().run(context, true, mView::launchInstallWAD);
+ new AfterDirectoryInitializationRunner().run(context, true,
+ () -> mView.launchOpenFileActivity(REQUEST_WAD_FILE));
+ return true;
+
+ case R.id.menu_import_wii_save:
+ new AfterDirectoryInitializationRunner().run(context, true,
+ () -> mView.launchOpenFileActivity(REQUEST_WII_SAVE_FILE));
return true;
}
@@ -150,32 +159,98 @@ public final class MainPresenter
mDirToAdd = uri.toString();
}
- public void installWAD(String file)
+ public void installWAD(String path)
+ {
+ runOnThreadAndShowResult(R.string.import_in_progress, () ->
+ {
+ boolean success = WiiUtils.installWAD(path);
+ int message = success ? R.string.wad_install_success : R.string.wad_install_failure;
+ return mContext.getResources().getString(message);
+ });
+ }
+
+ public void importWiiSave(String path)
{
final Activity mainPresenterActivity = (Activity) mContext;
- AlertDialog dialog = new AlertDialog.Builder(mContext, R.style.DolphinDialogBase).create();
- dialog.setTitle("Installing WAD");
- dialog.setMessage("Installing...");
- dialog.setCancelable(false);
- dialog.show();
+ CompletableFuture<Boolean> canOverwriteFuture = new CompletableFuture<>();
- Thread installWADThread = new Thread(() ->
+ runOnThreadAndShowResult(R.string.import_in_progress, () ->
{
- if (NativeLibrary.InstallWAD(file))
+ BooleanSupplier canOverwrite = () ->
{
- mainPresenterActivity.runOnUiThread(
- () -> Toast.makeText(mContext, R.string.wad_install_success, Toast.LENGTH_SHORT)
- .show());
- }
- else
+ mainPresenterActivity.runOnUiThread(() ->
+ {
+ AlertDialog.Builder builder =
+ new AlertDialog.Builder(mContext, R.style.DolphinDialogBase);
+ builder.setMessage(R.string.wii_save_exists);
+ builder.setCancelable(false);
+ builder.setPositiveButton(R.string.yes, (dialog, i) -> canOverwriteFuture.complete(true));
+ builder.setNegativeButton(R.string.no, (dialog, i) -> canOverwriteFuture.complete(false));
+ builder.show();
+ });
+
+ try
+ {
+ return canOverwriteFuture.get();
+ }
+ catch (ExecutionException | InterruptedException e)
+ {
+ // Shouldn't happen
+ throw new RuntimeException(e);
+ }
+ };
+
+ int result = WiiUtils.importWiiSave(path, canOverwrite);
+
+ int message;
+ switch (result)
{
- mainPresenterActivity.runOnUiThread(
- () -> Toast.makeText(mContext, R.string.wad_install_failure, Toast.LENGTH_SHORT)
- .show());
+ case WiiUtils.RESULT_SUCCESS:
+ message = R.string.wii_save_import_success;
+ break;
+ case WiiUtils.RESULT_CORRUPTED_SOURCE:
+ message = R.string.wii_save_import_corruped_source;
+ break;
+ case WiiUtils.RESULT_TITLE_MISSING:
+ message = R.string.wii_save_import_title_missing;
+ break;
+ case WiiUtils.RESULT_CANCELLED:
+ return null;
+ default:
+ message = R.string.wii_save_import_error;
+ break;
}
- mainPresenterActivity.runOnUiThread(dialog::dismiss);
- }, "InstallWAD");
- installWADThread.start();
+ return mContext.getResources().getString(message);
+ });
+ }
+
+ private void runOnThreadAndShowResult(int progressMessage, Supplier<String> f)
+ {
+ final Activity mainPresenterActivity = (Activity) mContext;
+
+ AlertDialog progressDialog = new AlertDialog.Builder(mContext, R.style.DolphinDialogBase)
+ .create();
+ progressDialog.setTitle(progressMessage);
+ progressDialog.setCancelable(false);
+ progressDialog.show();
+
+ new Thread(() ->
+ {
+ String result = f.get();
+ mainPresenterActivity.runOnUiThread(() ->
+ {
+ progressDialog.dismiss();
+
+ if (result != null)
+ {
+ AlertDialog.Builder builder =
+ new AlertDialog.Builder(mContext, R.style.DolphinDialogBase);
+ builder.setMessage(result);
+ builder.setPositiveButton(R.string.ok, (dialog, i) -> dialog.dismiss());
+ builder.show();
+ }
+ });
+ }, mContext.getResources().getString(progressMessage)).start();
}
}
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/MainView.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/MainView.java
index fc4ed31513..b2e6b74495 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/MainView.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/MainView.java
@@ -21,9 +21,7 @@ public interface MainView
void launchFileListActivity();
- void launchOpenFileActivity();
-
- void launchInstallWAD();
+ void launchOpenFileActivity(int requestCode);
/**
* To be called when the game file cache is updated.
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/TvMainActivity.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/TvMainActivity.java
index 8e96083ce1..d34c3d8518 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/TvMainActivity.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/TvMainActivity.java
@@ -180,21 +180,12 @@ public final class TvMainActivity extends FragmentActivity implements MainView
}
@Override
- public void launchOpenFileActivity()
+ public void launchOpenFileActivity(int requestCode)
{
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("*/*");
- startActivityForResult(intent, MainPresenter.REQUEST_GAME_FILE);
- }
-
- @Override
- public void launchInstallWAD()
- {
- Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
- intent.addCategory(Intent.CATEGORY_OPENABLE);
- intent.setType("*/*");
- startActivityForResult(intent, MainPresenter.REQUEST_WAD_FILE);
+ startActivityForResult(intent, requestCode);
}
@Override
@@ -253,6 +244,11 @@ public final class TvMainActivity extends FragmentActivity implements MainView
FileBrowserHelper.runAfterExtensionCheck(this, uri, FileBrowserHelper.WAD_EXTENSION,
() -> mPresenter.installWAD(result.getData().toString()));
break;
+
+ case MainPresenter.REQUEST_WII_SAVE_FILE:
+ FileBrowserHelper.runAfterExtensionCheck(this, uri, FileBrowserHelper.BIN_EXTENSION,
+ () -> mPresenter.importWiiSave(result.getData().toString()));
+ break;
}
}
else
@@ -353,6 +349,10 @@ public final class TvMainActivity extends FragmentActivity implements MainView
R.drawable.ic_folder,
R.string.grid_menu_install_wad));
+ rowItems.add(new TvSettingsItem(R.id.menu_import_wii_save,
+ R.drawable.ic_folder,
+ R.string.grid_menu_import_wii_save));
+
// Create a header for this row.
HeaderItem header =
new HeaderItem(R.string.preferences_settings, getString(R.string.preferences_settings));
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/BooleanSupplier.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/BooleanSupplier.java
new file mode 100644
index 0000000000..d1c490fe2a
--- /dev/null
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/BooleanSupplier.java
@@ -0,0 +1,6 @@
+package org.dolphinemu.dolphinemu.utils;
+
+public interface BooleanSupplier
+{
+ boolean get();
+}
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/CompletableFuture.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/CompletableFuture.java
new file mode 100644
index 0000000000..bdd1b02faf
--- /dev/null
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/CompletableFuture.java
@@ -0,0 +1,95 @@
+package org.dolphinemu.dolphinemu.utils;
+
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+/**
+ * Simplified re-implementation of a subset of {@link java.util.concurrent.CompletableFuture}.
+ * Replace this class with that class once we have full Java 8 support (once we require API 24).
+ */
+public class CompletableFuture<T> implements Future<T>
+{
+ private final Lock lock = new ReentrantLock();
+ private final Condition done = lock.newCondition();
+
+ private boolean isDone = false;
+ private T result = null;
+
+ @Override
+ public boolean cancel(boolean mayInterruptIfRunning)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean isCancelled()
+ {
+ return false;
+ }
+
+ @Override
+ public boolean isDone()
+ {
+ return isDone;
+ }
+
+ @Override
+ public T get() throws ExecutionException, InterruptedException
+ {
+ lock.lock();
+ try
+ {
+ while (!isDone)
+ done.await();
+
+ return result;
+ }
+ finally
+ {
+ lock.unlock();
+ }
+ }
+
+ @Override
+ public T get(long timeout, TimeUnit unit)
+ throws ExecutionException, InterruptedException, TimeoutException
+ {
+ lock.lock();
+ try
+ {
+ while (!isDone)
+ {
+ if (!done.await(timeout, unit))
+ throw new TimeoutException();
+ }
+
+ return result;
+ }
+ finally
+ {
+ lock.unlock();
+ }
+ }
+
+ public boolean complete(T value)
+ {
+ lock.lock();
+ try
+ {
+ boolean wasDone = isDone;
+ result = value;
+ isDone = true;
+ done.signalAll();
+ return !wasDone;
+ }
+ finally
+ {
+ lock.unlock();
+ }
+ }
+}
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/FileBrowserHelper.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/FileBrowserHelper.java
index f68bc46857..94b10806df 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/FileBrowserHelper.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/FileBrowserHelper.java
@@ -37,6 +37,9 @@ public final class FileBrowserHelper
GAME_LIKE_EXTENSIONS.add("dff");
}
+ public static final HashSet<String> BIN_EXTENSION = new HashSet<>(Collections.singletonList(
+ "bin"));
+
public static final HashSet<String> RAW_EXTENSION = new HashSet<>(Collections.singletonList(
"raw"));
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/WiiUtils.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/WiiUtils.java
new file mode 100644
index 0000000000..9a6440c9e5
--- /dev/null
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/WiiUtils.java
@@ -0,0 +1,14 @@
+package org.dolphinemu.dolphinemu.utils;
+
+public final class WiiUtils
+{
+ public static final int RESULT_SUCCESS = 0;
+ public static final int RESULT_ERROR = 1;
+ public static final int RESULT_CANCELLED = 2;
+ public static final int RESULT_CORRUPTED_SOURCE = 3;
+ public static final int RESULT_TITLE_MISSING = 4;
+
+ public static native boolean installWAD(String file);
+
+ public static native int importWiiSave(String file, BooleanSupplier canOverwrite);
+}