summaryrefslogtreecommitdiff
path: root/Source/Android/app/src/main/java/org
diff options
context:
space:
mode:
authorJMC47 <JMC4789@gmail.com>2025-12-22 13:34:58 -0500
committerGitHub <noreply@github.com>2025-12-22 13:34:58 -0500
commit8aabaf8b63b67e4af2b4001e77135e6ff83c23ea (patch)
treed0a34d728a391cba811577a56b858b986f7f36c3 /Source/Android/app/src/main/java/org
parent8a64bc499f831aa67026078fb594c46f019108f0 (diff)
parente78ece126e4d586f1816a8fd4dcf46a36ba71d03 (diff)
Merge pull request #14155 from Simonx22/android/remove-completable-future
Android: Remove CompletableFuture
Diffstat (limited to 'Source/Android/app/src/main/java/org')
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/MainPresenter.kt212
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/CompletableFuture.java97
2 files changed, 99 insertions, 210 deletions
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/MainPresenter.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/MainPresenter.kt
index cea17578d4..893d6a16d4 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/MainPresenter.kt
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/MainPresenter.kt
@@ -26,7 +26,6 @@ import org.dolphinemu.dolphinemu.model.GameFileCache
import org.dolphinemu.dolphinemu.services.GameFileCacheManager
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.DirectoryInitialization
import org.dolphinemu.dolphinemu.utils.FileBrowserHelper
@@ -34,7 +33,8 @@ import org.dolphinemu.dolphinemu.utils.PermissionsHandler
import org.dolphinemu.dolphinemu.utils.ThreadUtil
import org.dolphinemu.dolphinemu.utils.WiiUtils
import java.util.Arrays
-import java.util.concurrent.ExecutionException
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.atomic.AtomicReference
class MainPresenter(private val mainView: MainView, private val activity: FragmentActivity) {
private var dirToAdd: String? = null
@@ -104,8 +104,9 @@ class MainPresenter(private val mainView: MainView, private val activity: Fragme
fun onCreate() {
// Ask the user to grant write permission if relevant and not already granted
- if (DirectoryInitialization.isWaitingForWriteAccess(activity))
+ if (DirectoryInitialization.isWaitingForWriteAccess(activity)) {
PermissionsHandler.requestWritePermission(activity)
+ }
val versionName = BuildConfig.VERSION_NAME
mainView.setVersionString(versionName)
@@ -118,85 +119,83 @@ class MainPresenter(private val mainView: MainView, private val activity: Fragme
}
fun launchFileListActivity() {
- val intent =
- if (DirectoryInitialization.preferOldFolderPicker(activity)) {
- FileBrowserHelper.createDirectoryPickerIntent(
- activity,
- FileBrowserHelper.GAME_EXTENSIONS,
- )
- } else {
- Intent(Intent.ACTION_OPEN_DOCUMENT_TREE)
- }
+ val intent = if (DirectoryInitialization.preferOldFolderPicker(activity)) {
+ FileBrowserHelper.createDirectoryPickerIntent(
+ activity,
+ FileBrowserHelper.GAME_EXTENSIONS,
+ )
+ } else {
+ Intent(Intent.ACTION_OPEN_DOCUMENT_TREE)
+ }
requestDirectory.launch(intent)
}
- fun handleOptionSelection(itemId: Int, activity: ComponentActivity): Boolean =
- when (itemId) {
- R.id.menu_settings -> {
- mainView.launchSettingsActivity(MenuTag.SETTINGS)
- true
- }
-
- R.id.menu_grid_options -> {
- mainView.showGridOptions()
- true
- }
+ fun handleOptionSelection(itemId: Int, activity: ComponentActivity): Boolean = when (itemId) {
+ R.id.menu_settings -> {
+ mainView.launchSettingsActivity(MenuTag.SETTINGS)
+ true
+ }
- R.id.menu_refresh -> {
- mainView.setRefreshing(true)
- GameFileCacheManager.startRescan()
- true
- }
+ R.id.menu_grid_options -> {
+ mainView.showGridOptions()
+ true
+ }
- R.id.button_add_directory -> {
- AfterDirectoryInitializationRunner().runWithLifecycle(activity) { launchFileListActivity() }
- true
- }
+ R.id.menu_refresh -> {
+ mainView.setRefreshing(true)
+ GameFileCacheManager.startRescan()
+ true
+ }
- R.id.menu_open_file -> {
- requestGameFile.launch("*/*")
- true
- }
+ R.id.button_add_directory -> {
+ AfterDirectoryInitializationRunner().runWithLifecycle(activity) { launchFileListActivity() }
+ true
+ }
- R.id.menu_load_wii_system_menu -> {
- launchWiiSystemMenu()
- true
- }
+ R.id.menu_open_file -> {
+ requestGameFile.launch("*/*")
+ true
+ }
- R.id.menu_online_system_update -> {
- AfterDirectoryInitializationRunner().runWithLifecycle(activity) { launchOnlineUpdate() }
- true
- }
+ R.id.menu_load_wii_system_menu -> {
+ launchWiiSystemMenu()
+ true
+ }
- R.id.menu_install_wad -> {
- AfterDirectoryInitializationRunner().runWithLifecycle(
- activity
- ) { requestWadFile.launch("*/*") }
- true
- }
+ R.id.menu_online_system_update -> {
+ AfterDirectoryInitializationRunner().runWithLifecycle(activity) { launchOnlineUpdate() }
+ true
+ }
- R.id.menu_import_wii_save -> {
- AfterDirectoryInitializationRunner().runWithLifecycle(
- activity
- ) { requestWiiSaveFile.launch("*/*") }
- true
- }
+ R.id.menu_install_wad -> {
+ AfterDirectoryInitializationRunner().runWithLifecycle(
+ activity
+ ) { requestWadFile.launch("*/*") }
+ true
+ }
- R.id.menu_import_nand_backup -> {
- AfterDirectoryInitializationRunner().runWithLifecycle(
- activity
- ) { requestNandBinFile.launch("*/*") }
- true
- }
+ R.id.menu_import_wii_save -> {
+ AfterDirectoryInitializationRunner().runWithLifecycle(
+ activity
+ ) { requestWiiSaveFile.launch("*/*") }
+ true
+ }
- R.id.menu_about -> {
- showAboutDialog()
- false
- }
+ R.id.menu_import_nand_backup -> {
+ AfterDirectoryInitializationRunner().runWithLifecycle(
+ activity
+ ) { requestNandBinFile.launch("*/*") }
+ true
+ }
- else -> false
+ R.id.menu_about -> {
+ showAboutDialog()
+ false
}
+ else -> false
+ }
+
fun onResume() {
if (dirToAdd != null) {
GameFileCache.addGameFolder(dirToAdd!!)
@@ -226,24 +225,25 @@ class MainPresenter(private val mainView: MainView, private val activity: Fragme
val recursive = BooleanSetting.MAIN_RECURSIVE_ISO_PATHS.boolean
val childNames = ContentHandler.getChildNames(uri, recursive)
if (Arrays.stream(childNames).noneMatch {
- FileBrowserHelper.GAME_EXTENSIONS
- .contains(FileBrowserHelper.getExtension(it, false))
- }) {
- MaterialAlertDialogBuilder(activity)
- .setMessage(
- activity.getString(
- R.string.wrong_file_extension_in_directory,
- FileBrowserHelper.setToSortedDelimitedString(FileBrowserHelper.GAME_EXTENSIONS)
+ FileBrowserHelper.GAME_EXTENSIONS.contains(
+ FileBrowserHelper.getExtension(
+ it, false
)
)
- .setPositiveButton(android.R.string.ok, null)
- .show()
+ }) {
+ MaterialAlertDialogBuilder(activity).setMessage(
+ activity.getString(
+ R.string.wrong_file_extension_in_directory,
+ FileBrowserHelper.setToSortedDelimitedString(FileBrowserHelper.GAME_EXTENSIONS)
+ )
+ ).setPositiveButton(android.R.string.ok, null).show()
}
val contentResolver = activity.contentResolver
val canonicalizedUri = contentResolver.canonicalize(uri)
- if (canonicalizedUri != null)
+ if (canonicalizedUri != null) {
uri = canonicalizedUri
+ }
val takeFlags = result.flags and Intent.FLAG_GRANT_READ_URI_PERMISSION
activity.contentResolver.takePersistableUriPermission(uri, takeFlags)
@@ -253,10 +253,7 @@ class MainPresenter(private val mainView: MainView, private val activity: Fragme
fun installWAD(path: String?) {
ThreadUtil.runOnThreadAndShowResult(
- activity,
- R.string.import_in_progress,
- 0,
- {
+ activity, R.string.import_in_progress, 0, {
val success = WiiUtils.installWAD(path!!)
val message =
if (success) R.string.wad_install_success else R.string.wad_install_failure
@@ -265,33 +262,28 @@ class MainPresenter(private val mainView: MainView, private val activity: Fragme
}
fun importWiiSave(path: String?) {
- val canOverwriteFuture = CompletableFuture<Boolean>()
ThreadUtil.runOnThreadAndShowResult(
- activity,
- R.string.import_in_progress,
- 0,
- {
+ activity, R.string.import_in_progress, 0, {
val canOverwrite = BooleanSupplier {
+ val latch = CountDownLatch(1)
+ val decision = AtomicReference<Boolean>()
activity.runOnUiThread {
- MaterialAlertDialogBuilder(activity)
- .setMessage(R.string.wii_save_exists)
+ MaterialAlertDialogBuilder(activity).setMessage(R.string.wii_save_exists)
.setCancelable(false)
.setPositiveButton(R.string.yes) { _: DialogInterface?, _: Int ->
- canOverwriteFuture.complete(true)
- }
- .setNegativeButton(R.string.no) { _: DialogInterface?, _: Int ->
- canOverwriteFuture.complete(false)
- }
- .show()
+ decision.set(true)
+ latch.countDown()
+ }.setNegativeButton(R.string.no) { _: DialogInterface?, _: Int ->
+ decision.set(false)
+ latch.countDown()
+ }.show()
}
try {
- return@BooleanSupplier canOverwriteFuture.get()
- } catch (e: ExecutionException) {
- // Shouldn't happen
- throw RuntimeException(e)
+ latch.await()
} catch (e: InterruptedException) {
throw RuntimeException(e)
}
+ decision.get() ?: false
}
val message: Int = when (WiiUtils.importWiiSave(path!!, canOverwrite)) {
@@ -306,23 +298,18 @@ class MainPresenter(private val mainView: MainView, private val activity: Fragme
}
fun importNANDBin(path: String?) {
- MaterialAlertDialogBuilder(activity)
- .setMessage(R.string.nand_import_warning)
+ MaterialAlertDialogBuilder(activity).setMessage(R.string.nand_import_warning)
.setNegativeButton(R.string.no) { dialog: DialogInterface, _: Int -> dialog.dismiss() }
.setPositiveButton(R.string.yes) { dialog: DialogInterface, _: Int ->
dialog.dismiss()
ThreadUtil.runOnThreadAndShowResult(
- activity,
- R.string.import_in_progress,
- R.string.do_not_close_app,
- {
+ activity, R.string.import_in_progress, R.string.do_not_close_app, {
// ImportNANDBin unfortunately doesn't provide any result value...
// It does however show a panic alert if something goes wrong.
WiiUtils.importNANDBin(path!!)
null
})
- }
- .show()
+ }.show()
}
private fun launchOnlineUpdate() {
@@ -332,8 +319,7 @@ class MainPresenter(private val mainView: MainView, private val activity: Fragme
launchUpdateProgressBarFragment(activity)
} else {
SystemMenuNotInstalledDialogFragment().show(
- activity.supportFragmentManager,
- SystemMenuNotInstalledDialogFragment.TAG
+ activity.supportFragmentManager, SystemMenuNotInstalledDialogFragment.TAG
)
}
}
@@ -344,8 +330,7 @@ class MainPresenter(private val mainView: MainView, private val activity: Fragme
EmulationActivity.launchSystemMenu(activity)
} else {
SystemMenuNotInstalledDialogFragment().show(
- activity.supportFragmentManager,
- SystemMenuNotInstalledDialogFragment.TAG
+ activity.supportFragmentManager, SystemMenuNotInstalledDialogFragment.TAG
)
}
}
@@ -372,8 +357,9 @@ class MainPresenter(private val mainView: MainView, private val activity: Fragme
private fun launchUpdateProgressBarFragment(activity: FragmentActivity) {
val progressBarFragment = SystemUpdateProgressBarDialogFragment()
- progressBarFragment
- .show(activity.supportFragmentManager, SystemUpdateProgressBarDialogFragment.TAG)
+ progressBarFragment.show(
+ activity.supportFragmentManager, SystemUpdateProgressBarDialogFragment.TAG
+ )
progressBarFragment.isCancelable = false
}
}
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
deleted file mode 100644
index 1b3c450534..0000000000
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/CompletableFuture.java
+++ /dev/null
@@ -1,97 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-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();
- }
- }
-}