From a49a24b07958959ef08316f9160531cc5885a1a8 Mon Sep 17 00:00:00 2001
From: Charles Lombardo <clombardo169@gmail.com>
Date: Mon, 20 Mar 2023 01:44:22 -0400
Subject: [PATCH] android: Move driver installation off of main thread

Additionally creates an indeterminate loading dialog during installation
---
 .../org/yuzu/yuzu_emu/ui/main/MainActivity.kt | 54 ++++++++++++++-----
 .../yuzu/yuzu_emu/utils/GpuDriverHelper.kt    |  7 +--
 .../yuzu/yuzu_emu/utils/GpuDriverMetadata.kt  |  1 -
 .../app/src/main/res/values/strings.xml       |  1 +
 4 files changed, 42 insertions(+), 21 deletions(-)

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 c5259a13d..dd8750c4f 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
@@ -17,15 +17,21 @@ import androidx.core.view.ViewCompat
 import androidx.core.view.WindowCompat
 import androidx.core.view.WindowInsetsCompat
 import androidx.core.view.updatePadding
+import androidx.lifecycle.lifecycleScope
 import com.google.android.material.dialog.MaterialAlertDialogBuilder
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
 import org.yuzu.yuzu_emu.NativeLibrary
 import org.yuzu.yuzu_emu.R
 import org.yuzu.yuzu_emu.activities.EmulationActivity
 import org.yuzu.yuzu_emu.databinding.ActivityMainBinding
+import org.yuzu.yuzu_emu.databinding.DialogProgressBarBinding
 import org.yuzu.yuzu_emu.features.settings.ui.SettingsActivity
 import org.yuzu.yuzu_emu.model.GameProvider
 import org.yuzu.yuzu_emu.ui.platform.PlatformGamesFragment
 import org.yuzu.yuzu_emu.utils.*
+import java.io.IOException
 
 class MainActivity : AppCompatActivity(), MainView {
     private var platformGamesFragment: PlatformGamesFragment? = null
@@ -200,20 +206,40 @@ class MainActivity : AppCompatActivity(), MainView {
                     Uri.parse(result!!.dataString),
                     takeFlags
                 )
-                GpuDriverHelper.installCustomDriver(this, result.data)
-                val driverName = GpuDriverHelper.customDriverName
-                if (driverName != null) {
-                    Toast.makeText(
-                        this,
-                        getString(R.string.select_gpu_driver_install_success, driverName),
-                        Toast.LENGTH_SHORT
-                    ).show()
-                } else {
-                    Toast.makeText(
-                        this,
-                        R.string.select_gpu_driver_error,
-                        Toast.LENGTH_LONG
-                    ).show()
+
+                val progressBinding = DialogProgressBarBinding.inflate(layoutInflater)
+                progressBinding.progressBar.isIndeterminate = true
+                val installationDialog = MaterialAlertDialogBuilder(this)
+                    .setTitle(R.string.installing_driver)
+                    .setView(progressBinding.root)
+                    .show()
+
+                lifecycleScope.launch {
+                    withContext(Dispatchers.IO) {
+                        // Ignore file exceptions when a user selects an invalid zip
+                        try {
+                            GpuDriverHelper.installCustomDriver(applicationContext, result.data)
+                        } catch (_: IOException) {}
+
+                        withContext(Dispatchers.Main) {
+                            installationDialog.dismiss()
+
+                            val driverName = GpuDriverHelper.customDriverName
+                            if (driverName != null) {
+                                Toast.makeText(
+                                    applicationContext,
+                                    getString(R.string.select_gpu_driver_install_success, driverName),
+                                    Toast.LENGTH_SHORT
+                                ).show()
+                            } else {
+                                Toast.makeText(
+                                    applicationContext,
+                                    R.string.select_gpu_driver_error,
+                                    Toast.LENGTH_LONG
+                                ).show()
+                            }
+                        }
+                    }
                 }
             }
         }
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/GpuDriverHelper.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/GpuDriverHelper.kt
index bf26ab51e..598c6808b 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/GpuDriverHelper.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/GpuDriverHelper.kt
@@ -98,11 +98,7 @@ object GpuDriverHelper {
         )
 
         // Unzip the driver.
-        try {
-            unzip(driverInstallationPath + DRIVER_INTERNAL_FILENAME, driverInstallationPath!!)
-        } catch (e: IOException) {
-            throw RuntimeException(e)
-        }
+        unzip(driverInstallationPath + DRIVER_INTERNAL_FILENAME, driverInstallationPath!!)
 
         // Initialize the driver parameters.
         initializeDriverParameters(context)
@@ -111,7 +107,6 @@ object GpuDriverHelper {
     // Parse the custom driver metadata to retrieve the name.
     val customDriverName: String?
         get() {
-            // Parse the custom driver metadata to retrieve the name.
             val metadata = GpuDriverMetadata(driverInstallationPath + META_JSON_FILENAME)
             return metadata.name
         }
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/GpuDriverMetadata.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/GpuDriverMetadata.kt
index d3849d138..70bdb4097 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/GpuDriverMetadata.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/GpuDriverMetadata.kt
@@ -29,7 +29,6 @@ class GpuDriverMetadata(metadataFilePath: String) {
             driverVersion = json.getString("driverVersion")
             minApi = json.getInt("minApi")
             libraryName = json.getString("libraryName")
-            Log.info("Guh")
         } catch (e: JSONException) {
             // JSON is malformed, ignore and treat as unsupported metadata.
         } catch (e: IOException) {
diff --git a/src/android/app/src/main/res/values/strings.xml b/src/android/app/src/main/res/values/strings.xml
index fbf8fe9c1..abf75cca8 100644
--- a/src/android/app/src/main/res/values/strings.xml
+++ b/src/android/app/src/main/res/values/strings.xml
@@ -68,6 +68,7 @@
     <string name="select_gpu_driver_use_default">Using default GPU driver</string>
     <string name="select_gpu_driver_error">Invalid driver selected, using system default!</string>
     <string name="system_gpu_driver">System GPU driver</string>
+    <string name="installing_driver">Installing driver…</string>
 
     <!-- Preferences Screen -->
     <string name="preferences_settings">Settings</string>