summaryrefslogtreecommitdiff
path: root/Source/Android/app/src/main/java
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Android/app/src/main/java')
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/GameAdapter.kt5
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/GameRowPresenter.kt2
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/dialogs/GameDetailsDialog.kt4
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/netplay/ui/NetplayScreen.kt6
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/GameFile.kt2
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/TitleDatabase.kt17
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/services/GameFileCacheManager.kt35
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/services/SyncProgramsJobService.kt5
8 files changed, 64 insertions, 12 deletions
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/GameAdapter.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/GameAdapter.kt
index dbcfdd42e2..e7ea8e5519 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/GameAdapter.kt
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/GameAdapter.kt
@@ -61,13 +61,14 @@ class GameAdapter : RecyclerView.Adapter<GameViewHolder>(),
val gameFile = mGameFiles[position]
holder.apply {
+ val title = gameFile.getTitle(GameFileCacheManager.getTitleDatabase())
if (BooleanSetting.MAIN_SHOW_GAME_TITLES.boolean) {
- binding.textGameTitle.text = gameFile.getTitle()
+ binding.textGameTitle.text = title
binding.textGameTitle.visibility = View.VISIBLE
binding.textGameTitleInner.visibility = View.GONE
binding.textGameCaption.visibility = View.VISIBLE
} else {
- binding.textGameTitleInner.text = gameFile.getTitle()
+ binding.textGameTitleInner.text = title
binding.textGameTitleInner.visibility = View.VISIBLE
binding.textGameTitle.visibility = View.GONE
binding.textGameCaption.visibility = View.GONE
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/GameRowPresenter.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/GameRowPresenter.kt
index 4f43601e68..7cbb3000e2 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/GameRowPresenter.kt
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/GameRowPresenter.kt
@@ -48,7 +48,7 @@ class GameRowPresenter : Presenter() {
holder.apply {
imageScreenshot.setImageDrawable(null)
- cardParent.titleText = gameFile.getTitle()
+ cardParent.titleText = gameFile.getTitle(GameFileCacheManager.getTitleDatabase())
holder.gameFile = gameFile
// Set the background color of the card
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/dialogs/GameDetailsDialog.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/dialogs/GameDetailsDialog.kt
index 0384da89c0..b97fd987e6 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/dialogs/GameDetailsDialog.kt
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/dialogs/GameDetailsDialog.kt
@@ -51,7 +51,7 @@ class GameDetailsDialog : DialogFragment() {
textTimePlayed.visibility = View.GONE
}
- textGameTitle.text = gameFile.getTitle()
+ textGameTitle.text = gameFile.getTitle(GameFileCacheManager.getTitleDatabase())
textDescription.text = gameFile.getDescription()
if (gameFile.getDescription().isEmpty()) {
textDescription.visibility = View.GONE
@@ -118,7 +118,7 @@ class GameDetailsDialog : DialogFragment() {
textTimePlayed.visibility = View.GONE
}
- textGameTitle.text = gameFile.getTitle()
+ textGameTitle.text = gameFile.getTitle(GameFileCacheManager.getTitleDatabase())
textDescription.text = gameFile.getDescription()
if (gameFile.getDescription().isEmpty()) {
tvBinding.textDescription.visibility = View.GONE
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/netplay/ui/NetplayScreen.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/netplay/ui/NetplayScreen.kt
index 789a3cef17..3c641c6695 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/netplay/ui/NetplayScreen.kt
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/netplay/ui/NetplayScreen.kt
@@ -104,6 +104,7 @@ import org.dolphinemu.dolphinemu.features.netplay.model.Player
import org.dolphinemu.dolphinemu.features.netplay.model.SaveTransferProgress
import org.dolphinemu.dolphinemu.features.netplay.model.TraversalState
import org.dolphinemu.dolphinemu.model.GameFile
+import org.dolphinemu.dolphinemu.services.GameFileCacheManager
import org.dolphinemu.dolphinemu.ui.theme.DolphinScaffold
import org.dolphinemu.dolphinemu.ui.theme.DolphinTheme
import org.dolphinemu.dolphinemu.ui.theme.MenuSpacer
@@ -753,6 +754,7 @@ private fun GameGridItem(
gameFile: GameFile,
onClick: () -> Unit,
) {
+ val titleDatabase = GameFileCacheManager.getTitleDatabase()
Card(
onClick = onClick,
) {
@@ -762,7 +764,7 @@ private fun GameGridItem(
.data(gameFile)
.error(R.drawable.no_banner)
.build(),
- contentDescription = gameFile.getTitle(),
+ contentDescription = gameFile.getTitle(titleDatabase),
contentScale = ContentScale.Crop,
imageLoader = CoilUtils.imageLoader,
modifier = Modifier
@@ -770,7 +772,7 @@ private fun GameGridItem(
.aspectRatio(0.7f)
)
Text(
- text = gameFile.getTitle(),
+ text = gameFile.getTitle(titleDatabase),
style = MaterialTheme.typography.bodySmall,
maxLines = 2,
minLines = 2,
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/GameFile.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/GameFile.kt
index 26da174285..4794f5c1b7 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/GameFile.kt
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/GameFile.kt
@@ -12,7 +12,7 @@ class GameFile private constructor(private val pointer: Long) {
external fun getPlatform(): Int
- external fun getTitle(): String
+ external fun getTitle(titleDatabase: TitleDatabase?): String
external fun getDescription(): String
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/TitleDatabase.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/TitleDatabase.kt
new file mode 100644
index 0000000000..e5089673b8
--- /dev/null
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/TitleDatabase.kt
@@ -0,0 +1,17 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+package org.dolphinemu.dolphinemu.model
+
+import androidx.annotation.Keep
+
+@Keep
+class TitleDatabase private constructor(private val pointer: Long) {
+ external fun finalize()
+
+ external fun userTitleMapEquals(other: TitleDatabase?): Boolean
+
+ companion object {
+ @JvmStatic
+ external suspend fun load(): TitleDatabase
+ }
+}
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/services/GameFileCacheManager.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/services/GameFileCacheManager.kt
index 51ce4a4f2f..a5e54aa0de 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/services/GameFileCacheManager.kt
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/services/GameFileCacheManager.kt
@@ -7,6 +7,7 @@ import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.asFlow
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.MainScope
+import kotlinx.coroutines.async
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
@@ -14,10 +15,12 @@ import org.dolphinemu.dolphinemu.features.settings.model.BooleanSetting
import org.dolphinemu.dolphinemu.features.settings.model.ConfigChangedCallback
import org.dolphinemu.dolphinemu.model.GameFile
import org.dolphinemu.dolphinemu.model.GameFileCache
+import org.dolphinemu.dolphinemu.model.TitleDatabase
import org.dolphinemu.dolphinemu.ui.platform.Platform
import org.dolphinemu.dolphinemu.ui.platform.PlatformTab
import org.dolphinemu.dolphinemu.utils.AfterDirectoryInitializationRunner
import java.util.Arrays
+import java.util.concurrent.atomic.AtomicReference
/**
* Loads game list data in the background.
@@ -25,6 +28,7 @@ import java.util.Arrays
object GameFileCacheManager {
private var gameFileCache: GameFileCache? = null
private val gameFiles = MutableLiveData(emptyArray<GameFile>())
+ private var titleDatabase = AtomicReference<TitleDatabase>(null)
private var firstLoadDone = false
private var recursiveScanEnabled = false
@@ -88,6 +92,8 @@ object GameFileCacheManager {
}
}
+ fun getTitleDatabase(): TitleDatabase? = titleDatabase.get()
+
/**
* Returns true if in the process of loading the cache for the first time.
*/
@@ -171,13 +177,22 @@ object GameFileCacheManager {
*/
private suspend fun load() {
if (!firstLoadDone) {
+ val titleDatabaseJob = MainScope().async(Dispatchers.IO) {
+ TitleDatabase.load()
+ }
+
withContext(Dispatchers.IO) {
setUpAutomaticRescan()
+
gameFileCache!!.load()
+
+ titleDatabase.set(titleDatabaseJob.await())
+
if (gameFileCache!!.getSize() != 0) {
updateGameFileArray()
}
}
+
firstLoadDone = true
}
@@ -196,16 +211,29 @@ object GameFileCacheManager {
loadInProgress.asFlow().first { !it }
}
+ val titleDatabaseJob = MainScope().async(Dispatchers.IO) {
+ val newTitleDatabase = TitleDatabase.load()
+ val titleDatabaseChanged =
+ !newTitleDatabase.userTitleMapEquals(titleDatabase.get())
+ if (titleDatabaseChanged) newTitleDatabase else null
+ }
+
withContext(Dispatchers.IO) {
val gamePaths = GameFileCache.getAllGamePaths()
-
val changed = gameFileCache!!.update(gamePaths)
if (changed) {
updateGameFileArray()
}
val additionalMetadataChanged = gameFileCache!!.updateAdditionalMetadata()
- if (additionalMetadataChanged) {
+
+ val newTitleDatabase = titleDatabaseJob.await()
+ val titleDatabaseChanged = newTitleDatabase != null
+ if (titleDatabaseChanged) {
+ titleDatabase.set(newTitleDatabase)
+ }
+
+ if (additionalMetadataChanged || titleDatabaseChanged) {
updateGameFileArray()
}
@@ -219,8 +247,9 @@ object GameFileCacheManager {
private fun updateGameFileArray() {
val gameFilesTemp = gameFileCache!!.getAllGames()
+ val titleDatabase = titleDatabase.get()
Arrays.sort(gameFilesTemp) { lhs, rhs ->
- lhs.getTitle().compareTo(rhs.getTitle(), ignoreCase = true)
+ lhs.getTitle(titleDatabase).compareTo(rhs.getTitle(titleDatabase), ignoreCase = true)
}
gameFiles.postValue(gameFilesTemp)
}
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/services/SyncProgramsJobService.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/services/SyncProgramsJobService.kt
index 2d9ad354fb..fd13ff3175 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/services/SyncProgramsJobService.kt
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/services/SyncProgramsJobService.kt
@@ -138,7 +138,10 @@ class SyncProgramsJobService : JobService() {
TvContractCompat.PreviewPrograms.COLUMN_TYPE,
TvContractCompat.PreviewProgramColumns.TYPE_GAME
)
- values.put(TvContract.Programs.COLUMN_TITLE, game.getTitle())
+ values.put(
+ TvContract.Programs.COLUMN_TITLE,
+ game.getTitle(GameFileCacheManager.getTitleDatabase())
+ )
values.put(TvContract.Programs.COLUMN_SHORT_DESCRIPTION, game.getDescription())
values.put(TvContract.Programs.COLUMN_POSTER_ART_URI, banner.toString())
values.put(