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

@7.0.0 Android webview cannot display img with src="https://localhost/__cdvfile_content__/..." #526

Open
3 tasks done
lovelyelfpop opened this issue Jun 10, 2022 · 5 comments

Comments

@lovelyelfpop
Copy link

Bug Report

Problem

Android webview cannot display <img> with src="https://localhost/__cdvfile_content__/..."

What is expected to happen?

Android webview should display <img> with src="https://localhost/__cdvfile_content__/..."

What does actually happen?

ERR_CONNECTION_REFUSED in console,img not displaying

Information

<img> with src like https://localhost/__cdvfile_asstes__/... or https://localhost/__cdvfile_files__/... can display in webview, but not https://localhost/__cdvfile_content__/...,

Environment, Platform, Device

Redmi K30 pro, Android 11

Version information

Cordova@11.0.0
Cordova-Android@10.1.2
cordova-plugin-file@7.0.0

Checklist

  • I searched for existing GitHub issues
  • I updated all Cordova tooling to most recent version
  • I included all the necessary information above

Reason

WebViewAssetLoader.PathHandler in cordova-plugin-file\src\android\FileUtils.java missing content uri handler.

The right code is

    public CordovaPluginPathHandler getPathHandler() {
        WebViewAssetLoader.PathHandler pathHandler = path -> {
            String targetFileSystem = null;

            if (path.startsWith(LocalFilesystemURL.fsNameToCdvKeyword("persistent"))) {
                targetFileSystem = "persistent";
            } else if (path.startsWith(LocalFilesystemURL.fsNameToCdvKeyword("temporary"))) {
                targetFileSystem = "temporary";
            } else if (path.startsWith(LocalFilesystemURL.fsNameToCdvKeyword("files"))) {
                targetFileSystem = "files";
            } else if (path.startsWith(LocalFilesystemURL.fsNameToCdvKeyword("documents"))) {
                targetFileSystem = "documents";
            } else if (path.startsWith(LocalFilesystemURL.fsNameToCdvKeyword("cache"))) {
                targetFileSystem = "cache";
            } else if (path.startsWith(LocalFilesystemURL.fsNameToCdvKeyword("root"))) {
                targetFileSystem = "root";
            } else if (path.startsWith(LocalFilesystemURL.fsNameToCdvKeyword("files-external"))) {
                targetFileSystem = "files-external";
            } else if (path.startsWith(LocalFilesystemURL.fsNameToCdvKeyword("sdcard"))) {
                targetFileSystem = "sdcard";
            } else if (path.startsWith(LocalFilesystemURL.fsNameToCdvKeyword("cache-external"))) {
                targetFileSystem = "cache-external";
            } else if (path.startsWith(LocalFilesystemURL.fsNameToCdvKeyword("assets"))) {
                targetFileSystem = "assets";
            }
            // --------------------added start--------------------
            else if (path.startsWith(LocalFilesystemURL.fsNameToCdvKeyword("content"))) {
                targetFileSystem = "content";
            }
            // --------------------added end--------------------

            boolean isAssetsFS = targetFileSystem == "assets";

            if (targetFileSystem != null) {
                // Loop the registered file systems to find the target.
                for (Filesystem fileSystem : filesystems) {
                    /*
                     * When target is discovered:
                     * 1. Transform the url path to the native path
                     * 2. Load the file contents
                     * 3. Get the file mime type
                     * 4. Return the file & mime information back we Web Resources
                     */
                    if (fileSystem.name.equals(targetFileSystem)) {
                        // E.g. replace __cdvfile_persistent__ with native path "/data/user/0/com.example.file/files/files/"
                        String fileSystemNativeUri = fileSystem.rootUri.toString().replace("file://", "");
                        String fileTarget = path.replace(LocalFilesystemURL.fsNameToCdvKeyword(targetFileSystem) + "/", fileSystemNativeUri);
                        File file = null;

                        if (isAssetsFS) {
                            fileTarget = fileTarget.replace("/android_asset/", "");
                        } else {
                            file = new File(fileTarget);
                        }

                        try {
                            // --------------------added start--------------------
                            if(targetFileSystem == "content") {
                                ContentResolver cr = webView.getContext().getContentResolver();
                                Uri uri = Uri.parse(fileTarget);
                                InputStream fileIS = new FileInputStream(cr.openFileDescriptor(uri, "r").getFileDescriptor());
                                String fileMimeType = cr.getType(uri);

                                return new WebResourceResponse(fileMimeType, null, fileIS);
                            }
                            // --------------------added end--------------------

                            InputStream fileIS = !isAssetsFS ?
                                    new FileInputStream(file) :
                                    webView.getContext().getAssets().open(fileTarget);

                            String filePath = !isAssetsFS ? file.toString() : fileTarget;
                            Uri fileUri = Uri.parse(filePath);
                            String fileMimeType = getMimeType(fileUri);

                            return new WebResourceResponse(fileMimeType, null, fileIS);
                        } catch (FileNotFoundException e) {
                            Log.e(LOG_TAG, e.getMessage());
                        } catch (IOException e) {
                            Log.e(LOG_TAG, e.getMessage());
                        }
                    }
                }
            }

            return null;
        };

        return new CordovaPluginPathHandler(pathHandler);
    }
}
@HarelM
Copy link

HarelM commented Aug 3, 2022

I've seen this too I believe in version 7.0.
But the above change doesn't fix the call to resolveLocalFilesystemUrl which still I see in the debug that has https://localhost/__cdvfile_content__/... I think it has to do with the changes made in ContentFilesystem.java. I still need to test this theory though...

@breautek
Copy link
Contributor

If content is all that is missing and

 else if (path.startsWith(LocalFilesystemURL.fsNameToCdvKeyword("content"))) {
                targetFileSystem = "content";
            }

is what is needed to add it, then PR would definitely be welcome.

@HarelM
Copy link

HarelM commented Dec 19, 2022

I think this issue is also resolved with #534 which solves #525. I'm not sure though.
All I know is that I'm currently using in production the branch in the PR in #534 and I would love it to be merged so I can use an official version and not a branch...
Thanks!

@lovelyelfpop
Copy link
Author

When will this gets fixed?

pinionpi added a commit to pinionpi/cordova-plugin-file that referenced this issue Apr 10, 2023
@lovelyelfpop
Copy link
Author

I've created a pull request
#582

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

No branches or pull requests

3 participants