cordova-android icon indicating copy to clipboard operation
cordova-android copied to clipboard

Feature Request: Support showDirectoryPicker and showSaveFilePicker in SystemWebChromeClient for WebView 132+

Open nonameShijian opened this issue 11 months ago • 5 comments

Feature Request

Modify the onShowFileChooser method within the SystemWebChromeClient class to implement corresponding folder selection or save functionality when the fileChooserParams parameter is set to MODE_OPEN_FOLDER or MODE_SAVE.

Motivation Behind Feature

In WebView versions 132 and above, resolve the errors where JavaScript's showDirectoryPicker and showSaveFilePicker methods result in "The user aborted a request" responses.

Feature Description

In WebView versions 132 and above, support has been introduced for the following new methods:

  • showDirectoryPicker
  • showSaveFilePicker
  • showOpenFilePicker  I have observed that showOpenFilePicker works correctly, but showDirectoryPicker and showSaveFilePicker return errors indicating "The user aborted a request".  Upon examining the source code, I found that the onShowFileChooser method within the SystemWebChromeClient class can support these functionalities based on the fileChooserParams parameter. However, Cordova currently lacks support for these features.

Are there any drawbacks? Will this break anything for existing users?

 It is important to consider potential compatibility issues with existing applications. The implementation should be carefully tested to ensure it does not introduce regressions.

Alternatives or Workarounds

Proposed Solution: Modify the onShowFileChooser method within the SystemWebChromeClient class so that it implements the appropriate folder selection or save operations when the fileChooserParams parameter indicates MODE_OPEN_FOLDER or MODE_SAVE.  However, I have not attempted this solution myself due to my limited expertise in this area.

nonameShijian avatar Feb 06 '25 07:02 nonameShijian

This could be an Android issue, I can't find any documentation on it but on an unrelated Android project with no cordova, even if you try to handle for MODE_OPEN_FOLDER or MODE_SAVE, it still just returns a "The user aborted a request" response.

bastecklein avatar Mar 10 '25 21:03 bastecklein

We'd like to make use of the new support for the File System Access API in Cordova on Android for Construct, and after finding it not working, I ended up here, so that's a long winded way of saying +1.

What I found is some key remarks in this Intent to Ship email thread for File System Access on Android and WebView. Some key quotes:

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?

...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.

It looks like in cordova-android's source code SystemWebChromeClient.java already has an implementation for onShowFileChooser() - see here. The Android documentation for onShowFileChooser() includes in the description:

This is called to handle HTML forms with 'file' input type

So I would guess what has happened is the old onShowFileChooser() method previously existed for <input type="file"> and Cordova supported it, but now with support for the File System Access API there are new modes/options in that method that Cordova needs to take in to account. I've found in other webview test apps the "user aborted request" error comes up too, presumably because as with Cordova they also are not implementing the necessary path through onShowFileChooser().

It's not clear to me if the mentioned updates to WebChromeClient.FileChooserParams are now available - I'd guess not from a glance at the documentation, so perhaps we will have to wait for a future API update. Once available I'd consider paying for a developer's time to implement this - contact me at [email protected] if any Cordova developers are interested.

The code from this site looks like it can be used as a test case for implementing this: https://file-system-access-demo.glitch.me/

AshleyScirra avatar Mar 27 '25 10:03 AshleyScirra

Hi folks, any update on this? I'm happy to sponsor development work.

AshleyScirra avatar Jun 17 '25 09:06 AshleyScirra

@AshleyScirra

I took a quick glance but I'm not sure what changes are required to get this working properly.

I'm happy to sponsor development work.

PRs are always welcome.


Because I'm not very familiar with the new APIs or what's needed on the native side, I created a native app without Cordova to see how things behave without Cordova's internal logic.

It contains a WebView element, and I attached a WebChromeClient to override onShowFileChooser. The override simply logs a message to confirm it's being triggered and then defers to the superclass:

webView.setWebChromeClient(new WebChromeClient() {
    @Override
    public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams) {
        Log.e("MyApp", "onShowFileChooser was called");
        return super.onShowFileChooser(webView, filePathCallback, fileChooserParams);
    }
});

When clicking the DOM element <input type="file" /> or using the JS API window.showOpenFilePicker(), I can see that onShowFileChooser is triggered, as the log is printed.

However, when using window.showOpenFilePicker(), I also see this error:

AbortError: Failed to execute 'showOpenFilePicker' on 'Window': The user aborted a request.

I tried using a WebViewAssetLoader to serve the content from https://myapp/ instead of using the file:// scheme, to rule out any limitations with the file scheme, but the results were the same.

I also added buttons to test the following APIs:

  • window.showDirectoryPicker()
  • window.showSaveFilePicker()

Clicking those buttons does not trigger onShowFileChooser. I suspect this is expected behavior, but I'm not familiar with the expected native-side handling of these newer APIs.

In the developer tools, I also see the following errors for those calls:

AbortError: Failed to execute 'showDirectoryPicker' on 'Window': The user aborted a request. AbortError: Failed to execute 'showSaveFilePicker' on 'Window': The user aborted a request.

I was reading through the Intent to Ship: File System Access on Android and WebView discussion thread to see if there were anything to be aware of.

One response mentioned:

The FileSystemAccess API is enabled for android and webview in M132 and expecting to release to stable in Jan, 2025.

In my test, was running on an SDK 36 (Android 16) emulator, where the Android System WebView version is 133.0.

Someone also said earlier:

Apps that use WebView will need to implement WebChromeClient#onShowFileChooser() for the JS calls window.showOpenFilePicker(), showDirectoryPicker(), and showSaveFilePicker(). I'm working on adding more options to WebChromeClient.FileChooserParams to help clarify which API is being used. These additions should be available in the next API release.

Even though I've added a basic WebChromeClient#onShowFileChooser() override, it doesn't seem to be triggered for anything beyond showOpenFilePicker().

That's as far as I've gotten so far.

erisu avatar Jun 18 '25 05:06 erisu

I asked Google to clarify the situation of WebView support for this in the original Intent to Ship email thread. Here's what they said:

Supporting the File System Access API requires changes to the existing WebViewClient.onShowFileChooser callback: adding a read/write permission flag, and a mode to request opening a folder instead of a file. Existing apps are not expecting to receive these new calls and their code might handle them incorrectly (because they won't be aware of the new modes/flags), so the File System Access API is disabled by default.

The new callback flags and behavior were intended to be part of Android 16 (API36) and be enabled for apps which set their targetSdkVersion to 36 or later, but unfortunately this wasn't ready in time for the Android 16 release. We are instead working on shipping the new APIs and behavior in the next major Android release in 2026.

So it sounds like supporting this will be blocked until the next major Android release.

AshleyScirra avatar Jul 01 '25 09:07 AshleyScirra