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

[WebDAV] Streaming file handles can't report a size #963

Open
rfc2822 opened this issue Aug 7, 2024 · 0 comments
Open

[WebDAV] Streaming file handles can't report a size #963

rfc2822 opened this issue Aug 7, 2024 · 0 comments
Labels
webdav related to WebDAV file access

Comments

@rfc2822
Copy link
Member

rfc2822 commented Aug 7, 2024

Streaming file handles can't report a size, so the stat size is by design zero.

Some apps, like audio players or PDF viewers, however seem to call getStatSize() and then abort access when the value is 0.

Steps to reproduce

  • Add WebDAV mount
  • Make sure that random-access mode is not available for accessing a .wav or .pdf file, so DAVx5 uses a StreamingFileDescriptor instead of an RandomAccessCallback (view logs)
  • Access a .wav or .pdf file with with default AOSP client or some client that requests file size
  • Open the wav file
  • .wav client logs and closes itself:
Details
19:43:58.002   489-2910  MetadataRetrieverClient         E  offset (0) bigger than file size (0)
19:43:58.003   489-2910  MediaPlayerService              E  offset error
19:43:58.003 26243-26243 MediaPlayerNative               E  Unable to create media player
19:43:58.003 26243-26243 MediaPlayer                     W  Ignoring IO error while setting data source
                                                            java.io.IOException: setDataSourceFD failed.: status=0x80000000
                                                            	at android.media.MediaPlayer._setDataSource(Native Method)
                                                            	at android.media.MediaPlayer.setDataSource(MediaPlayer.java:1297)
                                                            	at android.media.MediaPlayer.setDataSource(MediaPlayer.java:1278)
                                                            	at android.media.MediaPlayer.setDataSource(MediaPlayer.java:1260)
                                                            	at android.media.MediaPlayer.attemptDataSource(MediaPlayer.java:1154)
                                                            	at android.media.MediaPlayer.setDataSource(MediaPlayer.java:1119)
                                                            	at android.media.MediaPlayer.setDataSource(MediaPlayer.java:1047)
                                                            	at gwp.b(PG:47)
                                                            	at com.google.android.apps.youtube.music.audiopreview.AudioPreviewPlayerActivity.onCreate(PG:5)
                                                            	at android.app.Activity.performCreate(Activity.java:8980)
                                                            	at android.app.Activity.performCreate(Activity.java:8958)
                                                            	at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1526)
                                                            	at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:4013)
                                                            	at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4218)
                                                            	at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:112)
                                                            	at android.app.servertransaction.TransactionExecutor.executeNonLifecycleItem(TransactionExecutor.java:174)
                                                            	at android.app.servertransaction.TransactionExecutor.executeTransactionItems(TransactionExecutor.java:109)
                                                            	at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:81)
                                                            	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2619)
                                                            	at android.os.Handler.dispatchMessage(Handler.java:107)
                                                            	at android.os.Looper.loopOnce(Looper.java:232)
                                                            	at android.os.Looper.loop(Looper.java:317)
                                                            	at android.app.ActivityThread.main(ActivityThread.java:8674)
                                                            	at java.lang.reflect.Method.invoke(Native Method)
                                                            	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:580)
                                                            	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:886)
19:43:58.003 26243-26243 MediaPlayerNative               E  prepareAsync called in state 1, mPlayer(0x0)
19:43:58.004 26243-26243 AudioPreview                    E  Exception occurred: null
19:43:58.007 26600-26853 TrafficStats                    D  tagSocket(120) with statsTag=0xffffffff, statsUid=-1
19:43:58.009 26600-26647 TrafficStats                    D  tagSocket(134) with statsTag=0xffffffff, statsUid=-1
19:43:58.011 26243-26243 AudioPreview                    E  Failed to set data source using MediaMetadataRetriever: content://at.bitfire.davdroid.webdav/document/32 with exception: java.lang.RuntimeException: setDataSource failed: status = 0xFFFFFFEA
                                                            java.lang.RuntimeException: setDataSource failed: status = 0xFFFFFFEA
                                                            	at android.media.MediaMetadataRetriever._setDataSource(Native Method)
                                                            	at android.media.MediaMetadataRetriever.setDataSource(MediaMetadataRetriever.java:310)
                                                            	at android.media.MediaMetadataRetriever.setDataSource(MediaMetadataRetriever.java:334)
                                                            	at android.media.MediaMetadataRetriever.setDataSource(MediaMetadataRetriever.java:383)
                                                            	at gwc.a(PG:1)
                                                            	at gwb.a(Unknown Source:6)
                                                            	at aosc.a(PG:3)
                                                            	at aqba.a(PG:1)
                                                            	at apzy.run(PG:4)
                                                            	at aqbc.run(PG:1)
                                                            	at snd.run(PG:1)
                                                            	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
                                                            	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644)
                                                            	at smj.run(PG:2)
                                                            	at java.lang.Thread.run(Thread.java:1012)
                                                            	at snu.run(PG:5)

  • DAVx5 file access is aborted because the pipe is broken#

Proposed solution

It seems that there is no way to return a file size when just returning two ParcelFileDescriptors, like the StreamingFileDescriptor currently does.

So we could use storageManager.openProxyFileDescriptor like for the RandomAccessCallback, and return a stat size.

Seek operations (= read from somewhere else than current position) could either fail, or even better, we could always

  • try partial file transfer, and
  • either return the correct part when the server returns 206,
  • or ignore the unrequested parts when the server returns 200 and only return the requested part.
@rfc2822 rfc2822 added the webdav related to WebDAV file access label Aug 7, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
webdav related to WebDAV file access
Projects
None yet
Development

No branches or pull requests

1 participant