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): missing content uri handler in WebViewAssetLoader.PathHandler #582

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

Conversation

lovelyelfpop
Copy link

@lovelyelfpop lovelyelfpop commented Jul 13, 2023

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@8.0.1-dev

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);
    }
}

@erisu erisu changed the title fix:missing content uri handler in WebViewAssetLoader.PathHandler fix(android): missing content uri handler in WebViewAssetLoader.PathHandler Jul 13, 2023
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.

1 participant