From 6dfa5550998fdf6d33ad60f5f5d6b00f6840f728 Mon Sep 17 00:00:00 2001 From: Charles Lombardo Date: Tue, 24 Jan 2023 00:24:05 -0500 Subject: [PATCH 01/11] Android: Convert SystemUpdateProgressBarDialogFragment to Kotlin --- ...SystemUpdateProgressBarDialogFragment.java | 133 ------------------ .../SystemUpdateProgressBarDialogFragment.kt | 110 +++++++++++++++ 2 files changed, 110 insertions(+), 133 deletions(-) delete mode 100644 Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/SystemUpdateProgressBarDialogFragment.java create mode 100644 Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/SystemUpdateProgressBarDialogFragment.kt diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/SystemUpdateProgressBarDialogFragment.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/SystemUpdateProgressBarDialogFragment.java deleted file mode 100644 index 96dda28903..0000000000 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/SystemUpdateProgressBarDialogFragment.java +++ /dev/null @@ -1,133 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later - -package org.dolphinemu.dolphinemu.features.sysupdate.ui; - -import android.app.Dialog; -import android.content.pm.ActivityInfo; -import android.os.Bundle; -import android.widget.Button; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.appcompat.app.AlertDialog; -import androidx.appcompat.app.AppCompatActivity; -import androidx.fragment.app.DialogFragment; -import androidx.lifecycle.ViewModelProvider; - -import com.google.android.material.dialog.MaterialAlertDialogBuilder; - -import org.dolphinemu.dolphinemu.R; -import org.dolphinemu.dolphinemu.databinding.DialogProgressBinding; -import org.dolphinemu.dolphinemu.databinding.DialogProgressTvBinding; - -public class SystemUpdateProgressBarDialogFragment extends DialogFragment -{ - @NonNull - @Override - public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) - { - // Store the current orientation to be restored later - final int orientation = getActivity().getRequestedOrientation(); - // Rotating the device while the update is running can result in a title failing to import. - getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED); - - SystemUpdateViewModel viewModel = - new ViewModelProvider(requireActivity()).get(SystemUpdateViewModel.class); - - DialogProgressBinding dialogProgressBinding; - DialogProgressTvBinding dialogProgressTvBinding; - - // We need to set the message to something here, otherwise the text will not appear when we set it later. - MaterialAlertDialogBuilder progressDialogBuilder = - new MaterialAlertDialogBuilder(requireContext()) - .setTitle(getString(R.string.updating)) - .setMessage("") - .setNegativeButton(getString(R.string.cancel), null) - .setCancelable(false); - - // TODO: Remove dialog_progress_tv if we switch to an AppCompatActivity for leanback - if (getActivity() instanceof AppCompatActivity) - { - dialogProgressBinding = DialogProgressBinding.inflate(getLayoutInflater()); - progressDialogBuilder.setView(dialogProgressBinding.getRoot()); - - viewModel.getProgressData().observe(this, - (@Nullable Integer progress) -> dialogProgressBinding.updateProgress.setProgress( - progress)); - - viewModel.getTotalData().observe(this, (@Nullable Integer total) -> - { - if (total == 0) - { - return; - } - - dialogProgressBinding.updateProgress.setMax(total); - }); - } - else - { - dialogProgressTvBinding = DialogProgressTvBinding.inflate(getLayoutInflater()); - progressDialogBuilder.setView(dialogProgressTvBinding.getRoot()); - - viewModel.getProgressData().observe(this, - (@Nullable Integer progress) -> dialogProgressTvBinding.updateProgress.setProgress( - progress)); - - viewModel.getTotalData().observe(this, (@Nullable Integer total) -> - { - if (total == 0) - { - return; - } - - dialogProgressTvBinding.updateProgress.setMax(total); - }); - } - - AlertDialog progressDialog = progressDialogBuilder.create(); - - viewModel.getTitleIdData().observe(this, (@Nullable Long titleId) -> progressDialog.setMessage( - getString(R.string.updating_message, titleId))); - - viewModel.getResultData().observe(this, (@Nullable Integer result) -> - { - if (result == -1) - { - // This is the default value, ignore - return; - } - - SystemUpdateResultFragment progressBarFragment = new SystemUpdateResultFragment(); - progressBarFragment.show(getParentFragmentManager(), "OnlineUpdateResultFragment"); - - getActivity().setRequestedOrientation(orientation); - - dismiss(); - }); - - if (savedInstanceState == null) - { - viewModel.startUpdate(); - } - return progressDialog; - } - - // By default, the ProgressDialog will immediately dismiss itself upon a button being pressed. - // Setting the OnClickListener again after the dialog is shown overrides this behavior. - @Override - public void onResume() - { - super.onResume(); - AlertDialog alertDialog = (AlertDialog) getDialog(); - SystemUpdateViewModel viewModel = - new ViewModelProvider(requireActivity()).get(SystemUpdateViewModel.class); - Button negativeButton = alertDialog.getButton(Dialog.BUTTON_NEGATIVE); - negativeButton.setOnClickListener(v -> - { - alertDialog.setTitle(getString(R.string.cancelling)); - alertDialog.setMessage(getString(R.string.update_cancelling)); - viewModel.setCanceled(); - }); - } -} diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/SystemUpdateProgressBarDialogFragment.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/SystemUpdateProgressBarDialogFragment.kt new file mode 100644 index 0000000000..6ff5f4d4f2 --- /dev/null +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/SystemUpdateProgressBarDialogFragment.kt @@ -0,0 +1,110 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +package org.dolphinemu.dolphinemu.features.sysupdate.ui + +import android.app.Dialog +import android.content.pm.ActivityInfo +import android.os.Bundle +import androidx.appcompat.app.AlertDialog +import androidx.appcompat.app.AppCompatActivity +import androidx.fragment.app.DialogFragment +import androidx.lifecycle.ViewModelProvider +import com.google.android.material.dialog.MaterialAlertDialogBuilder +import org.dolphinemu.dolphinemu.R +import org.dolphinemu.dolphinemu.databinding.DialogProgressBinding +import org.dolphinemu.dolphinemu.databinding.DialogProgressTvBinding + +class SystemUpdateProgressBarDialogFragment : DialogFragment() { + override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { + // Store the current orientation to be restored later + val orientation = requireActivity().requestedOrientation + // Rotating the device while the update is running can result in a title failing to import. + requireActivity().requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LOCKED + + val viewModel = ViewModelProvider(requireActivity())[SystemUpdateViewModel::class.java] + + val dialogProgressBinding: DialogProgressBinding + val dialogProgressTvBinding: DialogProgressTvBinding + + // We need to set the message to something here, otherwise the text will not appear when we set it later. + val progressDialogBuilder = MaterialAlertDialogBuilder(requireContext()) + .setTitle(getString(R.string.updating)) + .setMessage("") + .setNegativeButton(getString(R.string.cancel), null) + .setCancelable(false) + + // TODO: Remove dialog_progress_tv if we switch to an AppCompatActivity for leanback + if (activity is AppCompatActivity) { + dialogProgressBinding = DialogProgressBinding.inflate(layoutInflater) + progressDialogBuilder.setView(dialogProgressBinding.root) + + viewModel.progressData.observe( + this + ) { progress: Int -> + dialogProgressBinding.updateProgress.progress = progress + } + + viewModel.totalData.observe(this) { total: Int -> + if (total == 0) { + return@observe + } + dialogProgressBinding.updateProgress.max = total + } + } else { + dialogProgressTvBinding = DialogProgressTvBinding.inflate(layoutInflater) + progressDialogBuilder.setView(dialogProgressTvBinding.root) + + viewModel.progressData.observe( + this + ) { progress: Int -> + dialogProgressTvBinding.updateProgress.progress = progress + } + + viewModel.totalData.observe(this) { total: Int -> + if (total == 0) { + return@observe + } + dialogProgressTvBinding.updateProgress.max = total + } + } + + val progressDialog = progressDialogBuilder.create() + + viewModel.titleIdData.observe(this) { titleId: Long -> + progressDialog.setMessage(getString(R.string.updating_message, titleId)) + } + + viewModel.resultData.observe(this) { result: Int -> + if (result == -1) { + // This is the default value, ignore + return@observe + } + + val progressBarFragment = SystemUpdateResultFragment() + progressBarFragment.show(parentFragmentManager, "OnlineUpdateResultFragment") + + requireActivity().requestedOrientation = orientation + + dismiss() + } + + if (savedInstanceState == null) { + viewModel.startUpdate() + } + return progressDialog + } + + // By default, the ProgressDialog will immediately dismiss itself upon a button being pressed. + // Setting the OnClickListener again after the dialog is shown overrides this behavior. + override fun onResume() { + super.onResume() + val alertDialog = dialog as AlertDialog? + val viewModel = ViewModelProvider(requireActivity())[SystemUpdateViewModel::class.java] + val negativeButton = alertDialog!!.getButton(Dialog.BUTTON_NEGATIVE) + negativeButton.setOnClickListener { + alertDialog.setTitle(getString(R.string.cancelling)) + alertDialog.setMessage(getString(R.string.update_cancelling)) + viewModel.setCanceled() + } + } +} From 2b17e0334aa47c4266b70c6a7e08a143abdf9462 Mon Sep 17 00:00:00 2001 From: Charles Lombardo Date: Tue, 24 Jan 2023 10:55:33 -0500 Subject: [PATCH 02/11] Android: Convert SystemUpdateViewModel to Kotlin --- .../sysupdate/ui/SystemUpdateViewModel.java | 152 ------------------ .../sysupdate/ui/SystemUpdateViewModel.kt | 79 +++++++++ 2 files changed, 79 insertions(+), 152 deletions(-) delete mode 100644 Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/SystemUpdateViewModel.java create mode 100644 Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/SystemUpdateViewModel.kt diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/SystemUpdateViewModel.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/SystemUpdateViewModel.java deleted file mode 100644 index a249b01ee7..0000000000 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/SystemUpdateViewModel.java +++ /dev/null @@ -1,152 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later - -package org.dolphinemu.dolphinemu.features.sysupdate.ui; - -import androidx.lifecycle.MutableLiveData; -import androidx.lifecycle.ViewModel; - -import org.dolphinemu.dolphinemu.utils.WiiUpdateCallback; -import org.dolphinemu.dolphinemu.utils.WiiUtils; - -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; - -public class SystemUpdateViewModel extends ViewModel -{ - private static final ExecutorService executor = Executors.newFixedThreadPool(1); - - private final MutableLiveData mProgressData = new MutableLiveData<>(); - private final MutableLiveData mTotalData = new MutableLiveData<>(); - private final MutableLiveData mTitleIdData = new MutableLiveData<>(); - private final MutableLiveData mResultData = new MutableLiveData<>(); - - private boolean mCanceled = false; - private int mRegion; - private String mDiscPath; - - public SystemUpdateViewModel() - { - clear(); - } - - public void setRegion(int region) - { - mRegion = region; - } - - public int getRegion() - { - return mRegion; - } - - public void setDiscPath(String discPath) - { - mDiscPath = discPath; - } - - public String getDiscPath() - { - return mDiscPath; - } - - public MutableLiveData getProgressData() - { - return mProgressData; - } - - public MutableLiveData getTotalData() - { - return mTotalData; - } - - public MutableLiveData getTitleIdData() - { - return mTitleIdData; - } - - public MutableLiveData getResultData() - { - return mResultData; - } - - public void setCanceled() - { - mCanceled = true; - } - - public void startUpdate() - { - if (!mDiscPath.isEmpty()) - { - startDiscUpdate(mDiscPath); - } - else - { - final String region; - switch (mRegion) - { - case 0: - region = "EUR"; - break; - case 1: - region = "JPN"; - break; - case 2: - region = "KOR"; - break; - case 3: - region = "USA"; - break; - default: - region = ""; - break; - } - startOnlineUpdate(region); - } - } - - public void startOnlineUpdate(String region) - { - mCanceled = false; - - executor.execute(() -> - { - int result = WiiUtils.doOnlineUpdate(region, constructCallback()); - mResultData.postValue(result); - }); - } - - public void startDiscUpdate(String path) - { - mCanceled = false; - - executor.execute(() -> - { - int result = WiiUtils.doDiscUpdate(path, constructCallback()); - mResultData.postValue(result); - }); - } - - public void clear() - { - mProgressData.setValue(0); - mTotalData.setValue(0); - mTitleIdData.setValue(0l); - mResultData.setValue(-1); - mCanceled = false; - mRegion = -1; - mDiscPath = ""; - } - - private WiiUpdateCallback constructCallback() - { - return (processed, total, titleId) -> - { - mProgressData.postValue(processed); - mTotalData.postValue(total); - mTitleIdData.postValue(titleId); - - return !mCanceled; - }; - } -} diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/SystemUpdateViewModel.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/SystemUpdateViewModel.kt new file mode 100644 index 0000000000..dacc51221d --- /dev/null +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/SystemUpdateViewModel.kt @@ -0,0 +1,79 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +package org.dolphinemu.dolphinemu.features.sysupdate.ui + +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import org.dolphinemu.dolphinemu.utils.WiiUpdateCallback +import org.dolphinemu.dolphinemu.utils.WiiUtils +import java.util.concurrent.Executors + +class SystemUpdateViewModel : ViewModel() { + val progressData = MutableLiveData() + val totalData = MutableLiveData() + val titleIdData = MutableLiveData() + val resultData = MutableLiveData() + + private var canceled = false + var region = -1 + var discPath: String = "" + + init { + clear() + } + + fun setCanceled() { + canceled = true + } + + fun startUpdate() { + if (discPath.isNotEmpty()) { + startDiscUpdate(discPath) + } else { + val region: String = when (this.region) { + 0 -> "EUR" + 1 -> "JPN" + 2 -> "KOR" + 3 -> "USA" + else -> "" + } + startOnlineUpdate(region) + } + } + + private fun startOnlineUpdate(region: String?) { + canceled = false + executor.execute { + val result = WiiUtils.doOnlineUpdate(region, constructCallback()) + resultData.postValue(result) + } + } + + private fun startDiscUpdate(path: String?) { + canceled = false + executor.execute { + val result = WiiUtils.doDiscUpdate(path, constructCallback()) + resultData.postValue(result) + } + } + + fun clear() { + progressData.value = 0 + totalData.value = 0 + titleIdData.value = 0L + resultData.value = -1 + } + + private fun constructCallback(): WiiUpdateCallback { + return WiiUpdateCallback { processed: Int, total: Int, titleId: Long -> + progressData.postValue(processed) + totalData.postValue(total) + titleIdData.postValue(titleId) + !canceled + } + } + + companion object { + private val executor = Executors.newFixedThreadPool(1) + } +} From 60cb886cd458fc10390cb3e79096687da68a4354 Mon Sep 17 00:00:00 2001 From: Charles Lombardo Date: Tue, 24 Jan 2023 13:26:04 -0500 Subject: [PATCH 03/11] Android: Convert WiiUtils to Kotlin --- .../dolphinemu/dolphinemu/utils/WiiUtils.java | 42 ----------------- .../dolphinemu/dolphinemu/utils/WiiUtils.kt | 46 +++++++++++++++++++ 2 files changed, 46 insertions(+), 42 deletions(-) delete mode 100644 Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/WiiUtils.java create mode 100644 Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/WiiUtils.kt 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 deleted file mode 100644 index 61dfedf5cd..0000000000 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/WiiUtils.java +++ /dev/null @@ -1,42 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later - -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 final int UPDATE_RESULT_SUCCESS = 0; - public static final int UPDATE_RESULT_ALREADY_UP_TO_DATE = 1; - public static final int UPDATE_RESULT_REGION_MISMATCH = 2; - public static final int UPDATE_RESULT_MISSING_UPDATE_PARTITION = 3; - public static final int UPDATE_RESULT_DISC_READ_FAILED = 4; - public static final int UPDATE_RESULT_SERVER_FAILED = 5; - public static final int UPDATE_RESULT_DOWNLOAD_FAILED = 6; - public static final int UPDATE_RESULT_IMPORT_FAILED = 7; - public static final int UPDATE_RESULT_CANCELLED = 8; - - public static native boolean installWAD(String file); - - public static native int importWiiSave(String file, BooleanSupplier canOverwrite); - - public static native void importNANDBin(String file); - - public static native int doOnlineUpdate(String region, WiiUpdateCallback callback); - - public static native int doDiscUpdate(String path, WiiUpdateCallback callback); - - public static native boolean isSystemMenuInstalled(); - - public static native boolean isSystemMenuvWii(); - - public static native String getSystemMenuVersion(); - - public static native boolean syncSdFolderToSdImage(); - - public static native boolean syncSdImageToSdFolder(); -} diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/WiiUtils.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/WiiUtils.kt new file mode 100644 index 0000000000..b41ab24816 --- /dev/null +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/WiiUtils.kt @@ -0,0 +1,46 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +package org.dolphinemu.dolphinemu.utils + +object WiiUtils { + const val RESULT_SUCCESS = 0 + const val RESULT_ERROR = 1 + const val RESULT_CANCELLED = 2 + const val RESULT_CORRUPTED_SOURCE = 3 + const val RESULT_TITLE_MISSING = 4 + const val UPDATE_RESULT_SUCCESS = 0 + const val UPDATE_RESULT_ALREADY_UP_TO_DATE = 1 + const val UPDATE_RESULT_REGION_MISMATCH = 2 + const val UPDATE_RESULT_MISSING_UPDATE_PARTITION = 3 + const val UPDATE_RESULT_DISC_READ_FAILED = 4 + const val UPDATE_RESULT_SERVER_FAILED = 5 + const val UPDATE_RESULT_DOWNLOAD_FAILED = 6 + const val UPDATE_RESULT_IMPORT_FAILED = 7 + const val UPDATE_RESULT_CANCELLED = 8 + + @JvmStatic + external fun installWAD(file: String): Boolean + + @JvmStatic + external fun importWiiSave(file: String, canOverwrite: BooleanSupplier): Int + + @JvmStatic + external fun importNANDBin(file: String) + external fun doOnlineUpdate(region: String, callback: WiiUpdateCallback): Int + external fun doDiscUpdate(path: String, callback: WiiUpdateCallback): Int + + @JvmStatic + external fun isSystemMenuInstalled(): Boolean + + @JvmStatic + external fun isSystemMenuvWii(): Boolean + + @JvmStatic + external fun getSystemMenuVersion(): String + + @JvmStatic + external fun syncSdFolderToSdImage(): Boolean + + @JvmStatic + external fun syncSdImageToSdFolder(): Boolean +} From c8907349be6bc43365d34a51160426f8f63798b2 Mon Sep 17 00:00:00 2001 From: Charles Lombardo Date: Wed, 25 Jan 2023 13:59:19 -0500 Subject: [PATCH 04/11] Android: Convert SystemUpdateResultFragment to Kotlin --- .../ui/SystemUpdateResultFragment.java | 105 ------------------ .../ui/SystemUpdateResultFragment.kt | 61 ++++++++++ 2 files changed, 61 insertions(+), 105 deletions(-) delete mode 100644 Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/SystemUpdateResultFragment.java create mode 100644 Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/SystemUpdateResultFragment.kt diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/SystemUpdateResultFragment.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/SystemUpdateResultFragment.java deleted file mode 100644 index a8e638ad90..0000000000 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/SystemUpdateResultFragment.java +++ /dev/null @@ -1,105 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later - -package org.dolphinemu.dolphinemu.features.sysupdate.ui; - -import android.app.Dialog; -import android.os.Bundle; - -import androidx.annotation.NonNull; -import androidx.fragment.app.DialogFragment; -import androidx.lifecycle.ViewModelProvider; - -import com.google.android.material.dialog.MaterialAlertDialogBuilder; - -import org.dolphinemu.dolphinemu.R; -import org.dolphinemu.dolphinemu.utils.WiiUtils; - -public class SystemUpdateResultFragment extends DialogFragment -{ - private int mResult; - - @Override - public Dialog onCreateDialog(Bundle savedInstanceState) - { - SystemUpdateViewModel viewModel = - new ViewModelProvider(requireActivity()).get(SystemUpdateViewModel.class); - if (savedInstanceState == null) - { - mResult = viewModel.getResultData().getValue().intValue(); - viewModel.clear(); - } - else - { - mResult = savedInstanceState.getInt("result"); - } - - String message; - switch (mResult) - { - case WiiUtils.UPDATE_RESULT_SUCCESS: - message = getString(R.string.update_success); - break; - case WiiUtils.UPDATE_RESULT_ALREADY_UP_TO_DATE: - message = getString(R.string.already_up_to_date); - break; - case WiiUtils.UPDATE_RESULT_REGION_MISMATCH: - message = getString(R.string.region_mismatch); - break; - case WiiUtils.UPDATE_RESULT_MISSING_UPDATE_PARTITION: - message = getString(R.string.missing_update_partition); - break; - case WiiUtils.UPDATE_RESULT_DISC_READ_FAILED: - message = getString(R.string.disc_read_failed); - break; - case WiiUtils.UPDATE_RESULT_SERVER_FAILED: - message = getString(R.string.server_failed); - break; - case WiiUtils.UPDATE_RESULT_DOWNLOAD_FAILED: - message = getString(R.string.download_failed); - break; - case WiiUtils.UPDATE_RESULT_IMPORT_FAILED: - message = getString(R.string.import_failed); - break; - case WiiUtils.UPDATE_RESULT_CANCELLED: - message = getString(R.string.update_cancelled); - break; - default: - throw new IllegalStateException("Unexpected value: " + mResult); - } - - String title; - switch (mResult) - { - case WiiUtils.UPDATE_RESULT_SUCCESS: - case WiiUtils.UPDATE_RESULT_ALREADY_UP_TO_DATE: - title = getString(R.string.update_success_title); - break; - case WiiUtils.UPDATE_RESULT_REGION_MISMATCH: - case WiiUtils.UPDATE_RESULT_MISSING_UPDATE_PARTITION: - case WiiUtils.UPDATE_RESULT_DISC_READ_FAILED: - case WiiUtils.UPDATE_RESULT_SERVER_FAILED: - case WiiUtils.UPDATE_RESULT_DOWNLOAD_FAILED: - case WiiUtils.UPDATE_RESULT_IMPORT_FAILED: - title = getString(R.string.update_failed_title); - break; - case WiiUtils.UPDATE_RESULT_CANCELLED: - title = getString(R.string.update_cancelled_title); - break; - default: - throw new IllegalStateException("Unexpected value: " + mResult); - } - - return new MaterialAlertDialogBuilder(requireContext()) - .setTitle(title) - .setMessage(message) - .setPositiveButton(R.string.ok, (dialog, which) -> dismiss()) - .create(); - } - - @Override - public void onSaveInstanceState(@NonNull Bundle outState) - { - super.onSaveInstanceState(outState); - outState.putInt("result", mResult); - } -} diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/SystemUpdateResultFragment.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/SystemUpdateResultFragment.kt new file mode 100644 index 0000000000..352e6cd47a --- /dev/null +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/SystemUpdateResultFragment.kt @@ -0,0 +1,61 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +package org.dolphinemu.dolphinemu.features.sysupdate.ui + +import android.app.Dialog +import android.content.DialogInterface +import android.os.Bundle +import androidx.fragment.app.DialogFragment +import androidx.lifecycle.ViewModelProvider +import com.google.android.material.dialog.MaterialAlertDialogBuilder +import org.dolphinemu.dolphinemu.R +import org.dolphinemu.dolphinemu.utils.WiiUtils + +class SystemUpdateResultFragment : DialogFragment() { + private var mResult = 0 + + override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { + val viewModel = ViewModelProvider(requireActivity())[SystemUpdateViewModel::class.java] + if (savedInstanceState == null) { + mResult = viewModel.resultData.value!!.toInt() + viewModel.clear() + } else { + mResult = savedInstanceState.getInt("result") + } + val message: String = when (mResult) { + WiiUtils.UPDATE_RESULT_SUCCESS -> getString(R.string.update_success) + WiiUtils.UPDATE_RESULT_ALREADY_UP_TO_DATE -> getString(R.string.already_up_to_date) + WiiUtils.UPDATE_RESULT_REGION_MISMATCH -> getString(R.string.region_mismatch) + WiiUtils.UPDATE_RESULT_MISSING_UPDATE_PARTITION -> getString(R.string.missing_update_partition) + WiiUtils.UPDATE_RESULT_DISC_READ_FAILED -> getString(R.string.disc_read_failed) + WiiUtils.UPDATE_RESULT_SERVER_FAILED -> getString(R.string.server_failed) + WiiUtils.UPDATE_RESULT_DOWNLOAD_FAILED -> getString(R.string.download_failed) + WiiUtils.UPDATE_RESULT_IMPORT_FAILED -> getString(R.string.import_failed) + WiiUtils.UPDATE_RESULT_CANCELLED -> getString(R.string.update_cancelled) + else -> throw IllegalStateException("Unexpected value: $mResult") + } + val title: String = when (mResult) { + WiiUtils.UPDATE_RESULT_SUCCESS, + WiiUtils.UPDATE_RESULT_ALREADY_UP_TO_DATE -> getString(R.string.update_success_title) + WiiUtils.UPDATE_RESULT_REGION_MISMATCH, + WiiUtils.UPDATE_RESULT_MISSING_UPDATE_PARTITION, + WiiUtils.UPDATE_RESULT_DISC_READ_FAILED, + WiiUtils.UPDATE_RESULT_SERVER_FAILED, + WiiUtils.UPDATE_RESULT_DOWNLOAD_FAILED, + WiiUtils.UPDATE_RESULT_IMPORT_FAILED -> getString(R.string.update_failed_title) + WiiUtils.UPDATE_RESULT_CANCELLED -> getString(R.string.update_cancelled_title) + else -> throw IllegalStateException("Unexpected value: $mResult") + } + + return MaterialAlertDialogBuilder(requireContext()) + .setTitle(title) + .setMessage(message) + .setPositiveButton(R.string.ok) { _: DialogInterface?, _: Int -> dismiss() } + .create() + } + + override fun onSaveInstanceState(outState: Bundle) { + super.onSaveInstanceState(outState) + outState.putInt("result", mResult) + } +} From 0ac4fe763b8eb9b459e2f8a934b7ee8f80a6cdd6 Mon Sep 17 00:00:00 2001 From: Charles Lombardo Date: Wed, 25 Jan 2023 14:03:48 -0500 Subject: [PATCH 05/11] Android: Convert SystemMenuNotInstalledDialogFragment to Kotlin --- .../SystemMenuNotInstalledDialogFragment.java | 34 ------------------- .../SystemMenuNotInstalledDialogFragment.kt | 27 +++++++++++++++ 2 files changed, 27 insertions(+), 34 deletions(-) delete mode 100644 Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/SystemMenuNotInstalledDialogFragment.java create mode 100644 Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/SystemMenuNotInstalledDialogFragment.kt diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/SystemMenuNotInstalledDialogFragment.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/SystemMenuNotInstalledDialogFragment.java deleted file mode 100644 index 671750e1d6..0000000000 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/SystemMenuNotInstalledDialogFragment.java +++ /dev/null @@ -1,34 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later - -package org.dolphinemu.dolphinemu.features.sysupdate.ui; - -import android.app.Dialog; -import android.os.Bundle; - -import androidx.fragment.app.DialogFragment; -import androidx.fragment.app.FragmentManager; - -import com.google.android.material.dialog.MaterialAlertDialogBuilder; - -import org.dolphinemu.dolphinemu.R; - -public class SystemMenuNotInstalledDialogFragment extends DialogFragment -{ - @Override - public Dialog onCreateDialog(Bundle savedInstanceState) - { - return new MaterialAlertDialogBuilder(requireContext()) - .setTitle(R.string.system_menu_not_installed_title) - .setMessage(R.string.system_menu_not_installed_message) - .setPositiveButton(R.string.yes, (dialog, which) -> - { - FragmentManager fragmentManager = getParentFragmentManager(); - OnlineUpdateRegionSelectDialogFragment dialogFragment = - new OnlineUpdateRegionSelectDialogFragment(); - dialogFragment.show(fragmentManager, "OnlineUpdateRegionSelectDialogFragment"); - dismiss(); - }) - .setNegativeButton(R.string.no, (dialog, which) -> dismiss()) - .create(); - } -} diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/SystemMenuNotInstalledDialogFragment.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/SystemMenuNotInstalledDialogFragment.kt new file mode 100644 index 0000000000..396c60b8d8 --- /dev/null +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/SystemMenuNotInstalledDialogFragment.kt @@ -0,0 +1,27 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +package org.dolphinemu.dolphinemu.features.sysupdate.ui + +import android.app.Dialog +import android.content.DialogInterface +import android.os.Bundle +import androidx.fragment.app.DialogFragment +import com.google.android.material.dialog.MaterialAlertDialogBuilder +import org.dolphinemu.dolphinemu.R + +class SystemMenuNotInstalledDialogFragment : DialogFragment() { + override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { + return MaterialAlertDialogBuilder(requireContext()) + .setTitle(R.string.system_menu_not_installed_title) + .setMessage(R.string.system_menu_not_installed_message) + .setPositiveButton(R.string.yes) { _: DialogInterface?, _: Int -> + OnlineUpdateRegionSelectDialogFragment().show( + parentFragmentManager, + "OnlineUpdateRegionSelectDialogFragment" + ) + dismiss() + } + .setNegativeButton(R.string.no) { _: DialogInterface?, _: Int -> dismiss() } + .create() + } +} From 5eeb0a540bd76661aecd16ff3bb395aa162ada27 Mon Sep 17 00:00:00 2001 From: Charles Lombardo Date: Wed, 25 Jan 2023 14:09:38 -0500 Subject: [PATCH 06/11] Android: Convert OnlineUpdateRegionSelectDialogFragment to Kotlin --- ...nlineUpdateRegionSelectDialogFragment.java | 44 ------------------- .../OnlineUpdateRegionSelectDialogFragment.kt | 36 +++++++++++++++ 2 files changed, 36 insertions(+), 44 deletions(-) delete mode 100644 Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/OnlineUpdateRegionSelectDialogFragment.java create mode 100644 Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/OnlineUpdateRegionSelectDialogFragment.kt diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/OnlineUpdateRegionSelectDialogFragment.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/OnlineUpdateRegionSelectDialogFragment.java deleted file mode 100644 index ea1c535ca4..0000000000 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/OnlineUpdateRegionSelectDialogFragment.java +++ /dev/null @@ -1,44 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later - -package org.dolphinemu.dolphinemu.features.sysupdate.ui; - -import android.app.Dialog; -import android.os.Bundle; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.fragment.app.DialogFragment; -import androidx.lifecycle.ViewModelProvider; - -import com.google.android.material.dialog.MaterialAlertDialogBuilder; - -import org.dolphinemu.dolphinemu.R; - -public class OnlineUpdateRegionSelectDialogFragment extends DialogFragment -{ - @NonNull - @Override - public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) - { - String[] items = - {getString(R.string.country_europe), getString(R.string.country_japan), getString( - R.string.country_korea), getString(R.string.country_usa)}; - int checkedItem = -1; - - return new MaterialAlertDialogBuilder(requireContext()) - .setTitle(R.string.region_select_title) - .setSingleChoiceItems(items, checkedItem, (dialog, which) -> - { - SystemUpdateViewModel viewModel = - new ViewModelProvider(requireActivity()).get(SystemUpdateViewModel.class); - viewModel.setRegion(which); - - SystemUpdateProgressBarDialogFragment progressBarFragment = - new SystemUpdateProgressBarDialogFragment(); - progressBarFragment - .show(getParentFragmentManager(), "OnlineUpdateProgressBarDialogFragment"); - dismiss(); - }) - .create(); - } -} diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/OnlineUpdateRegionSelectDialogFragment.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/OnlineUpdateRegionSelectDialogFragment.kt new file mode 100644 index 0000000000..1e3b7235da --- /dev/null +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/OnlineUpdateRegionSelectDialogFragment.kt @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +package org.dolphinemu.dolphinemu.features.sysupdate.ui + +import android.app.Dialog +import android.content.DialogInterface +import android.os.Bundle +import androidx.fragment.app.DialogFragment +import androidx.lifecycle.ViewModelProvider +import com.google.android.material.dialog.MaterialAlertDialogBuilder +import org.dolphinemu.dolphinemu.R + +class OnlineUpdateRegionSelectDialogFragment : DialogFragment() { + override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { + val items = arrayOf( + getString(R.string.country_europe), + getString(R.string.country_japan), + getString(R.string.country_korea), + getString(R.string.country_usa) + ) + val checkedItem = -1 + return MaterialAlertDialogBuilder(requireContext()) + .setTitle(R.string.region_select_title) + .setSingleChoiceItems(items, checkedItem) { _: DialogInterface?, which: Int -> + val viewModel = + ViewModelProvider(requireActivity())[SystemUpdateViewModel::class.java] + viewModel.region = which + SystemUpdateProgressBarDialogFragment().show( + parentFragmentManager, + "OnlineUpdateProgressBarDialogFragment" + ) + dismiss() + } + .create() + } +} From c0868f04a980d32fff00c6dfc51088d73f9c0e7f Mon Sep 17 00:00:00 2001 From: Charles Lombardo Date: Thu, 26 Jan 2023 02:36:00 -0500 Subject: [PATCH 07/11] Android: Use Kotlin extensions for lifecycle components --- Source/Android/app/build.gradle | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Source/Android/app/build.gradle b/Source/Android/app/build.gradle index 11349147e8..e265f56068 100644 --- a/Source/Android/app/build.gradle +++ b/Source/Android/app/build.gradle @@ -144,8 +144,10 @@ dependencies { implementation 'androidx.preference:preference:1.2.0' implementation 'androidx.profileinstaller:profileinstaller:1.2.2' - // Force dependency version to solve build conflict with androidx preferences - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1" + // Kotlin extensions for lifecycle components + implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1' + implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.5.1' + implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.5.1' // Android TV UI libraries. implementation 'androidx.leanback:leanback:1.0.0' From 410aaef56ec6c962659eabef9269050a0f179f26 Mon Sep 17 00:00:00 2001 From: Charles Lombardo Date: Thu, 26 Jan 2023 12:57:00 -0500 Subject: [PATCH 08/11] Android: Remove orientation lock on system update dialog --- .../sysupdate/ui/SystemUpdateProgressBarDialogFragment.kt | 7 ------- 1 file changed, 7 deletions(-) diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/SystemUpdateProgressBarDialogFragment.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/SystemUpdateProgressBarDialogFragment.kt index 6ff5f4d4f2..8ecc914318 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/SystemUpdateProgressBarDialogFragment.kt +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/SystemUpdateProgressBarDialogFragment.kt @@ -16,11 +16,6 @@ import org.dolphinemu.dolphinemu.databinding.DialogProgressTvBinding class SystemUpdateProgressBarDialogFragment : DialogFragment() { override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { - // Store the current orientation to be restored later - val orientation = requireActivity().requestedOrientation - // Rotating the device while the update is running can result in a title failing to import. - requireActivity().requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LOCKED - val viewModel = ViewModelProvider(requireActivity())[SystemUpdateViewModel::class.java] val dialogProgressBinding: DialogProgressBinding @@ -83,8 +78,6 @@ class SystemUpdateProgressBarDialogFragment : DialogFragment() { val progressBarFragment = SystemUpdateResultFragment() progressBarFragment.show(parentFragmentManager, "OnlineUpdateResultFragment") - requireActivity().requestedOrientation = orientation - dismiss() } From 917ca2273e8233e78f5c3c84763385e352f7cac2 Mon Sep 17 00:00:00 2001 From: Charles Lombardo Date: Thu, 26 Jan 2023 13:02:53 -0500 Subject: [PATCH 09/11] Android: Remove hardcoded strings from system update dialogs --- .../ui/OnlineUpdateRegionSelectDialogFragment.kt | 6 +++++- .../ui/SystemMenuNotInstalledDialogFragment.kt | 6 +++++- .../ui/SystemUpdateProgressBarDialogFragment.kt | 6 +++++- .../sysupdate/ui/SystemUpdateResultFragment.kt | 10 ++++++++-- .../dolphinemu/dolphinemu/ui/main/MainPresenter.java | 2 +- 5 files changed, 24 insertions(+), 6 deletions(-) diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/OnlineUpdateRegionSelectDialogFragment.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/OnlineUpdateRegionSelectDialogFragment.kt index 1e3b7235da..ef41c2a034 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/OnlineUpdateRegionSelectDialogFragment.kt +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/OnlineUpdateRegionSelectDialogFragment.kt @@ -27,10 +27,14 @@ class OnlineUpdateRegionSelectDialogFragment : DialogFragment() { viewModel.region = which SystemUpdateProgressBarDialogFragment().show( parentFragmentManager, - "OnlineUpdateProgressBarDialogFragment" + SystemUpdateProgressBarDialogFragment.TAG ) dismiss() } .create() } + + companion object { + const val TAG = "OnlineUpdateRegionSelectDialogFragment" + } } diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/SystemMenuNotInstalledDialogFragment.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/SystemMenuNotInstalledDialogFragment.kt index 396c60b8d8..9dfb328738 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/SystemMenuNotInstalledDialogFragment.kt +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/SystemMenuNotInstalledDialogFragment.kt @@ -17,11 +17,15 @@ class SystemMenuNotInstalledDialogFragment : DialogFragment() { .setPositiveButton(R.string.yes) { _: DialogInterface?, _: Int -> OnlineUpdateRegionSelectDialogFragment().show( parentFragmentManager, - "OnlineUpdateRegionSelectDialogFragment" + OnlineUpdateRegionSelectDialogFragment.TAG ) dismiss() } .setNegativeButton(R.string.no) { _: DialogInterface?, _: Int -> dismiss() } .create() } + + companion object { + const val TAG = "SystemMenuNotInstalledDialogFragment" + } } diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/SystemUpdateProgressBarDialogFragment.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/SystemUpdateProgressBarDialogFragment.kt index 8ecc914318..842757eea1 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/SystemUpdateProgressBarDialogFragment.kt +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/SystemUpdateProgressBarDialogFragment.kt @@ -76,7 +76,7 @@ class SystemUpdateProgressBarDialogFragment : DialogFragment() { } val progressBarFragment = SystemUpdateResultFragment() - progressBarFragment.show(parentFragmentManager, "OnlineUpdateResultFragment") + progressBarFragment.show(parentFragmentManager, SystemUpdateResultFragment.TAG) dismiss() } @@ -100,4 +100,8 @@ class SystemUpdateProgressBarDialogFragment : DialogFragment() { viewModel.setCanceled() } } + + companion object { + const val TAG = "SystemUpdateProgressBarDialogFragment" + } } diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/SystemUpdateResultFragment.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/SystemUpdateResultFragment.kt index 352e6cd47a..a6af39e6b4 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/SystemUpdateResultFragment.kt +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/SystemUpdateResultFragment.kt @@ -12,6 +12,8 @@ import org.dolphinemu.dolphinemu.R import org.dolphinemu.dolphinemu.utils.WiiUtils class SystemUpdateResultFragment : DialogFragment() { + private val resultKey = "result" + private var mResult = 0 override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { @@ -20,7 +22,7 @@ class SystemUpdateResultFragment : DialogFragment() { mResult = viewModel.resultData.value!!.toInt() viewModel.clear() } else { - mResult = savedInstanceState.getInt("result") + mResult = savedInstanceState.getInt(resultKey) } val message: String = when (mResult) { WiiUtils.UPDATE_RESULT_SUCCESS -> getString(R.string.update_success) @@ -56,6 +58,10 @@ class SystemUpdateResultFragment : DialogFragment() { override fun onSaveInstanceState(outState: Bundle) { super.onSaveInstanceState(outState) - outState.putInt("result", mResult) + outState.putInt(resultKey, mResult) + } + + companion object { + const val TAG = "SystemUpdateResultFragment" } } 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 2e5d9c617f..b36a9ced2b 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 @@ -319,7 +319,7 @@ public final class MainPresenter SystemUpdateProgressBarDialogFragment progressBarFragment = new SystemUpdateProgressBarDialogFragment(); progressBarFragment - .show(activity.getSupportFragmentManager(), "SystemUpdateProgressBarDialogFragment"); + .show(activity.getSupportFragmentManager(), SystemUpdateProgressBarDialogFragment.TAG); progressBarFragment.setCancelable(false); } From d66d8210bf67435085cb03bd96752683cbb19083 Mon Sep 17 00:00:00 2001 From: Charles Lombardo Date: Thu, 26 Jan 2023 13:06:48 -0500 Subject: [PATCH 10/11] Android: Switch to indeterminate progress bar on system update cancel --- .../SystemUpdateProgressBarDialogFragment.kt | 37 +++++++++++-------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/SystemUpdateProgressBarDialogFragment.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/SystemUpdateProgressBarDialogFragment.kt index 842757eea1..a02e210a9c 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/SystemUpdateProgressBarDialogFragment.kt +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/SystemUpdateProgressBarDialogFragment.kt @@ -3,7 +3,6 @@ package org.dolphinemu.dolphinemu.features.sysupdate.ui import android.app.Dialog -import android.content.pm.ActivityInfo import android.os.Bundle import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AppCompatActivity @@ -15,11 +14,13 @@ import org.dolphinemu.dolphinemu.databinding.DialogProgressBinding import org.dolphinemu.dolphinemu.databinding.DialogProgressTvBinding class SystemUpdateProgressBarDialogFragment : DialogFragment() { - override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { - val viewModel = ViewModelProvider(requireActivity())[SystemUpdateViewModel::class.java] + private lateinit var viewModel: SystemUpdateViewModel - val dialogProgressBinding: DialogProgressBinding - val dialogProgressTvBinding: DialogProgressTvBinding + private lateinit var binding: DialogProgressBinding + private lateinit var bindingTv: DialogProgressTvBinding + + override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { + viewModel = ViewModelProvider(requireActivity())[SystemUpdateViewModel::class.java] // We need to set the message to something here, otherwise the text will not appear when we set it later. val progressDialogBuilder = MaterialAlertDialogBuilder(requireContext()) @@ -30,36 +31,36 @@ class SystemUpdateProgressBarDialogFragment : DialogFragment() { // TODO: Remove dialog_progress_tv if we switch to an AppCompatActivity for leanback if (activity is AppCompatActivity) { - dialogProgressBinding = DialogProgressBinding.inflate(layoutInflater) - progressDialogBuilder.setView(dialogProgressBinding.root) + binding = DialogProgressBinding.inflate(layoutInflater) + progressDialogBuilder.setView(binding.root) viewModel.progressData.observe( this ) { progress: Int -> - dialogProgressBinding.updateProgress.progress = progress + binding.updateProgress.progress = progress } viewModel.totalData.observe(this) { total: Int -> if (total == 0) { return@observe } - dialogProgressBinding.updateProgress.max = total + binding.updateProgress.max = total } } else { - dialogProgressTvBinding = DialogProgressTvBinding.inflate(layoutInflater) - progressDialogBuilder.setView(dialogProgressTvBinding.root) + bindingTv = DialogProgressTvBinding.inflate(layoutInflater) + progressDialogBuilder.setView(bindingTv.root) viewModel.progressData.observe( this ) { progress: Int -> - dialogProgressTvBinding.updateProgress.progress = progress + bindingTv.updateProgress.progress = progress } viewModel.totalData.observe(this) { total: Int -> if (total == 0) { return@observe } - dialogProgressTvBinding.updateProgress.max = total + bindingTv.updateProgress.max = total } } @@ -91,13 +92,17 @@ class SystemUpdateProgressBarDialogFragment : DialogFragment() { // Setting the OnClickListener again after the dialog is shown overrides this behavior. override fun onResume() { super.onResume() - val alertDialog = dialog as AlertDialog? - val viewModel = ViewModelProvider(requireActivity())[SystemUpdateViewModel::class.java] - val negativeButton = alertDialog!!.getButton(Dialog.BUTTON_NEGATIVE) + val alertDialog = dialog as AlertDialog + val negativeButton = alertDialog.getButton(Dialog.BUTTON_NEGATIVE) negativeButton.setOnClickListener { alertDialog.setTitle(getString(R.string.cancelling)) alertDialog.setMessage(getString(R.string.update_cancelling)) viewModel.setCanceled() + + if (activity is AppCompatActivity) + binding.updateProgress.isIndeterminate = true + else + bindingTv.updateProgress.isIndeterminate = true } } From 75ce7a04caaae0a9e1ca9083b35442fb6a9f7adb Mon Sep 17 00:00:00 2001 From: Charles Lombardo Date: Thu, 26 Jan 2023 13:13:25 -0500 Subject: [PATCH 11/11] Android: Use coroutine for system updates --- .../sysupdate/ui/SystemUpdateViewModel.kt | 54 ++++++++++--------- 1 file changed, 29 insertions(+), 25 deletions(-) diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/SystemUpdateViewModel.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/SystemUpdateViewModel.kt index dacc51221d..7dc53d83bd 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/SystemUpdateViewModel.kt +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/SystemUpdateViewModel.kt @@ -4,9 +4,12 @@ package org.dolphinemu.dolphinemu.features.sysupdate.ui import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext import org.dolphinemu.dolphinemu.utils.WiiUpdateCallback import org.dolphinemu.dolphinemu.utils.WiiUtils -import java.util.concurrent.Executors class SystemUpdateViewModel : ViewModel() { val progressData = MutableLiveData() @@ -14,6 +17,7 @@ class SystemUpdateViewModel : ViewModel() { val titleIdData = MutableLiveData() val resultData = MutableLiveData() + private var isRunning = false private var canceled = false var region = -1 var discPath: String = "" @@ -27,34 +31,38 @@ class SystemUpdateViewModel : ViewModel() { } fun startUpdate() { - if (discPath.isNotEmpty()) { - startDiscUpdate(discPath) - } else { - val region: String = when (this.region) { - 0 -> "EUR" - 1 -> "JPN" - 2 -> "KOR" - 3 -> "USA" - else -> "" + if (isRunning) return + isRunning = true + + viewModelScope.launch { + withContext(Dispatchers.IO) { + if (discPath.isNotEmpty()) { + startDiscUpdate(discPath) + } else { + val region: String = when (region) { + 0 -> "EUR" + 1 -> "JPN" + 2 -> "KOR" + 3 -> "USA" + else -> "" + } + startOnlineUpdate(region) + } + isRunning = false } - startOnlineUpdate(region) } } - private fun startOnlineUpdate(region: String?) { + private fun startOnlineUpdate(region: String) { canceled = false - executor.execute { - val result = WiiUtils.doOnlineUpdate(region, constructCallback()) - resultData.postValue(result) - } + val result = WiiUtils.doOnlineUpdate(region, constructCallback()) + resultData.postValue(result) } - private fun startDiscUpdate(path: String?) { + private fun startDiscUpdate(path: String) { canceled = false - executor.execute { - val result = WiiUtils.doDiscUpdate(path, constructCallback()) - resultData.postValue(result) - } + val result = WiiUtils.doDiscUpdate(path, constructCallback()) + resultData.postValue(result) } fun clear() { @@ -72,8 +80,4 @@ class SystemUpdateViewModel : ViewModel() { !canceled } } - - companion object { - private val executor = Executors.newFixedThreadPool(1) - } }