Merge pull request #11017 from JosJuice/saf-custom-cover
Android: Fix reading custom covers with SAF
This commit is contained in:
commit
11281b5cef
|
@ -61,7 +61,7 @@ public class GameFileCache
|
||||||
String path = dolphinIni.getString(Settings.SECTION_INI_GENERAL,
|
String path = dolphinIni.getString(Settings.SECTION_INI_GENERAL,
|
||||||
SettingsFile.KEY_ISO_PATH_BASE + i, "");
|
SettingsFile.KEY_ISO_PATH_BASE + i, "");
|
||||||
|
|
||||||
if (path.startsWith("content://") ? ContentHandler.exists(path) : new File(path).exists())
|
if (ContentHandler.isContentUri(path) ? ContentHandler.exists(path) : new File(path).exists())
|
||||||
{
|
{
|
||||||
pathSet.add(path);
|
pathSet.add(path);
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,11 @@ import java.util.function.Predicate;
|
||||||
|
|
||||||
public class ContentHandler
|
public class ContentHandler
|
||||||
{
|
{
|
||||||
|
public static boolean isContentUri(@NonNull String pathOrUri)
|
||||||
|
{
|
||||||
|
return pathOrUri.startsWith("content://");
|
||||||
|
}
|
||||||
|
|
||||||
@Keep
|
@Keep
|
||||||
public static int openFd(@NonNull String uri, @NonNull String mode)
|
public static int openFd(@NonNull String uri, @NonNull String mode)
|
||||||
{
|
{
|
||||||
|
@ -336,7 +341,7 @@ public class ContentHandler
|
||||||
* provider to use URIs without any % characters.
|
* provider to use URIs without any % characters.
|
||||||
*/
|
*/
|
||||||
@NonNull
|
@NonNull
|
||||||
private static Uri unmangle(@NonNull String uri) throws FileNotFoundException, SecurityException
|
public static Uri unmangle(@NonNull String uri) throws FileNotFoundException, SecurityException
|
||||||
{
|
{
|
||||||
int lastComponentEnd = getLastComponentEnd(uri);
|
int lastComponentEnd = getLastComponentEnd(uri);
|
||||||
int lastComponentStart = getLastComponentStart(uri, lastComponentEnd);
|
int lastComponentStart = getLastComponentStart(uri, lastComponentEnd);
|
||||||
|
|
|
@ -82,9 +82,16 @@ public final class FileBrowserHelper
|
||||||
return isPathEmptyOrValid(path.getStringGlobal());
|
return isPathEmptyOrValid(path.getStringGlobal());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if at least one of the following applies:
|
||||||
|
*
|
||||||
|
* 1. The input is empty.
|
||||||
|
* 2. The input is something which is not a content URI.
|
||||||
|
* 3. The input is a content URI that points to a file that exists and we're allowed to access.
|
||||||
|
*/
|
||||||
public static boolean isPathEmptyOrValid(String path)
|
public static boolean isPathEmptyOrValid(String path)
|
||||||
{
|
{
|
||||||
return !path.startsWith("content://") || ContentHandler.exists(path);
|
return !ContentHandler.isContentUri(path) || ContentHandler.exists(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void runAfterExtensionCheck(Context context, Uri uri, Set<String> validExtensions,
|
public static void runAfterExtensionCheck(Context context, Uri uri, Set<String> validExtensions,
|
||||||
|
|
|
@ -18,6 +18,7 @@ import org.dolphinemu.dolphinemu.model.GameFile;
|
||||||
import org.dolphinemu.dolphinemu.viewholders.GameViewHolder;
|
import org.dolphinemu.dolphinemu.viewholders.GameViewHolder;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
|
||||||
public class PicassoUtils
|
public class PicassoUtils
|
||||||
{
|
{
|
||||||
|
@ -54,12 +55,33 @@ public class PicassoUtils
|
||||||
gameViewHolder.textGameCaption.setVisibility(View.GONE);
|
gameViewHolder.textGameCaption.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String customCoverPath = gameFile.getCustomCoverPath();
|
||||||
|
Uri customCoverUri = null;
|
||||||
|
boolean customCoverExists = false;
|
||||||
|
if (ContentHandler.isContentUri(customCoverPath))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
customCoverUri = ContentHandler.unmangle(customCoverPath);
|
||||||
|
customCoverExists = true;
|
||||||
|
}
|
||||||
|
catch (FileNotFoundException | SecurityException ignored)
|
||||||
|
{
|
||||||
|
// Let customCoverExists remain false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
customCoverUri = Uri.parse(customCoverPath);
|
||||||
|
customCoverExists = new File(customCoverPath).exists();
|
||||||
|
}
|
||||||
|
|
||||||
Context context = imageView.getContext();
|
Context context = imageView.getContext();
|
||||||
File cover = new File(gameFile.getCustomCoverPath());
|
File cover;
|
||||||
if (cover.exists())
|
if (customCoverExists)
|
||||||
{
|
{
|
||||||
Picasso.get()
|
Picasso.get()
|
||||||
.load(cover)
|
.load(customCoverUri)
|
||||||
.noFade()
|
.noFade()
|
||||||
.noPlaceholder()
|
.noPlaceholder()
|
||||||
.fit()
|
.fit()
|
||||||
|
|
|
@ -34,6 +34,7 @@ import org.dolphinemu.dolphinemu.services.SyncProgramsJobService;
|
||||||
import org.dolphinemu.dolphinemu.ui.platform.Platform;
|
import org.dolphinemu.dolphinemu.ui.platform.Platform;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@ -155,26 +156,43 @@ public class TvUtil
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Leanback lanucher requires a uri for poster art so we create a contentUri and
|
* Leanback launcher requires a uri for poster art so we create a contentUri and
|
||||||
* pass that to LEANBACK_PACKAGE
|
* pass that to LEANBACK_PACKAGE
|
||||||
*/
|
*/
|
||||||
public static Uri buildBanner(GameFile game, Context context)
|
public static Uri buildBanner(GameFile game, Context context)
|
||||||
{
|
{
|
||||||
Uri contentUri = null;
|
Uri contentUri = null;
|
||||||
|
File cover;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
File cover = new File(game.getCustomCoverPath());
|
String customCoverPath = game.getCustomCoverPath();
|
||||||
if (cover.exists())
|
|
||||||
|
if (ContentHandler.isContentUri(customCoverPath))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
contentUri = ContentHandler.unmangle(customCoverPath);
|
||||||
|
}
|
||||||
|
catch (FileNotFoundException | SecurityException ignored)
|
||||||
|
{
|
||||||
|
// Let contentUri remain null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ((cover = new File(customCoverPath)).exists())
|
||||||
|
{
|
||||||
|
contentUri = getUriForFile(context, getFileProvider(context), cover);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (contentUri == null && (cover = new File(game.getCoverPath(context))).exists())
|
||||||
{
|
{
|
||||||
contentUri = getUriForFile(context, getFileProvider(context), cover);
|
contentUri = getUriForFile(context, getFileProvider(context), cover);
|
||||||
}
|
}
|
||||||
else if ((cover = new File(game.getCoverPath(context))).exists())
|
|
||||||
{
|
context.grantUriPermission(LEANBACK_PACKAGE, contentUri, FLAG_GRANT_READ_URI_PERMISSION);
|
||||||
contentUri = getUriForFile(context, getFileProvider(context), cover);
|
|
||||||
}
|
|
||||||
context.grantUriPermission(LEANBACK_PACKAGE, contentUri,
|
|
||||||
FLAG_GRANT_READ_URI_PERMISSION);
|
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue