Intent to Ship: File System Access on Android and WebView

910 views
Skip to first unread message

Joel Hockey

unread,
Sep 4, 2024, 8:53:46 PM9/4/24
to blink-dev
Contact emails

joelh...@chromium.org


Spec

https://wicg.github.io/file-system-access/


Summary

This feature has been supported on the 4 other platforms since M86 and will now be supported on the remaining 2 platforms.


Android platform and its use of Intents rather than file choosers, and content-URIs rather than posix-style paths and semantics provides some challenges, but the intention is that existing code such as the demo link will work unchaged for users to read and / or edit files.


There is one area where I am considering proposing a change to the spec that showOpenFilePicker() could take a boolean hint to indicate the intention of whether files are intended for read-only vs writable which would allow Android to choose between Intent GET_CONTENT (read-only, but supported by more providers) vs OPEN_DOCUMENT (allows for writing to files, but not supported by as many providers).


Original Chrome Status:

https://chromestatus.com/feature/6284708426022912


Original Intent-to-Ship:

https://groups.google.com/a/chromium.org/g/blink-dev/c/9Fcpl2KVfbk


Link to “Intent to Prototype” blink-dev discussion

See Original Intent-to-Ship


Link to Origin Trial feedback summary

See Original Intent-to-Ship


Is this feature supported on all six Blink platforms (Windows, Mac, Linux, Chrome OS, Android, and Android WebView)?

It is now.


Demo link

https://file-system-access-demo.glitch.me/


Debuggability

See Original Intent-to-Ship.  Devtools is a little more challenging on android, so I would expect most devs would debug their code on one of the other 4 platforms, but devtools can still be used.


Measurement


Risks

Interoperability and Compatibility

This spec is already proven. Support for the remaining 2 platforms only improves interoperability and compatibility.


Ergonomics

Android uses Intents where other platforms use a file-chooser. The common intents to open a file are GET_CONTENT (read-only, but supported by more providers) vs OPEN_DOCUMENT (writable files, but not as many providers). As stated above, I am considering proposing a change to the API to give JS code control over this.


Android files (content-URIs) do not support atomic writes, or atomic renames. As such, not all operations will be supported, or some operations like move will be implemented as copy. I am in discussion with the Android storage team about what can be possible in the future, but any changes will take time (years).


Activation

Developers already have code using this.


Is this feature fully tested by web-platform-tests? Link to test suite results from wpt.fyi.

Yes, but chromium project does not currently run WPT for android.

https://chromium.googlesource.com/chromium/src/+/HEAD/docs/testing/web_tests.md#:~:text=Android%20is%20not%20supported.


https://wpt.fyi/results/fs

https://wpt.fyi/results/file-system-access


Entry on the feature dashboard

https://chromestatus.com/feature/6284708426022912

Thomas Steiner

unread,
Sep 5, 2024, 5:31:00 AM9/5/24
to Joel Hockey, blink-dev
Very excited for this feature to come, it's a frequently requested gap so far—frequently enough to link to the FSA for Android bug from our developer-facing documentation
 

There is one area where I am considering proposing a change to the spec that showOpenFilePicker() could take a boolean hint to indicate the intention of whether files are intended for read-only vs writable which would allow Android to choose between Intent GET_CONTENT (read-only, but supported by more providers) vs OPEN_DOCUMENT (allows for writing to files, but not supported by as many providers).


I've just commented on a relevant GitHub issue and tagged you.

Joel Hockey

unread,
Oct 25, 2024, 7:06:31 PM10/25/24
to Thomas Steiner, blink-dev
The FileSystemAccessLocal feature has just been enabled for android in M132.

Thomas Steiner

unread,
Oct 28, 2024, 5:09:59 AM10/28/24
to Joel Hockey, Thomas Steiner, blink-dev
Wow, that's fantastic news! 

I tried the feature on 132.0.6803.0 on Android VanillaIceCream with this demo that uses the main window, a same origin iframe, and a cross origin iframe (the last one should not work). 
  • Opening a single file and multiple files works just fine. A slight user irritation was the camera and microphone permission, but it made sense once I saw the picker, which is a camera and the files icons.
  • File MIME type filters seem to be ignored. I filtered on images and texts, but could open a PDF.
  • Opening folders works just fine. You need to be careful to not open a too big folder. Attempting to open DCIM caused Canary to become unresponsive.
  • Saving seems to not work quite yet. While it did trigger the same picker with the files and the camera icons (the camera should probably not be there, it should just enter the files flow directly), there was in the end no obvious way for me to say "yes, save here", that is, some sort of file name dialog. Did I not understand what I needed to do?
Amazing work. I suppose the rest is polish and already known issues. 

Cheers,
Tom

