summaryrefslogtreecommitdiff
path: root/Source/Android/app/src/main/java
diff options
context:
space:
mode:
authorCharles Lombardo <clombardo169@gmail.com>2023-01-06 15:15:30 -0500
committerCharles Lombardo <clombardo169@gmail.com>2023-02-20 00:38:24 -0500
commit28faca63a634cd3c8de947143ee029b78a718690 (patch)
treef575f61098f858153eb85b0c71fda324cb063143 /Source/Android/app/src/main/java
parente6583f8bec814d8f3748f1d7738457600ce0de56 (diff)
Android: Replace Glide with Coil image loading
Diffstat (limited to 'Source/Android/app/src/main/java')
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/GameAdapter.kt55
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/GameRowPresenter.kt23
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/dialogs/GameDetailsDialog.kt36
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/GridOptionDialogFragment.kt5
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/GameFile.java12
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/TvMainActivity.java2
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/CoilUtils.kt95
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/CoverHelper.kt40
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/GlideUtils.kt233
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/TvUtil.java4
10 files changed, 209 insertions, 296 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 e3fa287967..919ded6fef 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
@@ -3,7 +3,6 @@
package org.dolphinemu.dolphinemu.adapters
import android.annotation.SuppressLint
-import android.app.Activity
import androidx.recyclerview.widget.RecyclerView
import org.dolphinemu.dolphinemu.adapters.GameAdapter.GameViewHolder
import android.view.View.OnLongClickListener
@@ -11,29 +10,23 @@ import org.dolphinemu.dolphinemu.model.GameFile
import android.view.ViewGroup
import android.view.LayoutInflater
import android.view.View
-import org.dolphinemu.dolphinemu.utils.GlideUtils
import org.dolphinemu.dolphinemu.services.GameFileCacheManager
import org.dolphinemu.dolphinemu.R
import android.view.animation.AnimationUtils
import org.dolphinemu.dolphinemu.activities.EmulationActivity
import androidx.fragment.app.FragmentActivity
+import androidx.lifecycle.lifecycleScope
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.withContext
import org.dolphinemu.dolphinemu.databinding.CardGameBinding
import org.dolphinemu.dolphinemu.dialogs.GamePropertiesDialog
+import org.dolphinemu.dolphinemu.features.settings.model.BooleanSetting
+import org.dolphinemu.dolphinemu.utils.CoilUtils
import java.util.ArrayList
-class GameAdapter(activity: Activity) : RecyclerView.Adapter<GameViewHolder>(),
+class GameAdapter(private val mActivity: FragmentActivity) : RecyclerView.Adapter<GameViewHolder>(),
View.OnClickListener, OnLongClickListener {
- private var mGameFiles: List<GameFile>
- private val mActivity: Activity
-
- /**
- * Initializes the adapter's observer, which watches for changes to the dataset. The adapter will
- * display no data until swapDataSet is called.
- */
- init {
- mGameFiles = ArrayList()
- mActivity = activity
- }
+ private var mGameFiles: List<GameFile> = ArrayList()
/**
* Called by the LayoutManager when it is necessary to create a new view.
@@ -65,7 +58,33 @@ class GameAdapter(activity: Activity) : RecyclerView.Adapter<GameViewHolder>(),
val context = holder.itemView.context
val gameFile = mGameFiles[position]
- GlideUtils.loadGameCover(holder, holder.binding.imageGameScreen, gameFile, mActivity)
+ holder.apply {
+ if (BooleanSetting.MAIN_SHOW_GAME_TITLES.booleanGlobal) {
+ binding.textGameTitle.text = gameFile.title
+ binding.textGameTitle.visibility = View.VISIBLE
+ binding.textGameTitleInner.visibility = View.GONE
+ binding.textGameCaption.visibility = View.VISIBLE
+ } else {
+ binding.textGameTitleInner.text = gameFile.title
+ binding.textGameTitleInner.visibility = View.VISIBLE
+ binding.textGameTitle.visibility = View.GONE
+ binding.textGameCaption.visibility = View.GONE
+ }
+ }
+
+ mActivity.lifecycleScope.launchWhenStarted {
+ withContext(Dispatchers.IO) {
+ val customCoverUri = CoilUtils.findCustomCover(gameFile)
+ withContext(Dispatchers.Main) {
+ CoilUtils.loadGameCover(
+ holder,
+ holder.binding.imageGameScreen,
+ gameFile,
+ customCoverUri
+ )
+ }
+ }
+ }
val animateIn = AnimationUtils.loadAnimation(context, R.anim.anim_card_game_in)
animateIn.fillAfter = true
@@ -86,15 +105,11 @@ class GameAdapter(activity: Activity) : RecyclerView.Adapter<GameViewHolder>(),
}
}
- class GameViewHolder(binding: CardGameBinding) : RecyclerView.ViewHolder(binding.root) {
+ class GameViewHolder(var binding: CardGameBinding) : RecyclerView.ViewHolder(binding.root) {
var gameFile: GameFile? = null
- @JvmField
- var binding: CardGameBinding
-
init {
binding.root.tag = this
- this.binding = binding
}
}
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 66a249e50d..4f062538f9 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
@@ -7,20 +7,24 @@ import android.view.ViewGroup
import androidx.leanback.widget.ImageCardView
import org.dolphinemu.dolphinemu.viewholders.TvGameViewHolder
import org.dolphinemu.dolphinemu.model.GameFile
-import org.dolphinemu.dolphinemu.utils.GlideUtils
import org.dolphinemu.dolphinemu.services.GameFileCacheManager
import org.dolphinemu.dolphinemu.R
import android.view.View
import androidx.core.content.ContextCompat
import android.widget.ImageView
import androidx.fragment.app.FragmentActivity
+import androidx.lifecycle.lifecycleScope
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.withContext
import org.dolphinemu.dolphinemu.dialogs.GamePropertiesDialog
+import org.dolphinemu.dolphinemu.utils.CoilUtils
/**
* The Leanback library / docs call this a Presenter, but it works very
* similarly to a RecyclerView.Adapter.
*/
-class GameRowPresenter : Presenter() {
+class GameRowPresenter(private val mActivity: FragmentActivity) : Presenter() {
+
override fun onCreateViewHolder(parent: ViewGroup): ViewHolder {
// Create a new view.
val gameCard = ImageCardView(parent.context)
@@ -63,7 +67,20 @@ class GameRowPresenter : Presenter() {
holder.cardParent.contentText = gameFile.company
}
}
- GlideUtils.loadGameCover(null, holder.imageScreenshot, gameFile, null)
+
+ mActivity.lifecycleScope.launchWhenStarted {
+ withContext(Dispatchers.IO) {
+ val customCoverUri = CoilUtils.findCustomCover(gameFile)
+ withContext(Dispatchers.Main) {
+ CoilUtils.loadGameCover(
+ null,
+ holder.imageScreenshot,
+ gameFile,
+ customCoverUri
+ )
+ }
+ }
+ }
}
override fun onUnbindViewHolder(viewHolder: ViewHolder) {
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 5c7cf2ed6a..83d69ebbb4 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
@@ -3,17 +3,23 @@
package org.dolphinemu.dolphinemu.dialogs
import android.app.Dialog
+import android.graphics.Bitmap
import android.os.Bundle
import android.view.View
+import android.widget.ImageView
import org.dolphinemu.dolphinemu.services.GameFileCacheManager
import org.dolphinemu.dolphinemu.R
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.DialogFragment
+import androidx.lifecycle.lifecycleScope
+import coil.imageLoader
+import coil.request.ImageRequest
+import kotlinx.coroutines.launch
import org.dolphinemu.dolphinemu.NativeLibrary
import org.dolphinemu.dolphinemu.databinding.DialogGameDetailsBinding
import org.dolphinemu.dolphinemu.databinding.DialogGameDetailsTvBinding
-import org.dolphinemu.dolphinemu.utils.GlideUtils
+import org.dolphinemu.dolphinemu.model.GameFile
class GameDetailsDialog : DialogFragment() {
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
@@ -73,7 +79,9 @@ class GameDetailsDialog : DialogFragment() {
}
}
- GlideUtils.loadGameBanner(binding.banner, gameFile)
+ this.lifecycleScope.launch {
+ loadGameBanner(binding.banner, gameFile)
+ }
builder.setView(binding.root)
} else {
@@ -123,13 +131,35 @@ class GameDetailsDialog : DialogFragment() {
}
}
- GlideUtils.loadGameBanner(tvBinding.banner, gameFile)
+ this.lifecycleScope.launch {
+ loadGameBanner(tvBinding.banner, gameFile)
+ }
builder.setView(tvBinding.root)
}
return builder.create()
}
+ private suspend fun loadGameBanner(imageView: ImageView, gameFile: GameFile) {
+ val vector = gameFile.banner
+ val width = gameFile.bannerWidth
+ val height = gameFile.bannerHeight
+
+ imageView.scaleType = ImageView.ScaleType.FIT_CENTER
+ val request = ImageRequest.Builder(imageView.context)
+ .target(imageView)
+ .error(R.drawable.no_banner)
+
+ if (width > 0 && height > 0) {
+ val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
+ bitmap.setPixels(vector, 0, width, 0, 0, width, height)
+ request.data(bitmap)
+ } else {
+ request.data(R.drawable.no_banner)
+ }
+ imageView.context.imageLoader.execute(request.build())
+ }
+
companion object {
private const val ARG_GAME_PATH = "game_path"
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/GridOptionDialogFragment.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/GridOptionDialogFragment.kt
index 94dda3f579..5f51038462 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/GridOptionDialogFragment.kt
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/GridOptionDialogFragment.kt
@@ -1,5 +1,6 @@
package org.dolphinemu.dolphinemu.fragments
+import android.app.Activity
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import android.view.LayoutInflater
import android.view.ViewGroup
@@ -88,7 +89,7 @@ class GridOptionDialogFragment : BottomSheetDialogFragment() {
NativeConfig.LAYER_BASE,
mBindingMobile.switchDownloadCovers.isChecked
)
- mView.reloadGrid()
+ (mView as Activity).recreate()
}
}
@@ -118,7 +119,7 @@ class GridOptionDialogFragment : BottomSheetDialogFragment() {
NativeConfig.LAYER_BASE,
mBindingTv.switchDownloadCovers.isChecked
)
- mView.reloadGrid()
+ (mView as Activity).recreate()
}
}
}
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/GameFile.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/GameFile.java
index b8de619e31..26f4c169ce 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/GameFile.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/GameFile.java
@@ -2,12 +2,15 @@
package org.dolphinemu.dolphinemu.model;
-import android.content.Context;
-
import androidx.annotation.Keep;
public class GameFile
{
+ public static int REGION_NTSC_J = 0;
+ public static int REGION_NTSC_U = 1;
+ public static int REGION_PAL = 2;
+ public static int REGION_NTSC_K = 4;
+
@Keep
private long mPointer;
@@ -68,11 +71,6 @@ public class GameFile
public native int getBannerHeight();
- public String getCoverPath(Context context)
- {
- return context.getExternalCacheDir().getPath() + "/GameCovers/" + getGameTdbId() + ".png";
- }
-
public String getCustomCoverPath()
{
return getPath().substring(0, getPath().lastIndexOf(".")) + ".cover.png";
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/TvMainActivity.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/TvMainActivity.java
index 0e1f55154b..2da1b8591d 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/TvMainActivity.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/TvMainActivity.java
@@ -349,7 +349,7 @@ public final class TvMainActivity extends FragmentActivity
}
// Create an adapter for this row.
- ArrayObjectAdapter row = new ArrayObjectAdapter(new GameRowPresenter());
+ ArrayObjectAdapter row = new ArrayObjectAdapter(new GameRowPresenter(this));
row.addAll(0, gameFiles);
// Keep a reference to the row in case we need to refresh it.
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/CoilUtils.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/CoilUtils.kt
new file mode 100644
index 0000000000..233f620d23
--- /dev/null
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/CoilUtils.kt
@@ -0,0 +1,95 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+package org.dolphinemu.dolphinemu.utils
+
+import android.net.Uri
+import android.view.View
+import android.widget.ImageView
+import coil.load
+import coil.target.ImageViewTarget
+import org.dolphinemu.dolphinemu.R
+import org.dolphinemu.dolphinemu.adapters.GameAdapter.GameViewHolder
+import org.dolphinemu.dolphinemu.features.settings.model.BooleanSetting
+import org.dolphinemu.dolphinemu.model.GameFile
+import java.io.File
+import java.io.FileNotFoundException
+
+object CoilUtils {
+ fun loadGameCover(
+ gameViewHolder: GameViewHolder?,
+ imageView: ImageView,
+ gameFile: GameFile,
+ customCoverUri: Uri?
+ ) {
+ imageView.scaleType = ImageView.ScaleType.FIT_CENTER
+ val imageTarget = ImageViewTarget(imageView)
+ if (customCoverUri != null) {
+ imageView.load(customCoverUri) {
+ error(R.drawable.no_banner)
+ target(
+ onSuccess = { success ->
+ disableInnerTitle(gameViewHolder)
+ imageTarget.drawable = success
+ },
+ onError = { error ->
+ enableInnerTitle(gameViewHolder)
+ imageTarget.drawable = error
+ }
+ )
+ }
+ } else if (BooleanSetting.MAIN_USE_GAME_COVERS.booleanGlobal) {
+ imageView.load(CoverHelper.buildGameTDBUrl(gameFile, CoverHelper.getRegion(gameFile))) {
+ error(R.drawable.no_banner)
+ target(
+ onSuccess = { success ->
+ disableInnerTitle(gameViewHolder)
+ imageTarget.drawable = success
+ },
+ onError = { error ->
+ enableInnerTitle(gameViewHolder)
+ imageTarget.drawable = error
+ }
+ )
+ }
+ } else {
+ imageView.load(R.drawable.no_banner)
+ enableInnerTitle(gameViewHolder)
+ }
+ }
+
+ private fun enableInnerTitle(gameViewHolder: GameViewHolder?) {
+ if (gameViewHolder != null && !BooleanSetting.MAIN_SHOW_GAME_TITLES.booleanGlobal) {
+ gameViewHolder.binding.textGameTitleInner.visibility = View.VISIBLE
+ }
+ }
+
+ private fun disableInnerTitle(gameViewHolder: GameViewHolder?) {
+ if (gameViewHolder != null && !BooleanSetting.MAIN_SHOW_GAME_TITLES.booleanGlobal) {
+ gameViewHolder.binding.textGameTitleInner.visibility = View.GONE
+ }
+ }
+
+ fun findCustomCover(gameFile: GameFile): Uri? {
+ val customCoverPath = gameFile.customCoverPath
+ var customCoverUri: Uri? = null
+ var customCoverExists = false
+ if (ContentHandler.isContentUri(customCoverPath)) {
+ try {
+ customCoverUri = ContentHandler.unmangle(customCoverPath)
+ customCoverExists = true
+ } catch (ignored: FileNotFoundException) {
+ } catch (ignored: SecurityException) {
+ // Let customCoverExists remain false
+ }
+ } else {
+ customCoverUri = Uri.parse(customCoverPath)
+ customCoverExists = File(customCoverPath).exists()
+ }
+
+ return if (customCoverExists) {
+ customCoverUri
+ } else {
+ null
+ }
+ }
+}
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/CoverHelper.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/CoverHelper.kt
index f1deeb3730..9359d38eb3 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/CoverHelper.kt
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/CoverHelper.kt
@@ -3,44 +3,34 @@
package org.dolphinemu.dolphinemu.utils
import org.dolphinemu.dolphinemu.model.GameFile
-import android.graphics.Bitmap
-import java.io.FileOutputStream
-import java.lang.Exception
object CoverHelper {
+ @JvmStatic
fun buildGameTDBUrl(game: GameFile, region: String?): String {
val baseUrl = "https://art.gametdb.com/wii/cover/%s/%s.png"
return String.format(baseUrl, region, game.gameTdbId)
}
+ @JvmStatic
fun getRegion(game: GameFile): String {
val region: String = when (game.region) {
- 0 -> "JA"
- 1 -> "US"
- 4 -> "KO"
- 2 -> when (game.country) {
- 3 -> "AU"
- 4 -> "FR"
- 5 -> "DE"
- 6 -> "IT"
- 8 -> "NL"
- 9 -> "RU"
- 10 -> "ES"
- 0 -> "EN"
+ GameFile.REGION_NTSC_J -> "JA"
+ GameFile.REGION_NTSC_U -> "US"
+ GameFile.REGION_NTSC_K -> "KO"
+ GameFile.REGION_PAL -> when (game.country) {
+ 3 -> "AU" // Australia
+ 4 -> "FR" // France
+ 5 -> "DE" // Germany
+ 6 -> "IT" // Italy
+ 8 -> "NL" // Netherlands
+ 9 -> "RU" // Russia
+ 10 -> "ES" // Spain
+ 0 -> "EN" // Europe
else -> "EN"
}
- 3 -> "EN"
+ 3 -> "EN" // Unknown
else -> "EN"
}
return region
}
-
- fun saveCover(cover: Bitmap, path: String?) {
- try {
- val out = FileOutputStream(path)
- cover.compress(Bitmap.CompressFormat.PNG, 100, out)
- out.close()
- } catch (ignored: Exception) {
- }
- }
}
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/GlideUtils.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/GlideUtils.kt
deleted file mode 100644
index ba2b9e344f..0000000000
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/GlideUtils.kt
+++ /dev/null
@@ -1,233 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-package org.dolphinemu.dolphinemu.utils
-
-import org.dolphinemu.dolphinemu.utils.CoverHelper.buildGameTDBUrl
-import org.dolphinemu.dolphinemu.utils.CoverHelper.getRegion
-import org.dolphinemu.dolphinemu.utils.CoverHelper.saveCover
-import android.os.Looper
-import org.dolphinemu.dolphinemu.model.GameFile
-import com.bumptech.glide.Glide
-import com.bumptech.glide.load.engine.DiskCacheStrategy
-import org.dolphinemu.dolphinemu.R
-import org.dolphinemu.dolphinemu.adapters.GameAdapter.GameViewHolder
-import android.app.Activity
-import android.graphics.Bitmap
-import android.graphics.drawable.BitmapDrawable
-import org.dolphinemu.dolphinemu.features.settings.model.BooleanSetting
-import com.bumptech.glide.request.RequestListener
-import android.graphics.drawable.Drawable
-import android.net.Uri
-import android.os.Handler
-import android.view.View
-import android.widget.ImageView
-import com.bumptech.glide.load.DataSource
-import com.bumptech.glide.load.engine.GlideException
-import com.bumptech.glide.request.target.CustomTarget
-import com.bumptech.glide.request.target.Target
-import com.bumptech.glide.request.transition.Transition
-import java.io.File
-import java.io.FileNotFoundException
-import java.util.concurrent.Executors
-
-object GlideUtils {
- private val saveCoverExecutor = Executors.newSingleThreadExecutor()
- private val unmangleExecutor = Executors.newSingleThreadExecutor()
- private val unmangleHandler = Handler(Looper.getMainLooper())
-
- fun loadGameBanner(imageView: ImageView, gameFile: GameFile) {
- val context = imageView.context
- val vector = gameFile.banner
- val width = gameFile.bannerWidth
- val height = gameFile.bannerHeight
- if (width > 0 && height > 0) {
- val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
- bitmap.setPixels(vector, 0, width, 0, 0, width, height)
- Glide.with(context)
- .load(bitmap)
- .diskCacheStrategy(DiskCacheStrategy.NONE)
- .centerCrop()
- .into(imageView)
- } else {
- Glide.with(context)
- .load(R.drawable.no_banner)
- .into(imageView)
- }
- }
-
- fun loadGameCover(
- gameViewHolder: GameViewHolder?,
- imageView: ImageView,
- gameFile: GameFile,
- activity: Activity?
- ) {
- gameViewHolder?.apply {
- if (BooleanSetting.MAIN_SHOW_GAME_TITLES.booleanGlobal) {
- binding.textGameTitle.text = gameFile.title
- binding.textGameTitle.visibility = View.VISIBLE
- binding.textGameTitleInner.visibility = View.GONE
- binding.textGameCaption.visibility = View.VISIBLE
- } else {
- binding.textGameTitleInner.text = gameFile.title
- binding.textGameTitle.visibility = View.GONE
- binding.textGameCaption.visibility = View.GONE
- }
- }
-
- unmangleExecutor.execute {
- val customCoverPath = gameFile.customCoverPath
- var customCoverUri: Uri? = null
- var customCoverExists = false
- if (ContentHandler.isContentUri(customCoverPath)) {
- try {
- customCoverUri = ContentHandler.unmangle(customCoverPath)
- customCoverExists = true
- } catch (ignored: FileNotFoundException) {
- // Let customCoverExists remain false
- } catch (ignored: SecurityException) {
- }
- } else {
- customCoverUri = Uri.parse(customCoverPath)
- customCoverExists = File(customCoverPath).exists()
- }
-
- val context = imageView.context
- val finalCustomCoverExists = customCoverExists
- val finalCustomCoverUri = customCoverUri
-
- val cover = File(gameFile.getCoverPath(context))
- val cachedCoverExists = cover.exists()
- unmangleHandler.post {
- // We can't get a reference to the current activity in the TV version.
- // Luckily it won't attempt to start loads on destroyed activities.
- if (activity != null) {
- // We can't start an image load on a destroyed activity
- if (activity.isDestroyed) {
- return@post
- }
- }
-
- if (finalCustomCoverExists) {
- Glide.with(imageView)
- .load(finalCustomCoverUri)
- .diskCacheStrategy(DiskCacheStrategy.NONE)
- .centerCrop()
- .error(R.drawable.no_banner)
- .listener(object : RequestListener<Drawable?> {
- override fun onLoadFailed(
- e: GlideException?,
- model: Any,
- target: Target<Drawable?>,
- isFirstResource: Boolean
- ): Boolean {
- enableInnerTitle(gameViewHolder)
- return false
- }
-
- override fun onResourceReady(
- resource: Drawable?,
- model: Any,
- target: Target<Drawable?>,
- dataSource: DataSource,
- isFirstResource: Boolean
- ): Boolean {
- disableInnerTitle(gameViewHolder)
- return false
- }
- })
- .into(imageView)
- } else if (cachedCoverExists) {
- Glide.with(imageView)
- .load(cover)
- .diskCacheStrategy(DiskCacheStrategy.NONE)
- .centerCrop()
- .error(R.drawable.no_banner)
- .listener(object : RequestListener<Drawable?> {
- override fun onLoadFailed(
- e: GlideException?,
- model: Any,
- target: Target<Drawable?>,
- isFirstResource: Boolean
- ): Boolean {
- enableInnerTitle(gameViewHolder)
- return false
- }
-
- override fun onResourceReady(
- resource: Drawable?,
- model: Any,
- target: Target<Drawable?>,
- dataSource: DataSource,
- isFirstResource: Boolean
- ): Boolean {
- disableInnerTitle(gameViewHolder)
- return false
- }
- })
- .into(imageView)
- } else if (BooleanSetting.MAIN_USE_GAME_COVERS.booleanGlobal) {
- Glide.with(context)
- .load(buildGameTDBUrl(gameFile, getRegion(gameFile)))
- .diskCacheStrategy(DiskCacheStrategy.NONE)
- .centerCrop()
- .error(R.drawable.no_banner)
- .listener(object : RequestListener<Drawable?> {
- override fun onLoadFailed(
- e: GlideException?,
- model: Any,
- target: Target<Drawable?>,
- isFirstResource: Boolean
- ): Boolean {
- enableInnerTitle(gameViewHolder)
- return false
- }
-
- override fun onResourceReady(
- resource: Drawable?,
- model: Any,
- target: Target<Drawable?>,
- dataSource: DataSource,
- isFirstResource: Boolean
- ): Boolean {
- disableInnerTitle(gameViewHolder)
- return false
- }
- })
- .into(object : CustomTarget<Drawable?>() {
- override fun onLoadCleared(placeholder: Drawable?) {}
- override fun onResourceReady(
- resource: Drawable,
- transition: Transition<in Drawable?>?
- ) {
- val savedCover = (resource as BitmapDrawable).bitmap
- saveCoverExecutor.execute {
- saveCover(
- savedCover,
- gameFile.getCoverPath(context)
- )
- }
- imageView.setImageBitmap(savedCover)
- }
- })
- } else {
- Glide.with(imageView.context)
- .load(R.drawable.no_banner)
- .into(imageView)
- enableInnerTitle(gameViewHolder)
- }
- }
- }
- }
-
- private fun enableInnerTitle(gameViewHolder: GameViewHolder?) {
- if (gameViewHolder != null && !BooleanSetting.MAIN_SHOW_GAME_TITLES.booleanGlobal) {
- gameViewHolder.binding.textGameTitleInner.visibility = View.VISIBLE
- }
- }
-
- private fun disableInnerTitle(gameViewHolder: GameViewHolder?) {
- if (gameViewHolder != null && !BooleanSetting.MAIN_SHOW_GAME_TITLES.booleanGlobal) {
- gameViewHolder.binding.textGameTitleInner.visibility = View.GONE
- }
- }
-}
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/TvUtil.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/TvUtil.java
index 940542ef49..57c567715c 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/TvUtil.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/TvUtil.java
@@ -186,9 +186,9 @@ public class TvUtil
}
}
- if (contentUri == null && (cover = new File(game.getCoverPath(context))).exists())
+ if (contentUri == null)
{
- contentUri = getUriForFile(context, getFileProvider(context), cover);
+ contentUri = Uri.parse(CoverHelper.buildGameTDBUrl(game, CoverHelper.getRegion(game)));
}
context.grantUriPermission(LEANBACK_PACKAGE, contentUri, FLAG_GRANT_READ_URI_PERMISSION);