diff options
| author | liamwhite <liamwhite@users.noreply.github.com> | 2023-07-02 11:29:08 -0400 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-07-02 11:29:08 -0400 | 
| commit | 657ab0287d1e7aa42ac01c49c26768e21b2088f7 (patch) | |
| tree | a1ad316c11506d78f8f419853a9761630b79a393 | |
| parent | eaa62aee988454f9cbd58219aa4d82d7e152c61d (diff) | |
| parent | ff6d35f2c780df5e3604979eef0d5b7c194617ea (diff) | |
Merge pull request #10949 from t895/memory-requirements
android: Rework MemoryUtil
4 files changed, 114 insertions, 44 deletions
| diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/activities/EmulationActivity.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/activities/EmulationActivity.kt index ae665ed2e..7461fb093 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/activities/EmulationActivity.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/activities/EmulationActivity.kt @@ -34,11 +34,14 @@ import androidx.core.view.WindowCompat  import androidx.core.view.WindowInsetsCompat  import androidx.core.view.WindowInsetsControllerCompat  import androidx.navigation.fragment.NavHostFragment +import androidx.preference.PreferenceManager  import org.yuzu.yuzu_emu.NativeLibrary  import org.yuzu.yuzu_emu.R +import org.yuzu.yuzu_emu.YuzuApplication  import org.yuzu.yuzu_emu.databinding.ActivityEmulationBinding  import org.yuzu.yuzu_emu.features.settings.model.BooleanSetting  import org.yuzu.yuzu_emu.features.settings.model.IntSetting +import org.yuzu.yuzu_emu.features.settings.model.Settings  import org.yuzu.yuzu_emu.features.settings.model.SettingsViewModel  import org.yuzu.yuzu_emu.model.Game  import org.yuzu.yuzu_emu.utils.ControllerMappingHelper @@ -47,6 +50,7 @@ import org.yuzu.yuzu_emu.utils.InputHandler  import org.yuzu.yuzu_emu.utils.MemoryUtil  import org.yuzu.yuzu_emu.utils.NfcReader  import org.yuzu.yuzu_emu.utils.ThemeHelper +import java.text.NumberFormat  import kotlin.math.roundToInt  class EmulationActivity : AppCompatActivity(), SensorEventListener { @@ -106,17 +110,26 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener {          inputHandler = InputHandler()          inputHandler.initialize() -        val memoryUtil = MemoryUtil(this) -        if (memoryUtil.isLessThan(8, MemoryUtil.Gb)) { -            Toast.makeText( -                this, -                getString( -                    R.string.device_memory_inadequate, -                    memoryUtil.getDeviceRAM(), -                    "8 ${getString(R.string.memory_gigabyte)}" -                ), -                Toast.LENGTH_LONG -            ).show() +        val preferences = PreferenceManager.getDefaultSharedPreferences(YuzuApplication.appContext) +        if (!preferences.getBoolean(Settings.PREF_MEMORY_WARNING_SHOWN, false)) { +            if (MemoryUtil.isLessThan(MemoryUtil.REQUIRED_MEMORY, MemoryUtil.Gb)) { +                Toast.makeText( +                    this, +                    getString( +                        R.string.device_memory_inadequate, +                        MemoryUtil.getDeviceRAM(), +                        getString( +                            R.string.memory_formatted, +                            NumberFormat.getInstance().format(MemoryUtil.REQUIRED_MEMORY), +                            getString(R.string.memory_gigabyte) +                        ) +                    ), +                    Toast.LENGTH_LONG +                ).show() +                preferences.edit() +                    .putBoolean(Settings.PREF_MEMORY_WARNING_SHOWN, true) +                    .apply() +            }          }          // Start a foreground service to prevent the app from getting killed in the background diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/Settings.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/Settings.kt index 88afb2223..be6e17e65 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/Settings.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/Settings.kt @@ -110,6 +110,8 @@ class Settings {          const val SECTION_THEME = "Theme"          const val SECTION_DEBUG = "Debug" +        const val PREF_MEMORY_WARNING_SHOWN = "MemoryWarningShown" +          const val PREF_OVERLAY_INIT = "OverlayInit"          const val PREF_CONTROL_SCALE = "controlScale"          const val PREF_CONTROL_OPACITY = "controlOpacity" diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/MemoryUtil.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/MemoryUtil.kt index 18e5fa0b0..aa4a5539a 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/MemoryUtil.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/MemoryUtil.kt @@ -5,35 +5,101 @@ package org.yuzu.yuzu_emu.utils  import android.app.ActivityManager  import android.content.Context +import android.os.Build  import org.yuzu.yuzu_emu.R +import org.yuzu.yuzu_emu.YuzuApplication  import java.util.Locale +import kotlin.math.ceil -class MemoryUtil(val context: Context) { +object MemoryUtil { +    private val context get() = YuzuApplication.appContext -    private val Long.floatForm: String -        get() = String.format(Locale.ROOT, "%.2f", this.toDouble()) +    private val Float.hundredths: String +        get() = String.format(Locale.ROOT, "%.2f", this) -    private fun bytesToSizeUnit(size: Long): String { -        return when { -            size < Kb -> "${size.floatForm} ${context.getString(R.string.memory_byte)}" -            size < Mb -> "${(size / Kb).floatForm} ${context.getString(R.string.memory_kilobyte)}" -            size < Gb -> "${(size / Mb).floatForm} ${context.getString(R.string.memory_megabyte)}" -            size < Tb -> "${(size / Gb).floatForm} ${context.getString(R.string.memory_gigabyte)}" -            size < Pb -> "${(size / Tb).floatForm} ${context.getString(R.string.memory_terabyte)}" -            size < Eb -> "${(size / Pb).floatForm} ${context.getString(R.string.memory_petabyte)}" -            else -> "${(size / Eb).floatForm} ${context.getString(R.string.memory_exabyte)}" +    // Required total system memory +    const val REQUIRED_MEMORY = 8 + +    const val Kb: Float = 1024F +    const val Mb = Kb * 1024 +    const val Gb = Mb * 1024 +    const val Tb = Gb * 1024 +    const val Pb = Tb * 1024 +    const val Eb = Pb * 1024 + +    private fun bytesToSizeUnit(size: Float): String = +        when { +            size < Kb -> { +                context.getString( +                    R.string.memory_formatted, +                    size.hundredths, +                    context.getString(R.string.memory_byte) +                ) +            } +            size < Mb -> { +                context.getString( +                    R.string.memory_formatted, +                    (size / Kb).hundredths, +                    context.getString(R.string.memory_kilobyte) +                ) +            } +            size < Gb -> { +                context.getString( +                    R.string.memory_formatted, +                    (size / Mb).hundredths, +                    context.getString(R.string.memory_megabyte) +                ) +            } +            size < Tb -> { +                context.getString( +                    R.string.memory_formatted, +                    (size / Gb).hundredths, +                    context.getString(R.string.memory_gigabyte) +                ) +            } +            size < Pb -> { +                context.getString( +                    R.string.memory_formatted, +                    (size / Tb).hundredths, +                    context.getString(R.string.memory_terabyte) +                ) +            } +            size < Eb -> { +                context.getString( +                    R.string.memory_formatted, +                    (size / Pb).hundredths, +                    context.getString(R.string.memory_petabyte) +                ) +            } +            else -> { +                context.getString( +                    R.string.memory_formatted, +                    (size / Eb).hundredths, +                    context.getString(R.string.memory_exabyte) +                ) +            }          } -    } -    private val totalMemory = -        with(context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager) { +    // Devices are unlikely to have 0.5GB increments of memory so we'll just round up to account for +    // the potential error created by memInfo.totalMem +    private val totalMemory: Float +        get() {              val memInfo = ActivityManager.MemoryInfo() -            getMemoryInfo(memInfo) -            memInfo.totalMem +            with(context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager) { +                getMemoryInfo(memInfo) +            } + +            return ceil( +                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { +                    memInfo.advertisedMem.toFloat() +                } else { +                    memInfo.totalMem.toFloat() +                } +            )          } -    fun isLessThan(minimum: Int, size: Long): Boolean { -        return when (size) { +    fun isLessThan(minimum: Int, size: Float): Boolean = +        when (size) {              Kb -> totalMemory < Mb && totalMemory < minimum              Mb -> totalMemory < Gb && (totalMemory / Mb) < minimum              Gb -> totalMemory < Tb && (totalMemory / Gb) < minimum @@ -42,18 +108,6 @@ class MemoryUtil(val context: Context) {              Eb -> totalMemory / Eb < minimum              else -> totalMemory < Kb && totalMemory < minimum          } -    } - -    fun getDeviceRAM(): String { -        return bytesToSizeUnit(totalMemory) -    } - -    companion object { -        const val Kb: Long = 1024 -        const val Mb = Kb * 1024 -        const val Gb = Mb * 1024 -        const val Tb = Gb * 1024 -        const val Pb = Tb * 1024 -        const val Eb = Pb * 1024 -    } + +    fun getDeviceRAM(): String = bytesToSizeUnit(totalMemory)  } diff --git a/src/android/app/src/main/res/values/strings.xml b/src/android/app/src/main/res/values/strings.xml index af7450619..b3c737979 100644 --- a/src/android/app/src/main/res/values/strings.xml +++ b/src/android/app/src/main/res/values/strings.xml @@ -273,6 +273,7 @@      <string name="fatal_error_message">A fatal error occurred. Check the log for details.\nContinuing emulation may result in crashes and bugs.</string>      <string name="performance_warning">Turning off this setting will significantly reduce emulation performance! For the best experience, it is recommended that you leave this setting enabled.</string>      <string name="device_memory_inadequate">Device RAM: %1$s\nRecommended: %2$s</string> +    <string name="memory_formatted">%1$s %2$s</string>      <!-- Region Names -->      <string name="region_japan">Japan</string> | 
