Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Android song unable to find a specified URI #8111

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from

Conversation

Mindfulplays
Copy link
Contributor

Changed Android Song to differentiate between Assets/URI-based DataSource.

@tomspilman @mrhelmut

@mrhelmut
Copy link
Contributor

Not a big fan of a try/catch within a try/catch and exception being silenced.

Suggestion:

var afd = Game.Activity.Assets.OpenFd(_name);
if (afd != null)
     _androidPlayer.SetDataSource(afd.FileDescriptor, afd.StartOffset, afd.Length);
else
     _androidPlayer.SetDataSource(_name); // assuming that if anything is wrong here, the user did something wrong with their URI and we shouldn't silently handle the exception to let the user know

@Mindfulplays
Copy link
Contributor Author

Not a big fan of a try/catch within a try/catch and exception being silenced.

Suggestion:

var afd = Game.Activity.Assets.OpenFd(_name);
if (afd != null)
     _androidPlayer.SetDataSource(afd.FileDescriptor, afd.StartOffset, afd.Length);
else
     _androidPlayer.SetDataSource(_name); // assuming that if anything is wrong here, the user did something wrong with their URI and we shouldn't silently handle the exception to let the user know

OpenFd throws if the file is not found (it's for a file I am Playing outside the ContentManager system). I do agree its ugly but this lets me use MG Song with my own files (I wonder if this is useful at all to others? If not I can close this PR).

@Mindfulplays
Copy link
Contributor Author

Squashed commits to ease PR review, thanks!

@dellis1972
Copy link
Contributor

dellis1972 commented Jan 20, 2024

Can we make use of Uri.TryCreate to query if the argument is a Uri then call the appropriate method?

Uri.TryCreate ("http://foo", UriKind.Absolute, out Uri result);

This code above will return true in this case, but false if you just passed say Assets/foo.xnb

@Mindfulplays
Copy link
Contributor Author

Can we make use of Uri.TryCreate to query if the argument is a Uri then call the appropriate method?

Uri.TryCreate ("http://foo", UriKind.Absolute, out Uri result);

This code above will return true in this case, but false if you just passed say Assets/foo.xnb

This is an Android problem not an dotnet Uri problem :( Android assumes that you know that you know the file you are accessing. The Uri itself would still be considered valid either way.

Or perhaps I am missing something else?

@dellis1972
Copy link
Contributor

So the Pr description says this is about knowing the difference between an "Asset" and a "Uri".
The problem is Game.Activity.Assets.OpenFd(_name); will throw if passed a Uri rather than an "Asset".
Things retrieved via the ContentManager do not usually have a Uri based filenames if I remember rightly. Its more like "Assets/songs/mysong.xnb" , which Uri.TryCreate will return false for.
If that is the case we could do

if (!Uri.TryCreate ("http://foo", UriKind.Absolute, out Uri result)) {
    var afd = Game.Activity.Assets.OpenFd(_name);
    if (afd != null)
       _androidPlayer.SetDataSource(afd.FileDescriptor, afd.StartOffset, afd.Length);
} else {
    _androidPlayer.SetDataSource(_name);
}

I could be wrong about the Uri, its been a while since took a look at that code.

On a side note its not really good practice to swallow exceptions in a library if you can help it. There are a number of reasons why a file might not exist. The main one on Android is someone using the incorrect Filename casing as its a case sensitive file system. If we swallow the exception the developer will have no idea what happened in code, the only hint would be the Song not playing. Not everyone will read the adb logcat output to figure out what is happening.

So you have some samples of the kinds of values that get passed to _name in this case? one for assets and the other for direct file access?

@mrhelmut
Copy link
Contributor

Couldn't we just have something like _name.StartsWith("file://") to differentiate content from external files?

            if (assetUri != null)
            {
                _androidPlayer.SetDataSource(MediaLibrary.Context, this.assetUri);
            }
            else if (_name.StartsWith("file://"))
            {
                _androidPlayer.SetDataSource(_name);
            }
            else
            {
                var afd = Game.Activity.Assets.OpenFd(_name);
                if (afd == null)
                    return;

                _androidPlayer.SetDataSource(afd.FileDescriptor, afd.StartOffset, afd.Length);
            }

- `Assets.OpenFd` throw if the given filename does not exist.
- So a hack to try `OpenFd` if not `SetDataSource` next with cascading `try/catch`.
@Mindfulplays
Copy link
Contributor Author

Good idea @mrhelmut fixed, please take a look.

Copy link
Contributor

@dellis1972 dellis1972 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks ok to me 👍

@dellis1972 dellis1972 requested a review from mrhelmut March 6, 2024 13:48
@dellis1972
Copy link
Contributor

@mrhelmut can we get one last look at this one please? If its good, I'll merge it.

@Mindfulplays
Copy link
Contributor Author

Gentle ping...

@mrhelmut
Copy link
Contributor

mrhelmut commented Mar 8, 2024

I'm a bit on the fence with the unnecessary changes I commented.

@Mindfulplays
Copy link
Contributor Author

FWIW, the code 'works' :) but yeah, lmk if it might break existing code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants