Skip to content

Commit

Permalink
Fix Java ESlint
Browse files Browse the repository at this point in the history
  • Loading branch information
gwdp committed Apr 7, 2022
1 parent 358003c commit c008440
Show file tree
Hide file tree
Showing 5 changed files with 154 additions and 97 deletions.
6 changes: 5 additions & 1 deletion android/capacitor/src/main/java/com/getcapacitor/App.java
Expand Up @@ -18,7 +18,11 @@ public interface AppRestoredListener {
void onAppRestored(PluginResult result);
}

public enum DownloadStatus { STARTED, COMPLETED, FAILED }
public enum DownloadStatus {
STARTED,
COMPLETED,
FAILED
}

/**
* Interface for callbacks when app is receives download request from webview.
Expand Down
Expand Up @@ -426,7 +426,6 @@ public void reset() {
private void initWebView() {
WebSettings settings = webView.getSettings();
settings.setJavaScriptEnabled(true);
settings.setAllowFileAccess(true);
webView.addJavascriptInterface(this.downloadProxy.jsInterface(), this.downloadProxy.jsInterfaceName());
webView.setDownloadListener(this.downloadProxy);
settings.setDomStorageEnabled(true);
Expand Down
@@ -1,10 +1,8 @@
package com.getcapacitor;

import android.webkit.JavascriptInterface;

import androidx.activity.result.ActivityResultLauncher;
import androidx.annotation.Nullable;

import java.util.HashMap;
import java.util.UUID;

Expand All @@ -15,17 +13,24 @@
* to the proxy in order to have that code executed exclusively for that request.
*/
public class DownloadJSInterface {
final private DownloadJSOperationController operationsController;
final private ActivityResultLauncher<DownloadJSOperationController.Input> launcher;
final private HashMap<String, DownloadJSOperationController.Input> pendingInputs;
final private Bridge bridge;

private final DownloadJSOperationController operationsController;
private final ActivityResultLauncher<DownloadJSOperationController.Input> launcher;
private final HashMap<String, DownloadJSOperationController.Input> pendingInputs;
private final Bridge bridge;

//
public DownloadJSInterface(Bridge bridge) {
this.operationsController = new DownloadJSOperationController(bridge.getActivity());
this.pendingInputs = new HashMap<>();
this.bridge = bridge;
this.launcher = bridge.getActivity().registerForActivityResult(this.operationsController,
result -> Logger.debug("DownloadJSActivity result", String.valueOf(result)));
this.launcher =
bridge
.getActivity()
.registerForActivityResult(
this.operationsController,
result -> Logger.debug("DownloadJSActivity result", String.valueOf(result))
);
}

/* JavascriptInterface imp. */
Expand All @@ -34,13 +39,15 @@ public void receiveContentTypeFromJavascript(String contentType, String operatio
//Transition pending input operation to started with resolved content type
this.transitionPendingInputOperation(operationID, contentType, null);
}

@JavascriptInterface
public void receiveStreamChunkFromJavascript(String chunk, String operationID) {
//Guarantee pending input transition to started operation (when no content type is resolved)
this.transitionPendingInputOperation(operationID, null, null);
//Append data to operation
this.operationsController.appendToOperation(operationID, chunk);
}

@JavascriptInterface
public void receiveStreamErrorFromJavascript(String error, String operationID) {
//Guarantee pending input transition to 'started-but-stale' operation before actually failing
Expand All @@ -50,6 +57,7 @@ public void receiveStreamErrorFromJavascript(String error, String operationID) {
//Notify
this.bridge.getApp().fireDownloadUpdate(operationID, App.DownloadStatus.FAILED, error);
}

@JavascriptInterface
public void receiveStreamCompletionFromJavascript(String operationID) {
//Complete operation signal
Expand All @@ -70,64 +78,82 @@ public String getJavascriptBridgeForURL(String fileURL, String contentDispositio
//will wait either stream start on content-type resolution to start asking
//for file pick and stream drain
String operationID = UUID.randomUUID().toString();
DownloadJSOperationController.Input input = new DownloadJSOperationController.Input(operationID, fileURL, mimeType, contentDisposition);
DownloadJSOperationController.Input input = new DownloadJSOperationController.Input(
operationID,
fileURL,
mimeType,
contentDisposition
);
this.pendingInputs.put(operationID, input);
//Return JS bridge with operationID tagged
return this.getJavascriptInterfaceBridgeForReadyAvailableData(fileURL, mimeType, operationID);
}
return null;
}

/* Injectors */
private String getJavascriptInterfaceBridgeForReadyAvailableData(String blobUrl, String mimeType, String operationID) {
return "javascript: " +
"" +
"function parseFile(file, chunkReadCallback, errorCallback, successCallback) {\n" +
" let fileSize = file.size;" +
" let chunkSize = 64 * 1024;" +
" let offset = 0;" +
" let self = this;" +
" let readBlock = null;" +
" let onLoadHandler = function(evt) {" +
" if (evt.target.error == null) {" +
" offset += evt.target.result.length;" +
" chunkReadCallback(evt.target.result);" +
" } else {" +
" errorCallback(evt.target.error);" +
" return;" +
" }" +
" if (offset >= fileSize) {" +
" if (successCallback) successCallback();" +
" return;" +
" }" +
" readBlock(offset, chunkSize, file);" +
" };" +
" readBlock = function(_offset, length, _file) {" +
" var r = new FileReader();" +
" var blob = _file.slice(_offset, length + _offset);" +
" r.onload = onLoadHandler;" +
" r.readAsBinaryString(blob);" +
" };" +
" readBlock(offset, chunkSize, file);" +
"};\n" +
"(() => { let xhr = new XMLHttpRequest();" +
"xhr.open('GET', '"+ blobUrl +"', true);" +
((mimeType != null && mimeType.length() > 0) ? "xhr.setRequestHeader('Content-type','" + mimeType + "');" : "") +
"xhr.responseType = 'blob';" +
"xhr.onerror = xhr.onload = function(e) {" +
" if (this.status == 200) {" +
" let contentType = this.getResponseHeader('content-type');" +
" if (contentType) { CapacitorDownloadInterface.receiveContentTypeFromJavascript(contentType, '" + operationID + "'); }" +
" var blob = this.response;" +
" parseFile(blob, " +
" function(chunk) { CapacitorDownloadInterface.receiveStreamChunkFromJavascript(chunk, '" + operationID + "'); }," +
" function(err) { console.error('[Capacitor XHR] - error:', err); CapacitorDownloadInterface.receiveStreamChunkFromJavascript(err.message, '" + operationID + "'); }, " +
" function() { console.log('[Capacitor XHR] - Drained!'); CapacitorDownloadInterface.receiveStreamCompletionFromJavascript('" + operationID + "'); } " +
" );" +
" } else {" +
" console.error('[Capacitor XHR] - error:', this.status, (e ? e.loaded : this.responseText));" +
" }" +
"};" +
"xhr.send();})()";
return (
"javascript: " +
"" +
"function parseFile(file, chunkReadCallback, errorCallback, successCallback) {\n" +
" let fileSize = file.size;" +
" let chunkSize = 64 * 1024;" +
" let offset = 0;" +
" let self = this;" +
" let readBlock = null;" +
" let onLoadHandler = function(evt) {" +
" if (evt.target.error == null) {" +
" offset += evt.target.result.length;" +
" chunkReadCallback(evt.target.result);" +
" } else {" +
" errorCallback(evt.target.error);" +
" return;" +
" }" +
" if (offset >= fileSize) {" +
" if (successCallback) successCallback();" +
" return;" +
" }" +
" readBlock(offset, chunkSize, file);" +
" };" +
" readBlock = function(_offset, length, _file) {" +
" var r = new FileReader();" +
" var blob = _file.slice(_offset, length + _offset);" +
" r.onload = onLoadHandler;" +
" r.readAsBinaryString(blob);" +
" };" +
" readBlock(offset, chunkSize, file);" +
"};\n" +
"(() => { let xhr = new XMLHttpRequest();" +
"xhr.open('GET', '" +
blobUrl +
"', true);" +
((mimeType != null && mimeType.length() > 0) ? "xhr.setRequestHeader('Content-type','" + mimeType + "');" : "") +
"xhr.responseType = 'blob';" +
"xhr.onerror = xhr.onload = function(e) {" +
" if (this.status == 200) {" +
" let contentType = this.getResponseHeader('content-type');" +
" if (contentType) { CapacitorDownloadInterface.receiveContentTypeFromJavascript(contentType, '" +
operationID +
"'); }" +
" var blob = this.response;" +
" parseFile(blob, " +
" function(chunk) { CapacitorDownloadInterface.receiveStreamChunkFromJavascript(chunk, '" +
operationID +
"'); }," +
" function(err) { console.error('[Capacitor XHR] - error:', err); CapacitorDownloadInterface.receiveStreamChunkFromJavascript(err.message, '" +
operationID +
"'); }, " +
" function() { console.log('[Capacitor XHR] - Drained!'); CapacitorDownloadInterface.receiveStreamCompletionFromJavascript('" +
operationID +
"'); } " +
" );" +
" } else {" +
" console.error('[Capacitor XHR] - error:', this.status, (e ? e.loaded : this.responseText));" +
" }" +
"};" +
"xhr.send();})()"
);
}

/* Helpers */
Expand Down

0 comments on commit c008440

Please sign in to comment.