Fix sandbox origin isolation and Android build issues
This commit is contained in:
@@ -13,7 +13,7 @@ import android.webkit.WebResourceResponse;
|
||||
import android.webkit.WebSettings;
|
||||
import android.webkit.WebView;
|
||||
import android.webkit.WebViewClient;
|
||||
import android.widget.FrameLayout;
|
||||
import androidx.coordinatorlayout.widget.CoordinatorLayout;
|
||||
|
||||
import com.getcapacitor.JSObject;
|
||||
import com.getcapacitor.Plugin;
|
||||
@@ -80,9 +80,11 @@ public class SandboxPlugin extends Plugin {
|
||||
sandboxes.put(sandboxId, sandbox);
|
||||
|
||||
// Add the WebView on top of the Capacitor WebView.
|
||||
// The parent is a CoordinatorLayout — using the wrong LayoutParams
|
||||
// type causes a ClassCastException when it intercepts touch events.
|
||||
View capWebView = getBridge().getWebView();
|
||||
ViewGroup parent = (ViewGroup) capWebView.getParent();
|
||||
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(pxWidth, pxHeight);
|
||||
CoordinatorLayout.LayoutParams params = new CoordinatorLayout.LayoutParams(pxWidth, pxHeight);
|
||||
params.leftMargin = pxX;
|
||||
params.topMargin = pxY;
|
||||
parent.addView(sandbox.webView, params);
|
||||
@@ -126,7 +128,7 @@ public class SandboxPlugin extends Plugin {
|
||||
return;
|
||||
}
|
||||
|
||||
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(pxWidth, pxHeight);
|
||||
CoordinatorLayout.LayoutParams params = new CoordinatorLayout.LayoutParams(pxWidth, pxHeight);
|
||||
params.leftMargin = pxX;
|
||||
params.topMargin = pxY;
|
||||
sandbox.webView.setLayoutParams(params);
|
||||
@@ -385,7 +387,7 @@ public class SandboxPlugin extends Plugin {
|
||||
" onMessage: function(data) {" +
|
||||
" var event = {" +
|
||||
" data: data," +
|
||||
" origin: 'sandbox://app'," +
|
||||
" origin: 'https://" + sandbox.id + ".sandbox.native'," +
|
||||
" source: window.parent," +
|
||||
" type: 'message'" +
|
||||
" };" +
|
||||
|
||||
@@ -194,10 +194,9 @@ private class SandboxInstance: NSObject, WKScriptMessageHandler {
|
||||
self.id = id
|
||||
self.plugin = plugin
|
||||
|
||||
// Use a shortened ID for the scheme (URL schemes have length limits
|
||||
// and must start with a letter). We use "sbx-" prefix + first 12 chars.
|
||||
let schemeId = String(id.prefix(12))
|
||||
self.customScheme = "sbx-\(schemeId)"
|
||||
// Each sandbox gets a unique custom URL scheme so that WKWebView
|
||||
// assigns a distinct origin, isolating localStorage/IndexedDB/cookies.
|
||||
self.customScheme = "sbx-\(id)"
|
||||
|
||||
self.schemeHandler = SandboxSchemeHandler(
|
||||
sandboxId: id,
|
||||
|
||||
@@ -413,7 +413,34 @@ const SandboxFrameNative = forwardRef<SandboxFrameHandle, SandboxFrameProps>(
|
||||
|
||||
const rect = el.getBoundingClientRect();
|
||||
|
||||
// Create the native WebView.
|
||||
// Register listeners BEFORE creating the WebView. On Android,
|
||||
// `shouldInterceptRequest` fires on a background thread as soon
|
||||
// as the WebView starts loading — if the fetch listener isn't
|
||||
// registered yet, the event is lost and the request times out
|
||||
// (the thread blocks via CountDownLatch waiting for a response
|
||||
// that never arrives).
|
||||
const fetchListener = await SandboxPlugin.addListener(
|
||||
'fetch',
|
||||
(event: SandboxFetchEvent) => {
|
||||
if (event.id !== id) return;
|
||||
handleNativeFetch(event);
|
||||
},
|
||||
);
|
||||
listeners.push(fetchListener);
|
||||
|
||||
const scriptListener = await SandboxPlugin.addListener(
|
||||
'scriptMessage',
|
||||
(event: SandboxScriptMessageEvent) => {
|
||||
if (event.id !== id) return;
|
||||
handleNativeScriptMessage(event);
|
||||
},
|
||||
);
|
||||
listeners.push(scriptListener);
|
||||
|
||||
if (cancelled || destroyedRef.current) return;
|
||||
|
||||
// Create the native WebView. Fetch events from the initial load
|
||||
// will be handled by the listeners registered above.
|
||||
await SandboxPlugin.create({
|
||||
id,
|
||||
frame: {
|
||||
@@ -431,26 +458,6 @@ const SandboxFrameNative = forwardRef<SandboxFrameHandle, SandboxFrameProps>(
|
||||
}
|
||||
|
||||
createdRef.current = true;
|
||||
|
||||
// Listen for fetch requests from the native URL scheme handler.
|
||||
const fetchListener = await SandboxPlugin.addListener(
|
||||
'fetch',
|
||||
(event: SandboxFetchEvent) => {
|
||||
if (event.id !== id) return;
|
||||
handleNativeFetch(event);
|
||||
},
|
||||
);
|
||||
listeners.push(fetchListener);
|
||||
|
||||
// Listen for script messages (custom JSON-RPC from injected scripts).
|
||||
const scriptListener = await SandboxPlugin.addListener(
|
||||
'scriptMessage',
|
||||
(event: SandboxScriptMessageEvent) => {
|
||||
if (event.id !== id) return;
|
||||
handleNativeScriptMessage(event);
|
||||
},
|
||||
);
|
||||
listeners.push(scriptListener);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user