From 0fdd6e893460472766b92ce01acbe7755acb7bc0 Mon Sep 17 00:00:00 2001
From: t895 <clombardo169@gmail.com>
Date: Thu, 25 Jan 2024 07:05:36 -0500
Subject: [PATCH] android: Fix waiting for driver install on startup

---
 .../yuzu_emu/fragments/EmulationFragment.kt   | 35 ++++++++++++-------
 .../yuzu/yuzu_emu/model/DriverViewModel.kt    |  1 +
 src/android/app/src/main/jni/native.cpp       |  1 +
 3 files changed, 24 insertions(+), 13 deletions(-)

diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.kt
index 82f8e3b50..d17e087fe 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.kt
@@ -38,7 +38,6 @@ import androidx.window.layout.WindowLayoutInfo
 import com.google.android.material.dialog.MaterialAlertDialogBuilder
 import com.google.android.material.slider.Slider
 import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.flow.collect
 import kotlinx.coroutines.flow.collectLatest
 import kotlinx.coroutines.launch
 import org.yuzu.yuzu_emu.HomeNavigationDirections
@@ -141,7 +140,9 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
 
         // So this fragment doesn't restart on configuration changes; i.e. rotation.
         retainInstance = true
-        emulationState = EmulationState(game.path)
+        emulationState = EmulationState(game.path) {
+            return@EmulationState driverViewModel.isInteractionAllowed.value
+        }
     }
 
     /**
@@ -370,6 +371,15 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
                     }
                 }
             }
+            launch {
+                repeatOnLifecycle(Lifecycle.State.RESUMED) {
+                    driverViewModel.isInteractionAllowed.collect {
+                        if (it) {
+                            startEmulation()
+                        }
+                    }
+                }
+            }
             launch {
                 repeatOnLifecycle(Lifecycle.State.CREATED) {
                     emulationViewModel.emulationStarted.collectLatest {
@@ -398,19 +408,10 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
                     }
                 }
             }
-            launch {
-                repeatOnLifecycle(Lifecycle.State.RESUMED) {
-                    driverViewModel.isInteractionAllowed.collect {
-                        if (it) {
-                            onEmulationStart()
-                        }
-                    }
-                }
-            }
         }
     }
 
-    private fun onEmulationStart() {
+    private fun startEmulation() {
         if (!NativeLibrary.isRunning() && !NativeLibrary.isPaused()) {
             if (!DirectoryInitialization.areDirectoriesReady) {
                 DirectoryInitialization.start()
@@ -810,7 +811,10 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
         }
     }
 
-    private class EmulationState(private val gamePath: String) {
+    private class EmulationState(
+        private val gamePath: String,
+        private val emulationCanStart: () -> Boolean
+    ) {
         private var state: State
         private var surface: Surface? = null
 
@@ -904,6 +908,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
                     State.PAUSED -> Log.warning(
                         "[EmulationFragment] Surface cleared while emulation paused."
                     )
+
                     else -> Log.warning(
                         "[EmulationFragment] Surface cleared while emulation stopped."
                     )
@@ -913,6 +918,10 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
 
         private fun runWithValidSurface() {
             NativeLibrary.surfaceChanged(surface)
+            if (!emulationCanStart.invoke()) {
+                return
+            }
+
             when (state) {
                 State.STOPPED -> {
                     val emulationThread = Thread({
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/model/DriverViewModel.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/model/DriverViewModel.kt
index 15ae3a42b..5ed754c96 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/model/DriverViewModel.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/model/DriverViewModel.kt
@@ -144,6 +144,7 @@ class DriverViewModel : ViewModel() {
         val selectedDriverFile = File(StringSetting.DRIVER_PATH.getString())
         val selectedDriverMetadata = GpuDriverHelper.customDriverSettingData
         if (GpuDriverHelper.installedCustomDriverData == selectedDriverMetadata) {
+            setDriverReady()
             return
         }
 
diff --git a/src/android/app/src/main/jni/native.cpp b/src/android/app/src/main/jni/native.cpp
index c6c55b20c..c20c2d2b8 100644
--- a/src/android/app/src/main/jni/native.cpp
+++ b/src/android/app/src/main/jni/native.cpp
@@ -247,6 +247,7 @@ Core::SystemResultStatus EmulationSession::InitializeEmulation(const std::string
     m_system.GetCpuManager().OnGpuReady();
     m_system.RegisterExitCallback([&] { HaltEmulation(); });
 
+    OnEmulationStarted();
     return Core::SystemResultStatus::Success;
 }