Skip to content

Commit

Permalink
Add content file system support in WebView
Browse files Browse the repository at this point in the history
This is a cherry-pick of a non-final implementation of PR
apache#629

WR-Issue: #17891
  • Loading branch information
lorenzodallavecchia committed Oct 16, 2024
1 parent c696c7a commit a090f04
Showing 1 changed file with 37 additions and 12 deletions.
49 changes: 37 additions & 12 deletions src/android/FileUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ Licensed to the Apache Software Foundation (ASF) under one
import org.apache.cordova.CordovaInterface;
import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.CordovaPluginPathHandler;
import org.apache.cordova.CordovaResourceApi;
import org.apache.cordova.CordovaWebView;
import org.apache.cordova.LOG;
import org.apache.cordova.PermissionHelper;
Expand Down Expand Up @@ -1240,6 +1241,8 @@ private String getMimeType(Uri uri) {
}

public CordovaPluginPathHandler getPathHandler() {
final CordovaResourceApi resourceApi = webView.getResourceApi();

WebViewAssetLoader.PathHandler pathHandler = path -> {
String targetFileSystem = null;

Expand All @@ -1263,9 +1266,11 @@ public CordovaPluginPathHandler getPathHandler() {
targetFileSystem = "cache-external";
} else if (path.startsWith(LocalFilesystemURL.fsNameToCdvKeyword("assets"))) {
targetFileSystem = "assets";
} else if (path.startsWith(LocalFilesystemURL.fsNameToCdvKeyword("content"))) {
targetFileSystem = "content";
}

boolean isAssetsFS = targetFileSystem == "assets";
boolean isAssetsFS = "assets".equals(targetFileSystem);

if (targetFileSystem != null) {
// Loop the registered file systems to find the target.
Expand All @@ -1279,26 +1284,46 @@ public CordovaPluginPathHandler getPathHandler() {
*/
if (fileSystem.name.equals(targetFileSystem)) {
// E.g. replace __cdvfile_persistent__ with native path "/data/user/0/com.example.file/files/files/"

if ("content".equals(targetFileSystem)) {
// The WebviewAssetLoader uses getPath API, which gives us a decoded path
// For content paths however, we need it to remain encoded.
// The Uri.encode API will encode forward slashes, therefore we must
// split the path, encode each segment, and rebuild the path
String[] pathParts = path.split("/");
path = "";
for (String part : pathParts) {
if ("".equals(path)) {
path = Uri.encode(part);
}
else {
path += "/" + Uri.encode(part);
}
}
}

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 {
InputStream fileIS = !isAssetsFS ?
new FileInputStream(file) :
webView.getContext().getAssets().open(fileTarget);
Uri fileUri = Uri.parse(fileTarget);
String mimeType = null;

String filePath = !isAssetsFS ? file.toString() : fileTarget;
Uri fileUri = Uri.parse(filePath);
String fileMimeType = getMimeType(fileUri);
try {
InputStream io = null;
if (isAssetsFS) {
io = webView.getContext().getAssets().open(fileTarget);
mimeType = getMimeType(fileUri);
} else {
CordovaResourceApi.OpenForReadResult resource = resourceApi.openForRead(fileUri);
io = resource.inputStream;
mimeType = resource.mimeType;
}

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

0 comments on commit a090f04

Please sign in to comment.