diff --git a/app/build.gradle b/app/build.gradle index c0f01108..cb42debb 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -172,6 +172,7 @@ dependencies { implementation 'com.google.android.material:material:1.8.0' implementation 'androidx.documentfile:documentfile:1.0.1' implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0' + implementation 'androidx.window:window:1.0.0' implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1" implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.5.1" implementation 'androidx.fragment:fragment-ktx:1.5.5' diff --git a/app/src/main/java/emu/skyline/EmulationActivity.kt b/app/src/main/java/emu/skyline/EmulationActivity.kt index 768df54c..bd98001e 100644 --- a/app/src/main/java/emu/skyline/EmulationActivity.kt +++ b/app/src/main/java/emu/skyline/EmulationActivity.kt @@ -13,12 +13,14 @@ import android.content.BroadcastReceiver import android.content.Context import android.content.Intent import android.content.IntentFilter +import android.content.pm.ActivityInfo import android.content.res.AssetManager import android.content.res.Configuration import android.graphics.PointF import android.graphics.drawable.Icon import android.hardware.display.DisplayManager import android.os.* +import android.util.DisplayMetrics import android.util.Log import android.util.Rational import android.view.* @@ -30,6 +32,12 @@ import androidx.core.view.isGone import androidx.core.view.isInvisible import androidx.core.view.updateMargins import androidx.fragment.app.FragmentTransaction +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.lifecycleScope +import androidx.lifecycle.repeatOnLifecycle +import androidx.window.layout.FoldingFeature +import androidx.window.layout.WindowInfoTracker +import androidx.window.layout.WindowLayoutInfo import com.google.android.material.dialog.MaterialAlertDialogBuilder import dagger.hilt.android.AndroidEntryPoint import emu.skyline.BuildConfig @@ -47,12 +55,15 @@ import emu.skyline.settings.NativeSettings import emu.skyline.utils.ByteBufferSerializable import emu.skyline.utils.GpuDriverHelper import emu.skyline.utils.serializable +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch import java.nio.ByteBuffer import java.nio.ByteOrder import java.util.concurrent.FutureTask import javax.inject.Inject import kotlin.math.abs + private const val ActionPause = "${BuildConfig.APPLICATION_ID}.ACTION_EMULATOR_PAUSE" private const val ActionMute = "${BuildConfig.APPLICATION_ID}.ACTION_EMULATOR_MUTE" @@ -263,7 +274,6 @@ class EmulationActivity : AppCompatActivity(), SurfaceHolder.Callback, View.OnTo populateAppItem() emulationSettings = EmulationSettings.forEmulation(item.titleId ?: item.key()) - requestedOrientation = emulationSettings.orientation window.attributes.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES inputHandler = InputHandler(inputManager, emulationSettings) setContentView(binding.root) @@ -305,6 +315,16 @@ class EmulationActivity : AppCompatActivity(), SurfaceHolder.Callback, View.OnTo } ) + lifecycleScope.launch(Dispatchers.Main) { + lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) { + WindowInfoTracker.getOrCreate(this@EmulationActivity) + .windowLayoutInfo(this@EmulationActivity) + .collect { newLayoutInfo -> + updateCurrentLayout(newLayoutInfo) + } + } + } + if (emulationSettings.perfStats) { if (emulationSettings.disableFrameThrottling) binding.perfStats.setTextColor(getColor(R.color.colorPerfStatsSecondary)) @@ -480,6 +500,28 @@ class EmulationActivity : AppCompatActivity(), SurfaceHolder.Callback, View.OnTo } } + /** + * Updating the layout depending on type and state of device + */ + private fun updateCurrentLayout(newLayoutInfo: WindowLayoutInfo) { + val displayMetrics = DisplayMetrics() + windowManager.defaultDisplay.getMetrics(displayMetrics) + binding.onScreenGameView.minimumHeight = displayMetrics.heightPixels + requestedOrientation = emulationSettings.orientation + for (displayFeature in newLayoutInfo.displayFeatures) { + val foldFeature = displayFeature as? FoldingFeature + foldFeature?.let { + if (it.isSeparating) { + //Folding feature separates the display area into two distinct sections + requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED + if (foldFeature.orientation == FoldingFeature.Orientation.HORIZONTAL) { + binding.onScreenGameView.minimumHeight = displayFeature.bounds.top + } + } + } + } + } + /** * Stop the currently executing ROM and replace it with the one specified in the new intent */ diff --git a/app/src/main/res/layout/emu_activity.xml b/app/src/main/res/layout/emu_activity.xml index 47db2aec..9875c61e 100644 --- a/app/src/main/res/layout/emu_activity.xml +++ b/app/src/main/res/layout/emu_activity.xml @@ -9,11 +9,17 @@ tools:context=".EmulationActivity" tools:ignore="RtlHardcoded"> - + android:layout_height="wrap_content"> + + +