From a8274863917c8941d296361f46779a98377e7337 Mon Sep 17 00:00:00 2001 From: Charles Lombardo Date: Tue, 4 Apr 2023 04:03:55 -0400 Subject: [PATCH] android: Remove LocalBroadcastManager This causes a couple of minor changes to directory initialization. We don't have a lengthy initialization step so we could spend less time creating state receivers and just run initialization on the main thread. We also don't have a situation where external storage will be a concern so checks are removed in favor of a binary check to see if initialization is ready. This additionally removes the unused DoFrame callback. --- src/android/app/build.gradle | 1 - .../java/org/yuzu/yuzu_emu/NativeLibrary.java | 2 - .../features/settings/ui/SettingsActivity.kt | 47 --------------- .../settings/ui/SettingsActivityPresenter.kt | 32 ++-------- .../settings/ui/SettingsActivityView.kt | 35 ----------- .../yuzu_emu/fragments/EmulationFragment.kt | 60 ++----------------- .../org/yuzu/yuzu_emu/ui/main/MainActivity.kt | 2 +- .../yuzu_emu/utils/DirectoryInitialization.kt | 41 ++----------- .../yuzu_emu/utils/DirectoryStateReceiver.kt | 18 ------ src/android/app/src/main/jni/native.cpp | 2 - .../app/src/main/res/values/strings.xml | 2 - 11 files changed, 17 insertions(+), 225 deletions(-) delete mode 100644 src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/DirectoryStateReceiver.kt diff --git a/src/android/app/build.gradle b/src/android/app/build.gradle index a82d2706b..221232712 100644 --- a/src/android/app/build.gradle +++ b/src/android/app/build.gradle @@ -142,7 +142,6 @@ dependencies { implementation 'androidx.window:window:1.0.0' implementation 'org.ini4j:ini4j:0.5.4' implementation 'androidx.constraintlayout:constraintlayout:2.1.4' - implementation 'androidx.localbroadcastmanager:localbroadcastmanager:1.1.0' implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0' } diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/NativeLibrary.java b/src/android/app/src/main/java/org/yuzu/yuzu_emu/NativeLibrary.java index 5def17f2b..50ec34e22 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/NativeLibrary.java +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/NativeLibrary.java @@ -218,8 +218,6 @@ public final class NativeLibrary { public static native void SurfaceDestroyed(); - public static native void DoFrame(); - /** * Unpauses emulation from a paused state. */ diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsActivity.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsActivity.kt index 60858ecd6..a655500f8 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsActivity.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsActivity.kt @@ -5,31 +5,25 @@ package org.yuzu.yuzu_emu.features.settings.ui import android.content.Context import android.content.Intent -import android.content.IntentFilter import android.os.Bundle import android.view.Menu import android.view.View import android.widget.Toast import androidx.activity.viewModels -import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AppCompatActivity import androidx.core.view.ViewCompat import androidx.core.view.WindowCompat import androidx.core.view.WindowInsetsCompat import androidx.core.view.updatePadding -import androidx.localbroadcastmanager.content.LocalBroadcastManager -import com.google.android.material.dialog.MaterialAlertDialogBuilder import org.yuzu.yuzu_emu.NativeLibrary import org.yuzu.yuzu_emu.R import org.yuzu.yuzu_emu.databinding.ActivitySettingsBinding -import org.yuzu.yuzu_emu.databinding.DialogProgressBarBinding import org.yuzu.yuzu_emu.features.settings.model.Settings import org.yuzu.yuzu_emu.features.settings.model.SettingsViewModel import org.yuzu.yuzu_emu.utils.* class SettingsActivity : AppCompatActivity(), SettingsActivityView { private val presenter = SettingsActivityPresenter(this) - private var dialog: AlertDialog? = null private lateinit var binding: ActivitySettingsBinding @@ -134,47 +128,6 @@ class SettingsActivity : AppCompatActivity(), SettingsActivityView { return duration != 0f && transition != 0f } - override fun startDirectoryInitializationService( - receiver: DirectoryStateReceiver?, - filter: IntentFilter - ) { - LocalBroadcastManager.getInstance(this).registerReceiver( - receiver!!, - filter - ) - DirectoryInitialization.start(this) - } - - override fun stopListeningToDirectoryInitializationService(receiver: DirectoryStateReceiver) { - LocalBroadcastManager.getInstance(this).unregisterReceiver(receiver) - } - - override fun showLoading() { - if (dialog == null) { - val loadingBinding = DialogProgressBarBinding.inflate(layoutInflater) - loadingBinding.progressBar.isIndeterminate = true - - dialog = MaterialAlertDialogBuilder(this) - .setTitle(R.string.load_settings) - .setView(loadingBinding.root) - .setCancelable(false) - .create() - } - dialog!!.show() - } - - override fun hideLoading() { - dialog!!.dismiss() - } - - override fun showExternalStorageNotMountedHint() { - Toast.makeText( - this, - R.string.external_storage_not_mounted, - Toast.LENGTH_SHORT - ).show() - } - override fun onSettingsFileLoaded() { val fragment: SettingsFragmentView? = settingsFragment fragment?.loadSettingsList() diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsActivityPresenter.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsActivityPresenter.kt index 2a86e4463..8c90156e3 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsActivityPresenter.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsActivityPresenter.kt @@ -3,15 +3,13 @@ package org.yuzu.yuzu_emu.features.settings.ui -import android.content.IntentFilter +import android.content.Context import android.os.Bundle import android.text.TextUtils import org.yuzu.yuzu_emu.NativeLibrary import org.yuzu.yuzu_emu.features.settings.model.Settings import org.yuzu.yuzu_emu.features.settings.utils.SettingsFile import org.yuzu.yuzu_emu.utils.DirectoryInitialization -import org.yuzu.yuzu_emu.utils.DirectoryInitialization.DirectoryInitializationState -import org.yuzu.yuzu_emu.utils.DirectoryStateReceiver import org.yuzu.yuzu_emu.utils.Log import java.io.File @@ -19,7 +17,6 @@ class SettingsActivityPresenter(private val activityView: SettingsActivityView) val settings: Settings get() = activityView.settings private var shouldSave = false - private var directoryStateReceiver: DirectoryStateReceiver? = null private lateinit var menuTag: String private lateinit var gameId: String @@ -54,33 +51,14 @@ class SettingsActivityPresenter(private val activityView: SettingsActivityView) Log.error(DirectoryInitialization.userDirectory + "/config/" + SettingsFile.FILE_NAME_CONFIG + ".ini") Log.error("yuzu config file could not be found!") } - if (DirectoryInitialization.areDirectoriesReady()) { - loadSettingsUI() - } else { - activityView.showLoading() - val statusIntentFilter = IntentFilter(DirectoryInitialization.BROADCAST_ACTION) - directoryStateReceiver = - DirectoryStateReceiver { directoryInitializationState: DirectoryInitializationState -> - if (directoryInitializationState == DirectoryInitializationState.YUZU_DIRECTORIES_INITIALIZED) { - activityView.hideLoading() - loadSettingsUI() - } else if (directoryInitializationState == DirectoryInitializationState.CANT_FIND_EXTERNAL_STORAGE) { - activityView.showExternalStorageNotMountedHint() - activityView.hideLoading() - } - } - activityView.startDirectoryInitializationService( - directoryStateReceiver, - statusIntentFilter - ) + + if (!DirectoryInitialization.areDirectoriesReady) { + DirectoryInitialization.start(activityView as Context) } + loadSettingsUI() } fun onStop(finishing: Boolean) { - if (directoryStateReceiver != null) { - activityView.stopListeningToDirectoryInitializationService(directoryStateReceiver!!) - directoryStateReceiver = null - } if (finishing && shouldSave) { Log.debug("[SettingsActivity] Settings activity stopping. Saving settings to INI...") settings.saveSettings(activityView) diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsActivityView.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsActivityView.kt index 2b6dd2fce..c186fc388 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsActivityView.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsActivityView.kt @@ -3,9 +3,7 @@ package org.yuzu.yuzu_emu.features.settings.ui -import android.content.IntentFilter import org.yuzu.yuzu_emu.features.settings.model.Settings -import org.yuzu.yuzu_emu.utils.DirectoryStateReceiver /** * Abstraction for the Activity that manages SettingsFragments. @@ -56,37 +54,4 @@ interface SettingsActivityView { * unless this has been called, the Activity will not save to disk. */ fun onSettingChanged() - - /** - * Show loading dialog while loading the settings - */ - fun showLoading() - - /** - * Hide the loading the dialog - */ - fun hideLoading() - - /** - * Show a hint to the user that the app needs the external storage to be mounted - */ - fun showExternalStorageNotMountedHint() - - /** - * Start the DirectoryInitialization and listen for the result. - * - * @param receiver the broadcast receiver for the DirectoryInitialization - * @param filter the Intent broadcasts to be received. - */ - fun startDirectoryInitializationService( - receiver: DirectoryStateReceiver?, - filter: IntentFilter - ) - - /** - * Stop listening to the DirectoryInitialization. - * - * @param receiver The broadcast receiver to unregister. - */ - fun stopListeningToDirectoryInitializationService(receiver: DirectoryStateReceiver) } 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 703d4623b..daee937ca 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 @@ -4,14 +4,13 @@ package org.yuzu.yuzu_emu.fragments import android.content.Context -import android.content.IntentFilter import android.content.SharedPreferences import android.graphics.Color import android.os.Bundle import android.os.Handler +import android.os.Looper import android.view.* import android.widget.TextView -import android.widget.Toast import androidx.activity.OnBackPressedCallback import androidx.appcompat.widget.PopupMenu import androidx.core.content.res.ResourcesCompat @@ -19,7 +18,6 @@ import androidx.core.graphics.Insets import androidx.core.view.ViewCompat import androidx.core.view.WindowInsetsCompat import androidx.fragment.app.Fragment -import androidx.localbroadcastmanager.content.LocalBroadcastManager import androidx.preference.PreferenceManager import com.google.android.material.dialog.MaterialAlertDialogBuilder import org.yuzu.yuzu_emu.NativeLibrary @@ -32,13 +30,11 @@ import org.yuzu.yuzu_emu.features.settings.ui.SettingsActivity import org.yuzu.yuzu_emu.features.settings.utils.SettingsFile import org.yuzu.yuzu_emu.model.Game import org.yuzu.yuzu_emu.utils.* -import org.yuzu.yuzu_emu.utils.DirectoryInitialization.DirectoryInitializationState import org.yuzu.yuzu_emu.utils.SerializableHelper.parcelable -class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.FrameCallback { +class EmulationFragment : Fragment(), SurfaceHolder.Callback { private lateinit var preferences: SharedPreferences private lateinit var emulationState: EmulationState - private var directoryStateReceiver: DirectoryStateReceiver? = null private var emulationActivity: EmulationActivity? = null private var perfStatsUpdater: (() -> Unit)? = null @@ -144,25 +140,16 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram override fun onResume() { super.onResume() - Choreographer.getInstance().postFrameCallback(this) - if (DirectoryInitialization.areDirectoriesReady()) { - emulationState.run(emulationActivity!!.isActivityRecreated) - } else { - setupDirectoriesThenStartEmulation() + if (!DirectoryInitialization.areDirectoriesReady) { + DirectoryInitialization.start(requireContext()) } + emulationState.run(emulationActivity!!.isActivityRecreated) } override fun onPause() { - if (directoryStateReceiver != null) { - LocalBroadcastManager.getInstance(requireActivity()).unregisterReceiver( - directoryStateReceiver!! - ) - directoryStateReceiver = null - } if (emulationState.isRunning) { emulationState.pause() } - Choreographer.getInstance().removeFrameCallback(this) super.onPause() } @@ -176,36 +163,6 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram super.onDetach() } - private fun setupDirectoriesThenStartEmulation() { - val statusIntentFilter = IntentFilter( - DirectoryInitialization.BROADCAST_ACTION - ) - directoryStateReceiver = - DirectoryStateReceiver { directoryInitializationState: DirectoryInitializationState -> - if (directoryInitializationState == - DirectoryInitializationState.YUZU_DIRECTORIES_INITIALIZED - ) { - emulationState.run(emulationActivity!!.isActivityRecreated) - } else if (directoryInitializationState == - DirectoryInitializationState.CANT_FIND_EXTERNAL_STORAGE - ) { - Toast.makeText( - context, - R.string.external_storage_not_mounted, - Toast.LENGTH_SHORT - ) - .show() - } - } - - // Registers the DirectoryStateReceiver and its intent filters - LocalBroadcastManager.getInstance(requireActivity()).registerReceiver( - directoryStateReceiver!!, - statusIntentFilter - ) - DirectoryInitialization.start(requireContext()) - } - fun refreshInputOverlay() { binding.surfaceInputOverlay.refreshControls() } @@ -259,11 +216,6 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram emulationState.clearSurface() } - override fun doFrame(frameTimeNanos: Long) { - Choreographer.getInstance().postFrameCallback(this) - NativeLibrary.DoFrame() - } - private fun showOverlayOptions() { val anchor = binding.inGameMenu.findViewById(R.id.menu_overlay_controls) val popup = PopupMenu(requireContext(), anchor) @@ -474,7 +426,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram } companion object { - private val perfStatsUpdateHandler = Handler() + private val perfStatsUpdateHandler = Handler(Looper.myLooper()!!) fun newInstance(game: Game): EmulationFragment { val args = 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 4885bc4bc..b6ad72591 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 @@ -41,7 +41,7 @@ class MainActivity : AppCompatActivity(), MainView { override fun onCreate(savedInstanceState: Bundle?) { val splashScreen = installSplashScreen() - splashScreen.setKeepOnScreenCondition { !DirectoryInitialization.areDirectoriesReady() } + splashScreen.setKeepOnScreenCondition { !DirectoryInitialization.areDirectoriesReady } ThemeHelper.setTheme(this) diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/DirectoryInitialization.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/DirectoryInitialization.kt index a02d8fb01..7b66bf220 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/DirectoryInitialization.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/DirectoryInitialization.kt @@ -4,46 +4,26 @@ package org.yuzu.yuzu_emu.utils import android.content.Context -import android.content.Intent -import androidx.localbroadcastmanager.content.LocalBroadcastManager import org.yuzu.yuzu_emu.NativeLibrary import java.io.IOException -import java.util.concurrent.atomic.AtomicBoolean object DirectoryInitialization { - const val BROADCAST_ACTION = "org.yuzu.yuzu_emu.BROADCAST" - const val EXTRA_STATE = "directoryState" - - @Volatile - private var directoryState: DirectoryInitializationState? = null private var userPath: String? = null - private val isDirectoryInitializationRunning = AtomicBoolean(false) + + var areDirectoriesReady: Boolean = false @JvmStatic fun start(context: Context) { - // Can take a few seconds to run, so don't block UI thread. - Runnable { init(context) }.run() - } - - private fun init(context: Context) { - if (!isDirectoryInitializationRunning.compareAndSet(false, true)) return - if (directoryState != DirectoryInitializationState.YUZU_DIRECTORIES_INITIALIZED) { + if (!areDirectoriesReady) { initializeInternalStorage(context) NativeLibrary.InitializeEmulation() - directoryState = DirectoryInitializationState.YUZU_DIRECTORIES_INITIALIZED + areDirectoriesReady = true } - isDirectoryInitializationRunning.set(false) - sendBroadcastState(directoryState, context) - } - - fun areDirectoriesReady(): Boolean { - return directoryState == DirectoryInitializationState.YUZU_DIRECTORIES_INITIALIZED } val userDirectory: String? get() { - checkNotNull(directoryState) { "DirectoryInitialization has to run at least once!" } - check(!isDirectoryInitializationRunning.get()) { "DirectoryInitialization has to finish running first!" } + check(areDirectoriesReady) { "Directory initialization is not ready!" } return userPath } @@ -55,15 +35,4 @@ object DirectoryInitialization { e.printStackTrace() } } - - private fun sendBroadcastState(state: DirectoryInitializationState?, context: Context) { - val localIntent = Intent(BROADCAST_ACTION) - .putExtra(EXTRA_STATE, state) - LocalBroadcastManager.getInstance(context).sendBroadcast(localIntent) - } - - enum class DirectoryInitializationState { - YUZU_DIRECTORIES_INITIALIZED, - CANT_FIND_EXTERNAL_STORAGE - } } diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/DirectoryStateReceiver.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/DirectoryStateReceiver.kt deleted file mode 100644 index 06e00cfc8..000000000 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/DirectoryStateReceiver.kt +++ /dev/null @@ -1,18 +0,0 @@ -// SPDX-FileCopyrightText: 2023 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -package org.yuzu.yuzu_emu.utils - -import android.content.BroadcastReceiver -import android.content.Context -import android.content.Intent -import org.yuzu.yuzu_emu.utils.DirectoryInitialization.DirectoryInitializationState - -class DirectoryStateReceiver(var callback: (DirectoryInitializationState) -> Unit) : - BroadcastReceiver() { - override fun onReceive(context: Context, intent: Intent) { - val state = intent - .getSerializableExtra(DirectoryInitialization.EXTRA_STATE) as DirectoryInitializationState - callback.invoke(state) - } -} diff --git a/src/android/app/src/main/jni/native.cpp b/src/android/app/src/main/jni/native.cpp index 86994f734..ce713b80f 100644 --- a/src/android/app/src/main/jni/native.cpp +++ b/src/android/app/src/main/jni/native.cpp @@ -367,8 +367,6 @@ void Java_org_yuzu_yuzu_1emu_NativeLibrary_SurfaceDestroyed(JNIEnv* env, EmulationSession::GetInstance().SurfaceChanged(); } -void Java_org_yuzu_yuzu_1emu_NativeLibrary_DoFrame(JNIEnv* env, [[maybe_unused]] jclass clazz) {} - void Java_org_yuzu_yuzu_1emu_NativeLibrary_NotifyOrientationChange(JNIEnv* env, [[maybe_unused]] jclass clazz, jint layout_option, diff --git a/src/android/app/src/main/res/values/strings.xml b/src/android/app/src/main/res/values/strings.xml index 29c1b1691..98a06c45d 100644 --- a/src/android/app/src/main/res/values/strings.xml +++ b/src/android/app/src/main/res/values/strings.xml @@ -98,8 +98,6 @@ Loading Settingsā€¦ - The external storage needs to be available in order to use yuzu - No files were found or no game directory has been selected yet.