--
Thomas Steiner, PhD—Developer Relations Engineer (blog.tomayac.comtoot.cafe/@tomayac)

Google Germany GmbH, ABC-Str. 19, 20354 Hamburg, Germany
Geschäftsführer: Paul Manicle, Liana Sebastian
Registergericht und -nummer: Hamburg, HRB 86891

----- BEGIN PGP SIGNATURE -----
Version: GnuPG v2.4.3 (GNU/Linux)

iFy0uwAntT0bE3xtRa5AfeCheCkthAtTh3reSabiGbl0ck
0fjumBl3DCharaCTersAttH3b0ttom.xKcd.cOm/1181.
----- END PGP SIGNATURE -----

Ashley Gullen

unread,
Oct 28, 2024, 8:50:29 AM10/28/24
to Thomas Steiner, Joel Hockey, blink-dev
I'd be very happy to see the File System Access API ship on Android! However from my testing it doesn't look ready yet. Using our PWA Construct (https://editor.construct.net) in Canary 132, create a new empty project and try saving it with Menu > Project > Save as, and:
  • Choosing 'Save as single file' shows a range of apps (some inappropriate including Camera) - choosing 'Files' then shows what appears to be a file picker. The aim here is to have a save-as operation and be able to choose a new file - but there doesn't seem to be any obvious way to choose a new filename here, it looks like you can only overwrite existing files.
  • Choosing 'Save as project folder' shows a folder picker right away. If I go to Documents, create a new folder named TestProject, tap 'Use this folder', approve the permission prompt (saying 'Allow'), and then approve a second permission prompt (this one saying 'Edit files'), it then shows an 'Unable to save project' error message. This appears to be because it throws 'InvalidStateError: An operation that depends on state cached in an interface object was made but the state had changed since it was read from disk.'
These are basic use cases for the File System Access API in our PWA. Would be great if someone could take a look.


--
You received this message because you are subscribed to the Google Groups "blink-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to blink-dev+...@chromium.org.
To view this discussion visit https://groups.google.com/a/chromium.org/d/msgid/blink-dev/CALgRrL%3D05USBgLCdEgg3k9bcxB%2BzU3YXpXU9i8egymV3KJLQbA%40mail.gmail.com.

Peter Beverloo

unread,
Oct 28, 2024, 8:57:40 AM10/28/24
to Ashley Gullen, Thomas Steiner, Joel Hockey, blink-dev
Hi Joel, could you summarise how this has ended up working on WebView, as there's neither permissions nor UI there? Will apps using WebView have to adopt anything?

Thanks,
Peter


Joel Hockey

unread,
Oct 29, 2024, 3:27:27 AM10/29/24
to Peter Beverloo, Ashley Gullen, Thomas Steiner, blink-dev
Thanks Tom and Ashley, I've created:

crbug.com/376097107 - Android FileSystemAccess mime filters are being ignored
crbug.com/376097630 - Android FileSystemAccess opening folder with many files causes chrome to become unresponsive
crbug.com/376097108 - Android FileSystemAccess save-as does not allow creating a new file, only selecting existing
crbug.com/376097631 - Android FileSystemAccess save as project folder fails

I don't think clank (chrome on android) currently has any code that does file-saveas, so the interface between chrome and the OS might not have all the required Intent options.  I'll take a look at that and the other issues.

Peter, apps that use webview will need to implement WebChromeClient#onShowFileChooser() for the JS code window.showOpenFilePicker() / showDirectoryPicker() / showSaveFilePicker().  I am working on adding more options to WebChromeClient.FileChooserParams to make it clearer when each is being used.  The additional options will be available in a future (should be the next) API release.  For permissions, the assumption is that if / when the app makes files available to JS code via onShowFileChooser(), the files are considered to have edit permissions.  Any app that does not want to allow JS code to edit files should either not implement onShowFileChooser(), or should apply filtering.

Thomas Steiner

unread,
Oct 29, 2024, 4:02:04 AM10/29/24
to Joel Hockey, Peter Beverloo, Ashley Gullen, Thomas Steiner, blink-dev
On Tue, Oct 29, 2024 at 8:27 AM Joel Hockey <joelh...@chromium.org> wrote:
Thanks Tom and Ashley, I've created:

crbug.com/376097107 - Android FileSystemAccess mime filters are being ignored
crbug.com/376097630 - Android FileSystemAccess opening folder with many files causes chrome to become unresponsive
crbug.com/376097108 - Android FileSystemAccess save-as does not allow creating a new file, only selecting existing

Thanks for filing all of those!
 
crbug.com/376097631 - Android FileSystemAccess save as project folder fails

Ashley, I wonder how you save as a folder, though? That's not even supported with showSaveFilePicker(). I don't think that's a feature of the File System Access API at all, only save as a file. Is the actual bug that you're reporting that showDirectoryPicker({mode: 'readwrite'}) doesn't work as intended? That's technically save, not save as

Peter Beverloo

unread,
Oct 29, 2024, 5:56:49 AM10/29/24
to Joel Hockey, Ashley Gullen, Thomas Steiner, blink-dev
On Tue, Oct 29, 2024 at 7:27 AM Joel Hockey <joelh...@chromium.org> wrote:
Thanks Tom and Ashley, I've created:

crbug.com/376097107 - Android FileSystemAccess mime filters are being ignored
crbug.com/376097630 - Android FileSystemAccess opening folder with many files causes chrome to become unresponsive
crbug.com/376097108 - Android FileSystemAccess save-as does not allow creating a new file, only selecting existing
crbug.com/376097631 - Android FileSystemAccess save as project folder fails

I don't think clank (chrome on android) currently has any code that does file-saveas, so the interface between chrome and the OS might not have all the required Intent options.  I'll take a look at that and the other issues.

Peter, apps that use webview will need to implement WebChromeClient#onShowFileChooser() for the JS code window.showOpenFilePicker() / showDirectoryPicker() / showSaveFilePicker().  I am working on adding more options to WebChromeClient.FileChooserParams to make it clearer when each is being used.  The additional options will be available in a future (should be the next) API release.  For permissions, the assumption is that if / when the app makes files available to JS code via onShowFileChooser(), the files are considered to have edit permissions.  Any app that does not want to allow JS code to edit files should either not implement onShowFileChooser(), or should apply filtering.

Great, thank you for the additional detail. Please feel free to reach out if there's bits/reviews we can help with! One thing to keep in mind is that there's already ~30k apps that have adopted the existing onShowFileChooser() w/ quite some daily usage, we should make sure that the defaults avoid any surprises there, security, privacy or otherwise.

Ashley Gullen

unread,
Oct 29, 2024, 6:49:54 AM10/29/24
to Peter Beverloo, Joel Hockey, Thomas Steiner, blink-dev
Thanks for filing the issues!

Re 'save as folder': yes, it's just showDirectoryPicker({ mode: "readwrite" }). We just describe that as "save as" in our own UI (as it basically means "choose the location with a dialog"). My main point is that things that work on desktop Chrome aren't currently working on Android.

Ashley

Thomas Steiner

unread,
Oct 29, 2024, 7:00:14 AM10/29/24
to Ashley Gullen, Peter Beverloo, Joel Hockey, Thomas Steiner, blink-dev
Re 'save as folder': yes, it's just showDirectoryPicker({ mode: "readwrite" }). We just describe that as "save as" in our own UI (as it basically means "choose the location with a dialog"). My main point is that things that work on desktop Chrome aren't currently working on Android.

Gotcha, thanks for the clarification. So it was as I expected… :-) You didn't magically discover `showSaveDirectoryPicker()`, which, actually, is a feature request. Apart from the semantically confusing Open vs. Save in the UI (below on macOS), your workaround actually gets us more than half-way there…

