android: Remove PiP reliance on fragment
This commit is contained in:
		| @@ -282,6 +282,11 @@ object NativeLibrary { | |||||||
|      */ |      */ | ||||||
|     external fun isRunning(): Boolean |     external fun isRunning(): Boolean | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Returns true if emulation is paused. | ||||||
|  |      */ | ||||||
|  |     external fun isPaused(): Boolean | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Returns the performance stats for the current game |      * Returns the performance stats for the current game | ||||||
|      */ |      */ | ||||||
|   | |||||||
| @@ -271,8 +271,7 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener { | |||||||
|         val pictureInPictureActions : MutableList<RemoteAction> = mutableListOf() |         val pictureInPictureActions : MutableList<RemoteAction> = mutableListOf() | ||||||
|         val pendingFlags = PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE |         val pendingFlags = PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE | ||||||
|  |  | ||||||
|         val isEmulationPaused = emulationFragment?.isEmulationStatePaused() ?: false |         if (NativeLibrary.isPaused()) { | ||||||
|         if (isEmulationPaused) { |  | ||||||
|             val playIcon = Icon.createWithResource(this@EmulationActivity, R.drawable.ic_pip_play) |             val playIcon = Icon.createWithResource(this@EmulationActivity, R.drawable.ic_pip_play) | ||||||
|             val playPendingIntent = PendingIntent.getBroadcast( |             val playPendingIntent = PendingIntent.getBroadcast( | ||||||
|                 this@EmulationActivity, R.drawable.ic_pip_play, Intent(actionPlay), pendingFlags |                 this@EmulationActivity, R.drawable.ic_pip_play, Intent(actionPlay), pendingFlags | ||||||
| @@ -303,9 +302,9 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener { | |||||||
|     private var pictureInPictureReceiver = object : BroadcastReceiver() { |     private var pictureInPictureReceiver = object : BroadcastReceiver() { | ||||||
|         override fun onReceive(context : Context?, intent : Intent) { |         override fun onReceive(context : Context?, intent : Intent) { | ||||||
|             if (intent.action == actionPlay) { |             if (intent.action == actionPlay) { | ||||||
|                 emulationFragment?.onPictureInPicturePlay() |                 if (NativeLibrary.isPaused()) NativeLibrary.unPauseEmulation() | ||||||
|             } else if (intent.action == actionPause) { |             } else if (intent.action == actionPause) { | ||||||
|                 emulationFragment?.onPictureInPicturePause() |                 if (!NativeLibrary.isPaused()) NativeLibrary.pauseEmulation() | ||||||
|             } |             } | ||||||
|             buildPictureInPictureParams() |             buildPictureInPictureParams() | ||||||
|         } |         } | ||||||
| @@ -320,12 +319,10 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener { | |||||||
|             }.also { |             }.also { | ||||||
|                 registerReceiver(pictureInPictureReceiver, it) |                 registerReceiver(pictureInPictureReceiver, it) | ||||||
|             } |             } | ||||||
|             emulationFragment?.onPictureInPictureEnter() |  | ||||||
|         } else { |         } else { | ||||||
|             try { |             try { | ||||||
|                 unregisterReceiver(pictureInPictureReceiver) |                 unregisterReceiver(pictureInPictureReceiver) | ||||||
|             } catch (ignored : Exception) { } |             } catch (ignored : Exception) { } | ||||||
|             emulationFragment?.onPictureInPictureLeave() |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -77,6 +77,14 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback { | |||||||
|             emulationActivity = context |             emulationActivity = context | ||||||
|             NativeLibrary.setEmulationActivity(context) |             NativeLibrary.setEmulationActivity(context) | ||||||
|  |  | ||||||
|  |             lifecycleScope.launch(Dispatchers.Main) { | ||||||
|  |                 lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) { | ||||||
|  |                     WindowInfoTracker.getOrCreate(context) | ||||||
|  |                         .windowLayoutInfo(context) | ||||||
|  |                         .collect { updateFoldableLayout(context, it) } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |  | ||||||
|             onReturnFromSettings = context.activityResultRegistry.register( |             onReturnFromSettings = context.activityResultRegistry.register( | ||||||
|                 "SettingsResult", ActivityResultContracts.StartActivityForResult() |                 "SettingsResult", ActivityResultContracts.StartActivityForResult() | ||||||
|             ) { |             ) { | ||||||
| @@ -198,14 +206,28 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback { | |||||||
|  |  | ||||||
|     override fun onConfigurationChanged(newConfig: Configuration) { |     override fun onConfigurationChanged(newConfig: Configuration) { | ||||||
|         super.onConfigurationChanged(newConfig) |         super.onConfigurationChanged(newConfig) | ||||||
|         if (!isInFoldableLayout) { |         if (emulationActivity?.isInPictureInPictureMode == true) { | ||||||
|             if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) { |             if (binding.drawerLayout.isOpen) { | ||||||
|                 binding.surfaceInputOverlay.setOrientation(InputOverlay.PORTRAIT) |                 binding.drawerLayout.close() | ||||||
|             } else { |             } | ||||||
|                 binding.surfaceInputOverlay.setOrientation(InputOverlay.LANDSCAPE) |             if (EmulationMenuSettings.showOverlay) { | ||||||
|  |                 binding.surfaceInputOverlay.post { binding.surfaceInputOverlay.isVisible = false } | ||||||
|  |             } | ||||||
|  |         } else { | ||||||
|  |             if (EmulationMenuSettings.showOverlay) { | ||||||
|  |                 binding.surfaceInputOverlay.post { binding.surfaceInputOverlay.isVisible = true } | ||||||
|  |             } | ||||||
|  |             if (!isInFoldableLayout) { | ||||||
|  |                 if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) { | ||||||
|  |                     binding.surfaceInputOverlay.setOrientation(InputOverlay.PORTRAIT) | ||||||
|  |                 } else { | ||||||
|  |                     binding.surfaceInputOverlay.setOrientation(InputOverlay.LANDSCAPE) | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             if (!binding.surfaceInputOverlay.isInEditMode) { | ||||||
|  |                 refreshInputOverlay() | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         if (!binding.surfaceInputOverlay.isInEditMode) refreshInputOverlay() |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     override fun onResume() { |     override fun onResume() { | ||||||
| @@ -247,37 +269,6 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback { | |||||||
|         super.onDetach() |         super.onDetach() | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     fun isEmulationStatePaused() : Boolean { |  | ||||||
|         return this::emulationState.isInitialized && emulationState.isPaused |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     fun onPictureInPictureEnter() { |  | ||||||
|         if (binding.drawerLayout.isOpen) { |  | ||||||
|             binding.drawerLayout.close() |  | ||||||
|         } |  | ||||||
|         if (EmulationMenuSettings.showOverlay) { |  | ||||||
|             binding.surfaceInputOverlay.post { binding.surfaceInputOverlay.isVisible = false } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     fun onPictureInPicturePause() { |  | ||||||
|         if (!emulationState.isPaused) { |  | ||||||
|             emulationState.pause() |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     fun onPictureInPicturePlay() { |  | ||||||
|         if (emulationState.isPaused) { |  | ||||||
|             emulationState.run(false) |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     fun onPictureInPictureLeave() { |  | ||||||
|         if (EmulationMenuSettings.showOverlay) { |  | ||||||
|             binding.surfaceInputOverlay.post { binding.surfaceInputOverlay.isVisible = true } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     private fun refreshInputOverlay() { |     private fun refreshInputOverlay() { | ||||||
|         binding.surfaceInputOverlay.refreshControls() |         binding.surfaceInputOverlay.refreshControls() | ||||||
|     } |     } | ||||||
| @@ -338,7 +329,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback { | |||||||
|  |  | ||||||
|     private val Number.toPx get() = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, this.toFloat(), Resources.getSystem().displayMetrics).toInt() |     private val Number.toPx get() = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, this.toFloat(), Resources.getSystem().displayMetrics).toInt() | ||||||
|  |  | ||||||
|     fun updateFoldableLayout(emulationActivity: EmulationActivity, newLayoutInfo: WindowLayoutInfo) { |     private fun updateFoldableLayout(emulationActivity: EmulationActivity, newLayoutInfo: WindowLayoutInfo) { | ||||||
|         val isFolding = (newLayoutInfo.displayFeatures.find { it is FoldingFeature } as? FoldingFeature)?.let { |         val isFolding = (newLayoutInfo.displayFeatures.find { it is FoldingFeature } as? FoldingFeature)?.let { | ||||||
|             if (it.isSeparating) { |             if (it.isSeparating) { | ||||||
|                 emulationActivity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED |                 emulationActivity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED | ||||||
|   | |||||||
| @@ -202,6 +202,11 @@ public: | |||||||
|         return m_is_running; |         return m_is_running; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     bool IsPaused() const { | ||||||
|  |         std::scoped_lock lock(m_mutex); | ||||||
|  |         return m_is_running && m_is_paused; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     const Core::PerfStatsResults& PerfStats() const { |     const Core::PerfStatsResults& PerfStats() const { | ||||||
|         std::scoped_lock m_perf_stats_lock(m_perf_stats_mutex); |         std::scoped_lock m_perf_stats_lock(m_perf_stats_mutex); | ||||||
|         return m_perf_stats; |         return m_perf_stats; | ||||||
| @@ -287,11 +292,13 @@ public: | |||||||
|     void PauseEmulation() { |     void PauseEmulation() { | ||||||
|         std::scoped_lock lock(m_mutex); |         std::scoped_lock lock(m_mutex); | ||||||
|         m_system.Pause(); |         m_system.Pause(); | ||||||
|  |         m_is_paused = true; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     void UnPauseEmulation() { |     void UnPauseEmulation() { | ||||||
|         std::scoped_lock lock(m_mutex); |         std::scoped_lock lock(m_mutex); | ||||||
|         m_system.Run(); |         m_system.Run(); | ||||||
|  |         m_is_paused = false; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     void HaltEmulation() { |     void HaltEmulation() { | ||||||
| @@ -473,6 +480,7 @@ private: | |||||||
|     std::shared_ptr<FileSys::VfsFilesystem> m_vfs; |     std::shared_ptr<FileSys::VfsFilesystem> m_vfs; | ||||||
|     Core::SystemResultStatus m_load_result{Core::SystemResultStatus::ErrorNotInitialized}; |     Core::SystemResultStatus m_load_result{Core::SystemResultStatus::ErrorNotInitialized}; | ||||||
|     bool m_is_running{}; |     bool m_is_running{}; | ||||||
|  |     bool m_is_paused{}; | ||||||
|     SoftwareKeyboard::AndroidKeyboard* m_software_keyboard{}; |     SoftwareKeyboard::AndroidKeyboard* m_software_keyboard{}; | ||||||
|     std::unique_ptr<Service::Account::ProfileManager> m_profile_manager; |     std::unique_ptr<Service::Account::ProfileManager> m_profile_manager; | ||||||
|  |  | ||||||
| @@ -583,6 +591,11 @@ jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_isRunning([[maybe_unused]] JNIEnv | |||||||
|     return static_cast<jboolean>(EmulationSession::GetInstance().IsRunning()); |     return static_cast<jboolean>(EmulationSession::GetInstance().IsRunning()); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_isPaused([[maybe_unused]] JNIEnv* env, | ||||||
|  |                                                         [[maybe_unused]] jclass clazz) { | ||||||
|  |     return static_cast<jboolean>(EmulationSession::GetInstance().IsPaused()); | ||||||
|  | } | ||||||
|  |  | ||||||
| jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_isHandheldOnly([[maybe_unused]] JNIEnv* env, | jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_isHandheldOnly([[maybe_unused]] JNIEnv* env, | ||||||
|                                                               [[maybe_unused]] jclass clazz) { |                                                               [[maybe_unused]] jclass clazz) { | ||||||
|     return EmulationSession::GetInstance().IsHandheldOnly(); |     return EmulationSession::GetInstance().IsHandheldOnly(); | ||||||
|   | |||||||
| @@ -59,43 +59,43 @@ | |||||||
|     <integer name="SWITCH_BUTTON_MINUS_PORTRAIT_Y">950</integer> |     <integer name="SWITCH_BUTTON_MINUS_PORTRAIT_Y">950</integer> | ||||||
|     <integer name="SWITCH_BUTTON_PLUS_PORTRAIT_X">560</integer> |     <integer name="SWITCH_BUTTON_PLUS_PORTRAIT_X">560</integer> | ||||||
|     <integer name="SWITCH_BUTTON_PLUS_PORTRAIT_Y">950</integer> |     <integer name="SWITCH_BUTTON_PLUS_PORTRAIT_Y">950</integer> | ||||||
|     <integer name="SWITCH_BUTTON_HOME_PORTRAIT_X">600</integer> |     <integer name="SWITCH_BUTTON_HOME_PORTRAIT_X">660</integer> | ||||||
|     <integer name="SWITCH_BUTTON_HOME_PORTRAIT_Y">950</integer> |     <integer name="SWITCH_BUTTON_HOME_PORTRAIT_Y">950</integer> | ||||||
|     <integer name="SWITCH_BUTTON_CAPTURE_PORTRAIT_X">400</integer> |     <integer name="SWITCH_BUTTON_CAPTURE_PORTRAIT_X">320</integer> | ||||||
|     <integer name="SWITCH_BUTTON_CAPTURE_PORTRAIT_Y">950</integer> |     <integer name="SWITCH_BUTTON_CAPTURE_PORTRAIT_Y">950</integer> | ||||||
|     <integer name="SWITCH_BUTTON_DPAD_PORTRAIT_X">240</integer> |     <integer name="SWITCH_BUTTON_DPAD_PORTRAIT_X">240</integer> | ||||||
|     <integer name="SWITCH_BUTTON_DPAD_PORTRAIT_Y">820</integer> |     <integer name="SWITCH_BUTTON_DPAD_PORTRAIT_Y">820</integer> | ||||||
|  |  | ||||||
|     <!-- Default SWITCH foldable layout --> |     <!-- Default SWITCH foldable layout --> | ||||||
|     <integer name="SWITCH_BUTTON_A_FOLDABLE_X">840</integer> |     <integer name="SWITCH_BUTTON_A_FOLDABLE_X">840</integer> | ||||||
|     <integer name="SWITCH_BUTTON_A_FOLDABLE_Y">420</integer> |     <integer name="SWITCH_BUTTON_A_FOLDABLE_Y">340</integer> | ||||||
|     <integer name="SWITCH_BUTTON_B_FOLDABLE_X">740</integer> |     <integer name="SWITCH_BUTTON_B_FOLDABLE_X">740</integer> | ||||||
|     <integer name="SWITCH_BUTTON_B_FOLDABLE_Y">460</integer> |     <integer name="SWITCH_BUTTON_B_FOLDABLE_Y">380</integer> | ||||||
|     <integer name="SWITCH_BUTTON_X_FOLDABLE_X">740</integer> |     <integer name="SWITCH_BUTTON_X_FOLDABLE_X">740</integer> | ||||||
|     <integer name="SWITCH_BUTTON_X_FOLDABLE_Y">380</integer> |     <integer name="SWITCH_BUTTON_X_FOLDABLE_Y">300</integer> | ||||||
|     <integer name="SWITCH_BUTTON_Y_FOLDABLE_X">640</integer> |     <integer name="SWITCH_BUTTON_Y_FOLDABLE_X">640</integer> | ||||||
|     <integer name="SWITCH_BUTTON_Y_FOLDABLE_Y">420</integer> |     <integer name="SWITCH_BUTTON_Y_FOLDABLE_Y">340</integer> | ||||||
|     <integer name="SWITCH_STICK_L_FOLDABLE_X">180</integer> |     <integer name="SWITCH_STICK_L_FOLDABLE_X">180</integer> | ||||||
|     <integer name="SWITCH_STICK_L_FOLDABLE_Y">240</integer> |     <integer name="SWITCH_STICK_L_FOLDABLE_Y">200</integer> | ||||||
|     <integer name="SWITCH_STICK_R_FOLDABLE_X">820</integer> |     <integer name="SWITCH_STICK_R_FOLDABLE_X">820</integer> | ||||||
|     <integer name="SWITCH_STICK_R_FOLDABLE_Y">240</integer> |     <integer name="SWITCH_STICK_R_FOLDABLE_Y">200</integer> | ||||||
|     <integer name="SWITCH_TRIGGER_L_FOLDABLE_X">140</integer> |     <integer name="SWITCH_TRIGGER_L_FOLDABLE_X">140</integer> | ||||||
|     <integer name="SWITCH_TRIGGER_L_FOLDABLE_Y">100</integer> |     <integer name="SWITCH_TRIGGER_L_FOLDABLE_Y">80</integer> | ||||||
|     <integer name="SWITCH_TRIGGER_R_FOLDABLE_X">860</integer> |     <integer name="SWITCH_TRIGGER_R_FOLDABLE_X">860</integer> | ||||||
|     <integer name="SWITCH_TRIGGER_R_FOLDABLE_Y">100</integer> |     <integer name="SWITCH_TRIGGER_R_FOLDABLE_Y">80</integer> | ||||||
|     <integer name="SWITCH_TRIGGER_ZL_FOLDABLE_X">140</integer> |     <integer name="SWITCH_TRIGGER_ZL_FOLDABLE_X">140</integer> | ||||||
|     <integer name="SWITCH_TRIGGER_ZL_FOLDABLE_Y">40</integer> |     <integer name="SWITCH_TRIGGER_ZL_FOLDABLE_Y">20</integer> | ||||||
|     <integer name="SWITCH_TRIGGER_ZR_FOLDABLE_X">860</integer> |     <integer name="SWITCH_TRIGGER_ZR_FOLDABLE_X">860</integer> | ||||||
|     <integer name="SWITCH_TRIGGER_ZR_FOLDABLE_Y">40</integer> |     <integer name="SWITCH_TRIGGER_ZR_FOLDABLE_Y">20</integer> | ||||||
|     <integer name="SWITCH_BUTTON_MINUS_FOLDABLE_X">440</integer> |     <integer name="SWITCH_BUTTON_MINUS_FOLDABLE_X">440</integer> | ||||||
|     <integer name="SWITCH_BUTTON_MINUS_FOLDABLE_Y">550</integer> |     <integer name="SWITCH_BUTTON_MINUS_FOLDABLE_Y">420</integer> | ||||||
|     <integer name="SWITCH_BUTTON_PLUS_FOLDABLE_X">560</integer> |     <integer name="SWITCH_BUTTON_PLUS_FOLDABLE_X">560</integer> | ||||||
|     <integer name="SWITCH_BUTTON_PLUS_FOLDABLE_Y">550</integer> |     <integer name="SWITCH_BUTTON_PLUS_FOLDABLE_Y">420</integer> | ||||||
|     <integer name="SWITCH_BUTTON_HOME_FOLDABLE_X">600</integer> |     <integer name="SWITCH_BUTTON_HOME_FOLDABLE_X">680</integer> | ||||||
|     <integer name="SWITCH_BUTTON_HOME_FOLDABLE_Y">550</integer> |     <integer name="SWITCH_BUTTON_HOME_FOLDABLE_Y">420</integer> | ||||||
|     <integer name="SWITCH_BUTTON_CAPTURE_FOLDABLE_X">400</integer> |     <integer name="SWITCH_BUTTON_CAPTURE_FOLDABLE_X">320</integer> | ||||||
|     <integer name="SWITCH_BUTTON_CAPTURE_FOLDABLE_Y">550</integer> |     <integer name="SWITCH_BUTTON_CAPTURE_FOLDABLE_Y">420</integer> | ||||||
|     <integer name="SWITCH_BUTTON_DPAD_FOLDABLE_X">240</integer> |     <integer name="SWITCH_BUTTON_DPAD_FOLDABLE_X">240</integer> | ||||||
|     <integer name="SWITCH_BUTTON_DPAD_FOLDABLE_Y">420</integer> |     <integer name="SWITCH_BUTTON_DPAD_FOLDABLE_Y">340</integer> | ||||||
|  |  | ||||||
| </resources> | </resources> | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user