From d833fc383dcd46d0dab7239f907dd71f5b59e9ed Mon Sep 17 00:00:00 2001 From: Charles Lombardo Date: Wed, 30 Aug 2023 18:02:16 -0400 Subject: [PATCH 1/2] android: Combine LongMessageDialogFragment with MessageDialogFragment --- .../yuzu_emu/adapters/HomeSettingAdapter.kt | 4 +- .../fragments/ImportExportSavesFragment.kt | 4 +- .../fragments/LongMessageDialogFragment.kt | 62 ------------------- .../fragments/MessageDialogFragment.kt | 32 +++++++--- .../org/yuzu/yuzu_emu/ui/main/MainActivity.kt | 43 +++++++------ 5 files changed, 47 insertions(+), 98 deletions(-) delete mode 100644 src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/LongMessageDialogFragment.kt diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/HomeSettingAdapter.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/HomeSettingAdapter.kt index 9f859b4422..8d87d3bd72 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/HomeSettingAdapter.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/HomeSettingAdapter.kt @@ -45,8 +45,8 @@ class HomeSettingAdapter( holder.option.onClick.invoke() } else { MessageDialogFragment.newInstance( - holder.option.disabledTitleId, - holder.option.disabledMessageId + titleId = holder.option.disabledTitleId, + descriptionId = holder.option.disabledMessageId ).show(activity.supportFragmentManager, MessageDialogFragment.TAG) } } diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/ImportExportSavesFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/ImportExportSavesFragment.kt index e1495ee8c4..f38aeea531 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/ImportExportSavesFragment.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/ImportExportSavesFragment.kt @@ -187,8 +187,8 @@ class ImportExportSavesFragment : DialogFragment() { withContext(Dispatchers.Main) { if (!validZip) { MessageDialogFragment.newInstance( - R.string.save_file_invalid_zip_structure, - R.string.save_file_invalid_zip_structure_description + titleId = R.string.save_file_invalid_zip_structure, + descriptionId = R.string.save_file_invalid_zip_structure_description ).show(activity.supportFragmentManager, MessageDialogFragment.TAG) return@withContext } diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/LongMessageDialogFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/LongMessageDialogFragment.kt deleted file mode 100644 index b29b627e9e..0000000000 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/LongMessageDialogFragment.kt +++ /dev/null @@ -1,62 +0,0 @@ -// SPDX-FileCopyrightText: 2023 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -package org.yuzu.yuzu_emu.fragments - -import android.app.Dialog -import android.content.Intent -import android.net.Uri -import android.os.Bundle -import androidx.fragment.app.DialogFragment -import com.google.android.material.dialog.MaterialAlertDialogBuilder -import org.yuzu.yuzu_emu.R - -class LongMessageDialogFragment : DialogFragment() { - override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { - val titleId = requireArguments().getInt(TITLE) - val description = requireArguments().getString(DESCRIPTION) - val helpLinkId = requireArguments().getInt(HELP_LINK) - - val dialog = MaterialAlertDialogBuilder(requireContext()) - .setPositiveButton(R.string.close, null) - .setTitle(titleId) - .setMessage(description) - - if (helpLinkId != 0) { - dialog.setNeutralButton(R.string.learn_more) { _, _ -> - openLink(getString(helpLinkId)) - } - } - - return dialog.show() - } - - private fun openLink(link: String) { - val intent = Intent(Intent.ACTION_VIEW, Uri.parse(link)) - startActivity(intent) - } - - companion object { - const val TAG = "LongMessageDialogFragment" - - private const val TITLE = "Title" - private const val DESCRIPTION = "Description" - private const val HELP_LINK = "Link" - - fun newInstance( - titleId: Int, - description: String, - helpLinkId: Int = 0 - ): LongMessageDialogFragment { - val dialog = LongMessageDialogFragment() - val bundle = Bundle() - bundle.apply { - putInt(TITLE, titleId) - putString(DESCRIPTION, description) - putInt(HELP_LINK, helpLinkId) - } - dialog.arguments = bundle - return dialog - } - } -} diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/MessageDialogFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/MessageDialogFragment.kt index 2db38fdc2e..7d1c2c8dd9 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/MessageDialogFragment.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/MessageDialogFragment.kt @@ -13,14 +13,20 @@ import org.yuzu.yuzu_emu.R class MessageDialogFragment : DialogFragment() { override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { - val titleId = requireArguments().getInt(TITLE) - val descriptionId = requireArguments().getInt(DESCRIPTION) + val titleId = requireArguments().getInt(TITLE_ID) + val titleString = requireArguments().getString(TITLE_STRING)!! + val descriptionId = requireArguments().getInt(DESCRIPTION_ID) + val descriptionString = requireArguments().getString(DESCRIPTION_STRING)!! val helpLinkId = requireArguments().getInt(HELP_LINK) val dialog = MaterialAlertDialogBuilder(requireContext()) .setPositiveButton(R.string.close, null) - .setTitle(titleId) - .setMessage(descriptionId) + + if (titleId != 0) dialog.setTitle(titleId) + if (titleString.isNotEmpty()) dialog.setTitle(titleString) + + if (descriptionId != 0) dialog.setMessage(descriptionId) + if (descriptionString.isNotEmpty()) dialog.setMessage(descriptionString) if (helpLinkId != 0) { dialog.setNeutralButton(R.string.learn_more) { _, _ -> @@ -39,20 +45,26 @@ class MessageDialogFragment : DialogFragment() { companion object { const val TAG = "MessageDialogFragment" - private const val TITLE = "Title" - private const val DESCRIPTION = "Description" + private const val TITLE_ID = "Title" + private const val TITLE_STRING = "TitleString" + private const val DESCRIPTION_ID = "DescriptionId" + private const val DESCRIPTION_STRING = "DescriptionString" private const val HELP_LINK = "Link" fun newInstance( - titleId: Int, - descriptionId: Int, + titleId: Int = 0, + titleString: String = "", + descriptionId: Int = 0, + descriptionString: String = "", helpLinkId: Int = 0 ): MessageDialogFragment { val dialog = MessageDialogFragment() val bundle = Bundle() bundle.apply { - putInt(TITLE, titleId) - putInt(DESCRIPTION, descriptionId) + putInt(TITLE_ID, titleId) + putString(TITLE_STRING, titleString) + putInt(DESCRIPTION_ID, descriptionId) + putString(DESCRIPTION_STRING, descriptionString) putInt(HELP_LINK, helpLinkId) } dialog.arguments = bundle diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt index 7735452e51..0721a59358 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt @@ -42,7 +42,6 @@ import org.yuzu.yuzu_emu.databinding.DialogProgressBarBinding import org.yuzu.yuzu_emu.features.settings.model.Settings import org.yuzu.yuzu_emu.features.settings.utils.SettingsFile import org.yuzu.yuzu_emu.fragments.IndeterminateProgressDialogFragment -import org.yuzu.yuzu_emu.fragments.LongMessageDialogFragment import org.yuzu.yuzu_emu.fragments.MessageDialogFragment import org.yuzu.yuzu_emu.model.GamesViewModel import org.yuzu.yuzu_emu.model.HomeViewModel @@ -301,8 +300,8 @@ class MainActivity : AppCompatActivity(), ThemeProvider { fun processKey(result: Uri): Boolean { if (FileUtil.getExtension(result) != "keys") { MessageDialogFragment.newInstance( - R.string.reading_keys_failure, - R.string.install_prod_keys_failure_extension_description + titleId = R.string.reading_keys_failure, + descriptionId = R.string.install_prod_keys_failure_extension_description ).show(supportFragmentManager, MessageDialogFragment.TAG) return false } @@ -330,9 +329,9 @@ class MainActivity : AppCompatActivity(), ThemeProvider { return true } else { MessageDialogFragment.newInstance( - R.string.invalid_keys_error, - R.string.install_keys_failure_description, - R.string.dumping_keys_quickstart_link + titleId = R.string.invalid_keys_error, + descriptionId = R.string.install_keys_failure_description, + helpLinkId = R.string.dumping_keys_quickstart_link ).show(supportFragmentManager, MessageDialogFragment.TAG) return false } @@ -370,8 +369,8 @@ class MainActivity : AppCompatActivity(), ThemeProvider { val filteredNumOfFiles = cacheFirmwareDir.list(filterNCA)?.size ?: -2 messageToShow = if (unfilteredNumOfFiles != filteredNumOfFiles) { MessageDialogFragment.newInstance( - R.string.firmware_installed_failure, - R.string.firmware_installed_failure_description + titleId = R.string.firmware_installed_failure, + descriptionId = R.string.firmware_installed_failure_description ) } else { firmwarePath.deleteRecursively() @@ -401,8 +400,8 @@ class MainActivity : AppCompatActivity(), ThemeProvider { if (FileUtil.getExtension(result) != "bin") { MessageDialogFragment.newInstance( - R.string.reading_keys_failure, - R.string.install_amiibo_keys_failure_extension_description + titleId = R.string.reading_keys_failure, + descriptionId = R.string.install_amiibo_keys_failure_extension_description ).show(supportFragmentManager, MessageDialogFragment.TAG) return@registerForActivityResult } @@ -428,9 +427,9 @@ class MainActivity : AppCompatActivity(), ThemeProvider { ).show() } else { MessageDialogFragment.newInstance( - R.string.invalid_keys_error, - R.string.install_keys_failure_description, - R.string.dumping_keys_quickstart_link + titleId = R.string.invalid_keys_error, + descriptionId = R.string.install_keys_failure_description, + helpLinkId = R.string.dumping_keys_quickstart_link ).show(supportFragmentManager, MessageDialogFragment.TAG) } } @@ -578,16 +577,16 @@ class MainActivity : AppCompatActivity(), ThemeProvider { ) installResult.append(separator) } - LongMessageDialogFragment.newInstance( - R.string.install_game_content_failure, - installResult.toString().trim(), - R.string.install_game_content_help_link - ).show(supportFragmentManager, LongMessageDialogFragment.TAG) + MessageDialogFragment.newInstance( + titleId = R.string.install_game_content_failure, + descriptionString = installResult.toString().trim(), + helpLinkId = R.string.install_game_content_help_link + ).show(supportFragmentManager, MessageDialogFragment.TAG) } else { - LongMessageDialogFragment.newInstance( - R.string.install_game_content_success, - installResult.toString().trim() - ).show(supportFragmentManager, LongMessageDialogFragment.TAG) + MessageDialogFragment.newInstance( + titleId = R.string.install_game_content_success, + descriptionString = installResult.toString().trim() + ).show(supportFragmentManager, MessageDialogFragment.TAG) } } } From 50d4e0f4f77ea35dbdf1c07067e68fcd0ee2b326 Mon Sep 17 00:00:00 2001 From: Charles Lombardo Date: Wed, 30 Aug 2023 19:05:33 -0400 Subject: [PATCH 2/2] android: Fix game content installer Before this would run on the main thread and freeze the device. Additionally this fixes the result dialog not appearing if a config change happens during the installation by getting the activity's fragment manager when needed. --- .../IndeterminateProgressDialogFragment.kt | 2 +- .../org/yuzu/yuzu_emu/ui/main/MainActivity.kt | 163 +++++++++--------- 2 files changed, 80 insertions(+), 85 deletions(-) diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/IndeterminateProgressDialogFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/IndeterminateProgressDialogFragment.kt index 739b26f995..181bd983af 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/IndeterminateProgressDialogFragment.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/IndeterminateProgressDialogFragment.kt @@ -34,7 +34,7 @@ class IndeterminateProgressDialogFragment : DialogFragment() { when (val result = taskViewModel.result.value) { is String -> Toast.makeText(requireContext(), result, Toast.LENGTH_LONG).show() is MessageDialogFragment -> result.show( - parentFragmentManager, + requireActivity().supportFragmentManager, MessageDialogFragment.TAG ) } diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt index 0721a59358..7d8e06ad8a 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt @@ -501,96 +501,91 @@ class MainActivity : AppCompatActivity(), ThemeProvider { var errorBaseGame = 0 var errorExtension = 0 var errorOther = 0 - var errorTotal = 0 - lifecycleScope.launch { - documents.forEach { - when (NativeLibrary.installFileToNand(it.toString())) { - NativeLibrary.InstallFileToNandResult.Success -> { - installSuccess += 1 - } - - NativeLibrary.InstallFileToNandResult.SuccessFileOverwritten -> { - installOverwrite += 1 - } - - NativeLibrary.InstallFileToNandResult.ErrorBaseGame -> { - errorBaseGame += 1 - } - - NativeLibrary.InstallFileToNandResult.ErrorFilenameExtension -> { - errorExtension += 1 - } - - else -> { - errorOther += 1 - } + documents.forEach { + when (NativeLibrary.installFileToNand(it.toString())) { + NativeLibrary.InstallFileToNandResult.Success -> { + installSuccess += 1 } - } - withContext(Dispatchers.Main) { - val separator = System.getProperty("line.separator") ?: "\n" - val installResult = StringBuilder() - if (installSuccess > 0) { - installResult.append( - getString( - R.string.install_game_content_success_install, - installSuccess - ) - ) - installResult.append(separator) + + NativeLibrary.InstallFileToNandResult.SuccessFileOverwritten -> { + installOverwrite += 1 } - if (installOverwrite > 0) { - installResult.append( - getString( - R.string.install_game_content_success_overwrite, - installOverwrite - ) - ) - installResult.append(separator) + + NativeLibrary.InstallFileToNandResult.ErrorBaseGame -> { + errorBaseGame += 1 } - errorTotal = errorBaseGame + errorExtension + errorOther - if (errorTotal > 0) { - installResult.append(separator) - installResult.append( - getString( - R.string.install_game_content_failed_count, - errorTotal - ) - ) - installResult.append(separator) - if (errorBaseGame > 0) { - installResult.append(separator) - installResult.append( - getString(R.string.install_game_content_failure_base) - ) - installResult.append(separator) - } - if (errorExtension > 0) { - installResult.append(separator) - installResult.append( - getString(R.string.install_game_content_failure_file_extension) - ) - installResult.append(separator) - } - if (errorOther > 0) { - installResult.append( - getString(R.string.install_game_content_failure_description) - ) - installResult.append(separator) - } - MessageDialogFragment.newInstance( - titleId = R.string.install_game_content_failure, - descriptionString = installResult.toString().trim(), - helpLinkId = R.string.install_game_content_help_link - ).show(supportFragmentManager, MessageDialogFragment.TAG) - } else { - MessageDialogFragment.newInstance( - titleId = R.string.install_game_content_success, - descriptionString = installResult.toString().trim() - ).show(supportFragmentManager, MessageDialogFragment.TAG) + + NativeLibrary.InstallFileToNandResult.ErrorFilenameExtension -> { + errorExtension += 1 + } + + else -> { + errorOther += 1 } } } - return@newInstance installSuccess + installOverwrite + errorTotal + + val separator = System.getProperty("line.separator") ?: "\n" + val installResult = StringBuilder() + if (installSuccess > 0) { + installResult.append( + getString( + R.string.install_game_content_success_install, + installSuccess + ) + ) + installResult.append(separator) + } + if (installOverwrite > 0) { + installResult.append( + getString( + R.string.install_game_content_success_overwrite, + installOverwrite + ) + ) + installResult.append(separator) + } + val errorTotal: Int = errorBaseGame + errorExtension + errorOther + if (errorTotal > 0) { + installResult.append(separator) + installResult.append( + getString( + R.string.install_game_content_failed_count, + errorTotal + ) + ) + installResult.append(separator) + if (errorBaseGame > 0) { + installResult.append(separator) + installResult.append( + getString(R.string.install_game_content_failure_base) + ) + installResult.append(separator) + } + if (errorExtension > 0) { + installResult.append(separator) + installResult.append( + getString(R.string.install_game_content_failure_file_extension) + ) + installResult.append(separator) + } + if (errorOther > 0) { + installResult.append( + getString(R.string.install_game_content_failure_description) + ) + installResult.append(separator) + } + return@newInstance MessageDialogFragment.newInstance( + titleId = R.string.install_game_content_failure, + descriptionString = installResult.toString().trim(), + helpLinkId = R.string.install_game_content_help_link + ) + } else { + return@newInstance MessageDialogFragment.newInstance( + titleId = R.string.install_game_content_success, + descriptionString = installResult.toString().trim() + ) + } }.show(supportFragmentManager, IndeterminateProgressDialogFragment.TAG) } }