Screenshot 2024-10-29 at 11.58.00.png
Screenshot 2024-10-29 at 11.58.17.png

Joel Hockey

unread,
Oct 30, 2024, 4:40:54 AM10/30/24
to Thomas Steiner, Ashley Gullen, Peter Beverloo, blink-dev
I've got fixes for mime-types and save-as.

Ashley, I tried out the app and saw how it fails for "save as project folder".  I haven't looked at the JS code you have, but I'm guessing that the problem is that the android implementation of FileSystemHandle is missing some features such as
dirHandle.getFileHandle(name, {create: true})


Android uses content-URIs for file paths, which don't work the same as posix paths where you can append files inside a parent dir.  I'll take a look at this more and see what we can do, but a lot of things in android depend on both the APIs available and which file providers have implemented them and how.

Can you confirm if you are using getFileHandle() or if you are able to detect which specific call is failing?

Ashley Gullen

unread,
Oct 30, 2024, 6:55:21 AM10/30/24
to Joel Hockey, Thomas Steiner, Peter Beverloo, blink-dev
Yes, we use dirHandle.getFileHandle(name, { create: true }). We use that to create new files in the chosen folder. That is fundamental to how our PWA saves data in folders (and I'd have thought fundamental to the use of a directory picker).

Jeffrey Yasskin

unread,
Oct 30, 2024, 11:58:51 AM10/30/24
to Joel Hockey, Ashley Gullen, Thomas Steiner, Peter Beverloo, blink-dev
It seems like the "Interoperability and Compatibility" section for this Intent is misleading: shipping a piece of an API can cause compatibility problems if developers were feature-detecting the API as a whole, and then a function is missing or doesn't work after they've already committed to the "use the API" path. Do you have metrics for how many sites will break like this?

How do you intend developers to feature-detect the fraction of the API that works on Android? If there's no good story for that, perhaps this shouldn't ship until there is. (My sense matches Ashley's, that Android doesn't actually support opening directories if it can't then open files inside those directories, so perhaps the `showDirectoryPicker` function should be omitted.)

I also see that this re-used the overall File System Access Chrome Status entry, so the API owners weren't prompted to actually LGTM it, and there are no LGTMs on this thread. The launch process doesn't explicitly describe the case of adding some platforms to a shipped feature, but I think the right thing to do is to click the "Add Stage" button at the bottom of the page, to add a new "Prepare to Ship" stage, and then request API Owner review from that stage.

Jeffrey

--
You received this message because you are subscribed to the Google Groups "blink-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to blink-dev+...@chromium.org.

Joel Hockey

unread,
Nov 1, 2024, 8:56:43 AM11/1/24
to blink-dev, Jeffrey Yasskin, Ashley Gullen, Thomas Steiner, Peter Beverloo, blink-dev, Joel Hockey
Ashley, I've got some fixes coming for the getFileHandle() call.  I've been able to test with your app and it is working.  I'm hoping to land them next week, but part of my change touches a lot of internal APIs, so review make take some time.

Jeffrey, I think I've got the interop and compat better now, and if other devs find bugs, I'm hopeful that I can get code that can run unchanged on android.  I've taken guidance from the Web Platform reviewer in launch/4341240 for doing this I2S.  I'm not very familliar with the overall process, and I'm not sure what anyone is expecting in regard to LGTMs.  I don't see any "Add Stage" button on the entry when I'm logged in.

Joel Hockey

unread,
Nov 12, 2024, 6:55:04 PM11/12/24
to Joel Hockey, blink-dev, Jeffrey Yasskin, Ashley Gullen, Thomas Steiner, Peter Beverloo
The FileSystemAccess API is enabled for android and webview in M132 and expecting to release to stable in Jan, 2025.

Thanks to Ashley and others who have already tested, we have been able to fix some missing pieces that were tricky for android.  Please do let me know if there are other issues or bugs.

The blink-api-owners have approved shipping this API on android, and suggested that PSA is sufficient for a case like this where an API already exists on existing platforms.

Mike Taylor

unread,
Nov 12, 2024, 8:00:55 PM11/12/24
to Joel Hockey, Joel Hockey, blink-dev, Jeffrey Yasskin, Ashley Gullen, Thomas Steiner, Peter Beverloo

Thank you Joel for your work to enable this on Andoid and Webview, and thanks to you and others for ensuring we ship quality features everywhere. :)

Ashley Gullen

unread,
Nov 14, 2024, 4:18:35 AM11/14/24
to Mike Taylor, Joel Hockey, Joel Hockey, blink-dev, Jeffrey Yasskin, Thomas Steiner, Peter Beverloo
Just re-tried this and it's working a lot better in the latest Canary! Thanks for the fixes.

One more issue I noticed though is that save prompts don't appear to add a default file extension. Using our PWA (https://editor.construct.net), create a new empty project and try saving it with Menu > Project > Save as > Save as single file. This uses showSaveFilePicker() passing an option like this:

"types": [{
  "description": ...,
  "accept": {
    "application/x-construct3-project": [".c3p"]
  }
}]

On Windows in the save prompt, type 'test' as the filename and save in the Documents folder, and it saves a file named 'test.c3p' (including the specified .c3p file extension). On Android if you do this it saves a file named 'test' with no file extension, whereas I expected it to also include the default file extension .c3p. Otherwise the user has to explicitly type in the file extension to save a file that is correctly identified by its file extension.

Joel Hockey

unread,
Nov 14, 2024, 7:43:45 PM11/14/24
to Ashley Gullen, Mike Taylor, Joel Hockey, blink-dev, Jeffrey Yasskin, Thomas Steiner, Peter Beverloo
From my testing, chromeos sets a default extension, but linux doesn't.

Android doesn't support default extensions, but it does support setting the default filename.  I have created crbug.com/379140421 to set that via showSaveFilePicker optional suggestedName field.

Ashley Gullen

unread,
Jan 21, 2025, 6:52:08 AMJan 21
to Joel Hockey, Mike Taylor, Joel Hockey, blink-dev, Jeffrey Yasskin, Thomas Steiner, Peter Beverloo
I was happy to see this ship in the latest M132 release, but I ran in to another bug, so just as a heads up I'm linking it here: https://issues.chromium.org/issues/391283117

Ashley
Reply all
Reply to author
Forward
0 new messages