|
@@ -15,6 +15,9 @@ import android.os.Build;
|
|
|
import android.os.Bundle;
|
|
|
import android.os.Handler;
|
|
|
import android.os.HandlerThread;
|
|
|
+import android.text.TextUtils;
|
|
|
+import android.util.Log;
|
|
|
+import android.view.ViewTreeObserver;
|
|
|
import android.webkit.ValueCallback;
|
|
|
import android.webkit.WebSettings;
|
|
|
import android.webkit.WebView;
|
|
@@ -31,13 +34,16 @@ import androidx.webkit.WebViewFeature;
|
|
|
import com.getcapacitor.android.R;
|
|
|
import com.getcapacitor.annotation.CapacitorPlugin;
|
|
|
import com.getcapacitor.annotation.Permission;
|
|
|
+import com.getcapacitor.cordova.MockCordovaGeckoviewImpl;
|
|
|
import com.getcapacitor.cordova.MockCordovaInterfaceImpl;
|
|
|
import com.getcapacitor.cordova.MockCordovaWebViewImpl;
|
|
|
+import com.getcapacitor.httpserver.SimpleHttpServer;
|
|
|
import com.getcapacitor.util.HostMask;
|
|
|
import com.getcapacitor.util.InternalUtils;
|
|
|
import com.getcapacitor.util.PermissionHelper;
|
|
|
import com.getcapacitor.util.WebColor;
|
|
|
import java.io.File;
|
|
|
+import java.io.IOException;
|
|
|
import java.net.SocketTimeoutException;
|
|
|
import java.net.URL;
|
|
|
import java.util.ArrayList;
|
|
@@ -48,6 +54,7 @@ import java.util.HashSet;
|
|
|
import java.util.LinkedList;
|
|
|
import java.util.List;
|
|
|
import java.util.Map;
|
|
|
+import java.util.Random;
|
|
|
import java.util.Set;
|
|
|
import java.util.regex.Matcher;
|
|
|
import java.util.regex.Pattern;
|
|
@@ -58,6 +65,14 @@ import org.apache.cordova.PluginEntry;
|
|
|
import org.apache.cordova.PluginManager;
|
|
|
import org.json.JSONException;
|
|
|
|
|
|
+import org.mozilla.geckoview.GeckoRuntime;
|
|
|
+import org.mozilla.geckoview.GeckoRuntimeSettings;
|
|
|
+import org.mozilla.geckoview.GeckoSession;
|
|
|
+import org.mozilla.geckoview.GeckoSessionSettings;
|
|
|
+import org.mozilla.geckoview.GeckoView;
|
|
|
+import org.mozilla.geckoview.WebExtension;
|
|
|
+
|
|
|
+import fi.iki.elonen.NanoHTTPD;
|
|
|
/**
|
|
|
* The Bridge class is the main engine of Capacitor. It manages
|
|
|
* loading and communicating with all Plugins,
|
|
@@ -73,7 +88,7 @@ import org.json.JSONException;
|
|
|
* <a href="https://github.com/ionic-team/capacitor/blob/HEAD/android/capacitor/src/main/java/com/getcapacitor/BridgeActivity.java">
|
|
|
* BridgeActivity.java</a>
|
|
|
*/
|
|
|
-public class Bridge {
|
|
|
+public class Bridge implements IPostMessage {
|
|
|
|
|
|
private static final String PREFS_NAME = "CapacitorSettings";
|
|
|
private static final String PERMISSION_PREFS_NAME = "PluginPermStates";
|
|
@@ -81,6 +96,7 @@ public class Bridge {
|
|
|
private static final String BUNDLE_LAST_PLUGIN_CALL_METHOD_NAME_KEY = "capacitorLastActivityPluginMethod";
|
|
|
private static final String BUNDLE_PLUGIN_CALL_OPTIONS_SAVED_KEY = "capacitorLastPluginCallOptions";
|
|
|
private static final String BUNDLE_PLUGIN_CALL_BUNDLE_KEY = "capacitorLastPluginCallBundle";
|
|
|
+ private static final String BUNDLE_SESSION_PARCELABLE_BUNDLE_KEY = "geckoviewSessionState";
|
|
|
private static final String LAST_BINARY_VERSION_CODE = "lastBinaryVersionCode";
|
|
|
private static final String LAST_BINARY_VERSION_NAME = "lastBinaryVersionName";
|
|
|
private static final String MINIMUM_ANDROID_WEBVIEW_ERROR = "System WebView is not supported";
|
|
@@ -119,8 +135,8 @@ public class Bridge {
|
|
|
private Set<String> allowedOriginRules = new HashSet<String>();
|
|
|
private ArrayList<String> authorities = new ArrayList<>();
|
|
|
// A reference to the main WebView for the app
|
|
|
- private final WebView webView;
|
|
|
- public final MockCordovaInterfaceImpl cordovaInterface;
|
|
|
+ // private final WebView webView;
|
|
|
+ // public final MockCordovaInterfaceImpl cordovaInterface;
|
|
|
private CordovaWebView cordovaWebView;
|
|
|
private CordovaPreferences preferences;
|
|
|
private BridgeWebViewClient webViewClient;
|
|
@@ -164,9 +180,16 @@ public class Bridge {
|
|
|
// A pre-determined path to load the bridge
|
|
|
private ServerPath serverPath;
|
|
|
|
|
|
+ private WebExtensionPortProxy webExtensionPortProxy;
|
|
|
+ public final MockCordovaInterfaceImpl cordovaInterface;
|
|
|
+ private WebviewExtension webviewExtension;
|
|
|
+ private final static String BUILD_INSTALL = "resource://android/assets/";
|
|
|
+ private NanoHTTPD server;
|
|
|
+
|
|
|
+ private GeckoSession.SessionState mSessionState;
|
|
|
/**
|
|
|
* Create the Bridge with a reference to the main {@link Activity} for the
|
|
|
- * app, and a reference to the {@link WebView} our app will use.
|
|
|
+ * app, and a reference to the {@link GeckoView} our app will use.
|
|
|
* @param context
|
|
|
* @param webView
|
|
|
* @deprecated Use {@link Bridge.Builder} to create Bridge instances
|
|
@@ -174,7 +197,7 @@ public class Bridge {
|
|
|
@Deprecated
|
|
|
public Bridge(
|
|
|
AppCompatActivity context,
|
|
|
- WebView webView,
|
|
|
+ GeckoView webView,
|
|
|
List<Class<? extends Plugin>> initialPlugins,
|
|
|
MockCordovaInterfaceImpl cordovaInterface,
|
|
|
PluginManager pluginManager,
|
|
@@ -200,7 +223,8 @@ public class Bridge {
|
|
|
this.serverPath = serverPath;
|
|
|
this.context = context;
|
|
|
this.fragment = fragment;
|
|
|
- this.webView = webView;
|
|
|
+ // this.webView = webView;
|
|
|
+ this.webviewExtension = new WebviewExtension(webView);
|
|
|
this.webViewClient = new BridgeWebViewClient(this);
|
|
|
this.initialPlugins = initialPlugins;
|
|
|
this.pluginInstances = pluginInstances;
|
|
@@ -252,8 +276,74 @@ public class Bridge {
|
|
|
public App getApp() {
|
|
|
return app;
|
|
|
}
|
|
|
-
|
|
|
+ private void startRandomPort() {
|
|
|
+ // bind port retry 3 times
|
|
|
+ for (int retry = 0; retry < 3 && server == null; retry++) {
|
|
|
+ try {
|
|
|
+ int port = 1024 + new Random().nextInt(64511);
|
|
|
+ config.setPort(port);
|
|
|
+ server = new SimpleHttpServer(context, this);
|
|
|
+ server.start();
|
|
|
+ } catch (IOException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ server = null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
private void loadWebView() {
|
|
|
+
|
|
|
+ startRandomPort();
|
|
|
+ String overriddenUserAgentString = TextUtils.isEmpty(config.getOverriddenUserAgentString()) ? "" : config.getOverriddenUserAgentString();
|
|
|
+ String appendedUserAgentString = TextUtils.isEmpty(config.getAppendedUserAgentString()) ? "" : config.getAppendedUserAgentString();
|
|
|
+ GeckoSessionSettings sessionSettings = new GeckoSessionSettings.Builder()
|
|
|
+ .allowJavascript(true)
|
|
|
+ .userAgentOverride("random_port/" + config.getPort() + ";" + overriddenUserAgentString + appendedUserAgentString)
|
|
|
+ .build();
|
|
|
+ GeckoSession session = new GeckoSession(sessionSettings);
|
|
|
+ session.setContentDelegate(new GeckoSession.ContentDelegate() {
|
|
|
+
|
|
|
+ });
|
|
|
+
|
|
|
+ webviewExtension.setSession(session);
|
|
|
+
|
|
|
+ appUrlConfig = this.getServerUrl();
|
|
|
+ String[] appAllowNavigationConfig = this.config.getAllowNavigation();
|
|
|
+
|
|
|
+ ArrayList<String> authorities = new ArrayList<>();
|
|
|
+
|
|
|
+ if (appAllowNavigationConfig != null) {
|
|
|
+ authorities.addAll(Arrays.asList(appAllowNavigationConfig));
|
|
|
+ }
|
|
|
+ this.appAllowNavigationMask = HostMask.Parser.parse(appAllowNavigationConfig);
|
|
|
+ String authority = this.getHost();
|
|
|
+ authorities.add(authority);
|
|
|
+ String scheme = this.getScheme();
|
|
|
+
|
|
|
+ localUrl = scheme + "://" + authority;
|
|
|
+
|
|
|
+ if (appUrlConfig != null) {
|
|
|
+ try {
|
|
|
+ URL appUrlObject = new URL(appUrlConfig);
|
|
|
+ authorities.add(appUrlObject.getAuthority());
|
|
|
+ } catch (Exception ex) {
|
|
|
+ Logger.error("Provided server url is invalid: " + ex.getMessage());
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ localUrl = appUrlConfig;
|
|
|
+ appUrl = appUrlConfig;
|
|
|
+ } else {
|
|
|
+ appUrl = localUrl;
|
|
|
+ // custom URL schemes requires path ending with /
|
|
|
+ if (!scheme.equals(Bridge.CAPACITOR_HTTP_SCHEME) && !scheme.equals(CAPACITOR_HTTPS_SCHEME)) {
|
|
|
+ appUrl += "/";
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ String appUrlPath = this.config.getStartPath();
|
|
|
+ if (appUrlPath != null && !appUrlPath.trim().isEmpty()) {
|
|
|
+ appUrl += appUrlPath;
|
|
|
+ }
|
|
|
+
|
|
|
final boolean html5mode = this.config.isHTML5Mode();
|
|
|
|
|
|
// Start the local web server
|
|
@@ -272,8 +362,8 @@ public class Bridge {
|
|
|
|
|
|
Logger.debug("Loading app at " + appUrl);
|
|
|
|
|
|
- webView.setWebChromeClient(new BridgeWebChromeClient(this));
|
|
|
- webView.setWebViewClient(this.webViewClient);
|
|
|
+ // webView.setWebChromeClient(new BridgeWebChromeClient(this));
|
|
|
+ // webView.setWebViewClient(this.webViewClient);
|
|
|
|
|
|
if (!isDeployDisabled() && !isNewBinary()) {
|
|
|
SharedPreferences prefs = getContext()
|
|
@@ -286,7 +376,7 @@ public class Bridge {
|
|
|
if (!this.isMinimumWebViewInstalled()) {
|
|
|
String errorUrl = this.getErrorUrl();
|
|
|
if (errorUrl != null) {
|
|
|
- webView.loadUrl(errorUrl);
|
|
|
+ // webView.loadUrl(errorUrl);
|
|
|
return;
|
|
|
} else {
|
|
|
Logger.error(MINIMUM_ANDROID_WEBVIEW_ERROR);
|
|
@@ -302,8 +392,23 @@ public class Bridge {
|
|
|
}
|
|
|
} else {
|
|
|
// Get to work
|
|
|
- webView.loadUrl(appUrl);
|
|
|
+ // webView.loadUrl(appUrl);
|
|
|
}
|
|
|
+ listener = new ViewTreeObserver.OnGlobalLayoutListener() {
|
|
|
+ @Override
|
|
|
+ public void onGlobalLayout() {
|
|
|
+ webviewExtension.getSession().loadUri(appUrl);
|
|
|
+ removeListener();
|
|
|
+ }
|
|
|
+ };
|
|
|
+ this.webviewExtension.getWebview().getViewTreeObserver().addOnGlobalLayoutListener(listener);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ ViewTreeObserver.OnGlobalLayoutListener listener = null;
|
|
|
+
|
|
|
+ private void removeListener() {
|
|
|
+ this.webviewExtension.getWebview().getViewTreeObserver().removeOnGlobalLayoutListener(listener);
|
|
|
}
|
|
|
|
|
|
@SuppressLint("WebViewApiAvailability")
|
|
@@ -488,11 +593,11 @@ public class Bridge {
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * Get the core WebView under Capacitor's control
|
|
|
+ * Get the core GeckoView under Capacitor's control
|
|
|
* @return
|
|
|
*/
|
|
|
- public WebView getWebView() {
|
|
|
- return this.webView;
|
|
|
+ public WebviewExtension getWebView() {
|
|
|
+ return this.webviewExtension;
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -559,31 +664,32 @@ public class Bridge {
|
|
|
*/
|
|
|
@SuppressLint("SetJavaScriptEnabled")
|
|
|
private void initWebView() {
|
|
|
- WebSettings settings = webView.getSettings();
|
|
|
- settings.setJavaScriptEnabled(true);
|
|
|
- settings.setDomStorageEnabled(true);
|
|
|
- settings.setGeolocationEnabled(true);
|
|
|
- settings.setDatabaseEnabled(true);
|
|
|
- settings.setMediaPlaybackRequiresUserGesture(false);
|
|
|
- settings.setJavaScriptCanOpenWindowsAutomatically(true);
|
|
|
- if (this.config.isMixedContentAllowed()) {
|
|
|
- settings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
|
|
|
- }
|
|
|
-
|
|
|
- String appendUserAgent = this.config.getAppendedUserAgentString();
|
|
|
- if (appendUserAgent != null) {
|
|
|
- String defaultUserAgent = settings.getUserAgentString();
|
|
|
- settings.setUserAgentString(defaultUserAgent + " " + appendUserAgent);
|
|
|
- }
|
|
|
- String overrideUserAgent = this.config.getOverriddenUserAgentString();
|
|
|
- if (overrideUserAgent != null) {
|
|
|
- settings.setUserAgentString(overrideUserAgent);
|
|
|
- }
|
|
|
+ // WebSettings settings = webView.getSettings();
|
|
|
+ // settings.setJavaScriptEnabled(true);
|
|
|
+ // settings.setDomStorageEnabled(true);
|
|
|
+ // settings.setGeolocationEnabled(true);
|
|
|
+ // settings.setDatabaseEnabled(true);
|
|
|
+ // settings.setMediaPlaybackRequiresUserGesture(false);
|
|
|
+ // settings.setJavaScriptCanOpenWindowsAutomatically(true);
|
|
|
+ // if (this.config.isMixedContentAllowed()) {
|
|
|
+ // settings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
|
|
|
+ // }
|
|
|
+
|
|
|
+ // String appendUserAgent = this.config.getAppendedUserAgentString();
|
|
|
+ // if (appendUserAgent != null) {
|
|
|
+ // String defaultUserAgent = settings.getUserAgentString();
|
|
|
+ // settings.setUserAgentString(defaultUserAgent + " " + appendUserAgent);
|
|
|
+ // }
|
|
|
+ // String overrideUserAgent = this.config.getOverriddenUserAgentString();
|
|
|
+ // if (overrideUserAgent != null) {
|
|
|
+ // settings.setUserAgentString(overrideUserAgent);
|
|
|
+ // }
|
|
|
|
|
|
String backgroundColor = this.config.getBackgroundColor();
|
|
|
try {
|
|
|
if (backgroundColor != null) {
|
|
|
- webView.setBackgroundColor(WebColor.parseColor(backgroundColor));
|
|
|
+ // webView.setBackgroundColor(WebColor.parseColor(backgroundColor));
|
|
|
+ webviewExtension.getWebview().setBackgroundColor(WebColor.parseColor(backgroundColor));
|
|
|
}
|
|
|
} catch (IllegalArgumentException ex) {
|
|
|
Logger.debug("WebView background color not applied");
|
|
@@ -593,7 +699,9 @@ public class Bridge {
|
|
|
settings.setBuiltInZoomControls(this.config.isZoomableWebView());
|
|
|
|
|
|
if (config.isInitialFocus()) {
|
|
|
- webView.requestFocusFromTouch();
|
|
|
+ // webView.requestFocusFromTouch();
|
|
|
+ webviewExtension.getWebview().requestFocusFromTouch();
|
|
|
+
|
|
|
}
|
|
|
|
|
|
WebView.setWebContentsDebuggingEnabled(this.config.isWebContentsDebuggingEnabled());
|
|
@@ -847,7 +955,8 @@ public class Bridge {
|
|
|
*/
|
|
|
public void eval(final String js, final ValueCallback<String> callback) {
|
|
|
Handler mainHandler = new Handler(context.getMainLooper());
|
|
|
- mainHandler.post(() -> webView.evaluateJavascript(js, callback));
|
|
|
+ // mainHandler.post(() -> webView.evaluateJavascript(js, callback));
|
|
|
+ mainHandler.post(() -> webExtensionPortProxy.eval(js));
|
|
|
}
|
|
|
|
|
|
public void logToJs(final String message, final String level) {
|
|
@@ -1020,6 +1129,12 @@ public class Bridge {
|
|
|
String lastPluginCallMethod = savedInstanceState.getString(BUNDLE_LAST_PLUGIN_CALL_METHOD_NAME_KEY);
|
|
|
String lastOptionsJson = savedInstanceState.getString(BUNDLE_PLUGIN_CALL_OPTIONS_SAVED_KEY);
|
|
|
|
|
|
+ GeckoSession.SessionState sessionState = savedInstanceState.getParcelable(BUNDLE_SESSION_PARCELABLE_BUNDLE_KEY);
|
|
|
+ if (sessionState != null) {
|
|
|
+ this.setSessionState(sessionState);
|
|
|
+ this.getWebView().getSession().restoreState(sessionState);
|
|
|
+ }
|
|
|
+
|
|
|
if (lastPluginId != null) {
|
|
|
// If we have JSON blob saved, create a new plugin call with the original options
|
|
|
if (lastOptionsJson != null) {
|
|
@@ -1060,6 +1175,9 @@ public class Bridge {
|
|
|
outState.putString(BUNDLE_LAST_PLUGIN_CALL_METHOD_NAME_KEY, call.getMethodName());
|
|
|
outState.putString(BUNDLE_PLUGIN_CALL_OPTIONS_SAVED_KEY, call.getData().toString());
|
|
|
outState.putBundle(BUNDLE_PLUGIN_CALL_BUNDLE_KEY, bundle);
|
|
|
+ if (mSessionState != null) {
|
|
|
+ outState.putParcelable(BUNDLE_SESSION_PARCELABLE_BUNDLE_KEY, mSessionState);
|
|
|
+ }
|
|
|
} else {
|
|
|
Logger.error("Couldn't save last " + call.getPluginId() + "'s Plugin " + call.getMethodName() + " call");
|
|
|
}
|
|
@@ -1359,8 +1477,10 @@ public class Bridge {
|
|
|
* Handle onDetachedFromWindow lifecycle event
|
|
|
*/
|
|
|
public void onDetachedFromWindow() {
|
|
|
- webView.removeAllViews();
|
|
|
- webView.destroy();
|
|
|
+ // webView.removeAllViews();
|
|
|
+ // webView.destroy();
|
|
|
+ this.getWebView().getWebview().onDetachedFromWindow();
|
|
|
+ this.getWebView().getWebview().removeAllViews();
|
|
|
}
|
|
|
|
|
|
public String getServerBasePath() {
|
|
@@ -1384,14 +1504,16 @@ public class Bridge {
|
|
|
*/
|
|
|
public void setServerAssetPath(String path) {
|
|
|
localServer.hostAssets(path);
|
|
|
- webView.post(() -> webView.loadUrl(appUrl));
|
|
|
+ // webView.post(() -> webView.loadUrl(appUrl));
|
|
|
+ webviewExtension.getWebview().post(() -> this.webviewExtension.getSession().loadUri(appUrl));
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Reload the WebView
|
|
|
*/
|
|
|
public void reload() {
|
|
|
- webView.post(() -> webView.loadUrl(appUrl));
|
|
|
+ // webView.post(() -> webView.loadUrl(appUrl));
|
|
|
+ webviewExtension.getWebview().post(() -> this.webviewExtension.getSession().loadUri(appUrl));
|
|
|
}
|
|
|
|
|
|
public String getLocalUrl() {
|
|
@@ -1416,7 +1538,7 @@ public class Bridge {
|
|
|
|
|
|
public void setWebViewClient(BridgeWebViewClient client) {
|
|
|
this.webViewClient = client;
|
|
|
- webView.setWebViewClient(client);
|
|
|
+ // webView.setWebViewClient(client);
|
|
|
}
|
|
|
|
|
|
List<WebViewListener> getWebViewListeners() {
|
|
@@ -1537,6 +1659,7 @@ public class Bridge {
|
|
|
return this;
|
|
|
}
|
|
|
|
|
|
+ @SuppressLint({"WrongThread", "SetJavaScriptEnabled"})
|
|
|
public Bridge create() {
|
|
|
// Cordova initialization
|
|
|
ConfigXmlParser parser = new ConfigXmlParser();
|
|
@@ -1550,12 +1673,28 @@ public class Bridge {
|
|
|
cordovaInterface.restoreInstanceState(instanceState);
|
|
|
}
|
|
|
|
|
|
- WebView webView = this.fragment != null ? fragment.getView().findViewById(R.id.webview) : activity.findViewById(R.id.webview);
|
|
|
- MockCordovaWebViewImpl mockWebView = new MockCordovaWebViewImpl(activity.getApplicationContext());
|
|
|
+ // WebView webView = this.fragment != null ? fragment.getView().findViewById(R.id.webview) : activity.findViewById(R.id.webview);
|
|
|
+ // MockCordovaWebViewImpl mockWebView = new MockCordovaWebViewImpl(activity.getApplicationContext());
|
|
|
+ GeckoView webView = this.fragment != null ? fragment.getView().findViewById(R.id.webview) : activity.findViewById(R.id.webview);
|
|
|
+ MockCordovaGeckoviewImpl mockWebView = new MockCordovaGeckoviewImpl(activity.getApplicationContext());
|
|
|
mockWebView.init(cordovaInterface, pluginEntries, preferences, webView);
|
|
|
PluginManager pluginManager = mockWebView.getPluginManager();
|
|
|
cordovaInterface.onCordovaInit(pluginManager);
|
|
|
|
|
|
+ if (config == null)
|
|
|
+ config = CapConfig.loadDefault(activity.getApplicationContext());
|
|
|
+ GeckoRuntimeSettings runTimeSettings = new GeckoRuntimeSettings.Builder()
|
|
|
+ .configFilePath("")
|
|
|
+ .javaScriptEnabled(true)
|
|
|
+ .loginAutofillEnabled(true)
|
|
|
+ .webManifest(false)
|
|
|
+ .aboutConfigEnabled(false)
|
|
|
+ .remoteDebuggingEnabled(true)
|
|
|
+ .build();
|
|
|
+
|
|
|
+ GeckoRuntime sRuntime = GeckoRuntime
|
|
|
+ .create(activity, runTimeSettings);
|
|
|
+
|
|
|
// Bridge initialization
|
|
|
Bridge bridge = new Bridge(
|
|
|
activity,
|
|
@@ -1570,10 +1709,25 @@ public class Bridge {
|
|
|
config
|
|
|
);
|
|
|
|
|
|
- if (webView instanceof CapacitorWebView) {
|
|
|
- CapacitorWebView capacitorWebView = (CapacitorWebView) webView;
|
|
|
- capacitorWebView.setBridge(bridge);
|
|
|
- }
|
|
|
+ // if (webView instanceof CapacitorWebView) {
|
|
|
+ // CapacitorWebView capacitorWebView = (CapacitorWebView) webView;
|
|
|
+ // capacitorWebView.setBridge(bridge);
|
|
|
+ // }
|
|
|
+
|
|
|
+ webView.setSession(bridge.getWebView().getSession());
|
|
|
+ webView.getSession().setProgressDelegate(new GeckoSession.ProgressDelegate() {
|
|
|
+ @Override
|
|
|
+ public void onSessionStateChange(@NonNull GeckoSession session, @NonNull GeckoSession.SessionState sessionState) {
|
|
|
+// GeckoSession.ProgressDelegate.super.onSessionStateChange(session, sessionState);
|
|
|
+ String value = "";
|
|
|
+ if (sessionState != null) {
|
|
|
+ value = sessionState.toString();
|
|
|
+ }
|
|
|
+ Log.i("geckoview", "onSessionStateChange when " + System.currentTimeMillis() + "ms " + value);
|
|
|
+ bridge.setSessionState(sessionState);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ webView.getSession().open(sRuntime);
|
|
|
|
|
|
bridge.setCordovaWebView(mockWebView);
|
|
|
bridge.setWebViewListeners(webViewListeners);
|
|
@@ -1583,7 +1737,40 @@ public class Bridge {
|
|
|
bridge.restoreInstanceState(instanceState);
|
|
|
}
|
|
|
|
|
|
+ WebExtensionPortProxy webExtensionProxy = new WebExtensionPortProxy(bridge);
|
|
|
+ WebExtension.PortDelegate portDelegate = new PortDelegate(webExtensionProxy);
|
|
|
+ WebExtension.MessageDelegate messageDelegate = new MessageDelegate(webExtensionProxy, portDelegate);
|
|
|
+ sRuntime
|
|
|
+ .getWebExtensionController()
|
|
|
+ .ensureBuiltIn(BUILD_INSTALL, "messaging@example.com")
|
|
|
+ .accept(
|
|
|
+ // Set delegate that will receive messages coming from this extension.
|
|
|
+ extension ->
|
|
|
+ extension
|
|
|
+ .setMessageDelegate(messageDelegate, "browser"),
|
|
|
+ // Something bad happened, let's log an error
|
|
|
+ e -> Log.e("MessageDelegate", "Error registering extension", e));
|
|
|
+ mockWebView.setProxy(webExtensionProxy);
|
|
|
+ mockWebView.setHttpServer(bridge.server);
|
|
|
+ bridge.setWebExtensionPortProxy(webExtensionProxy);
|
|
|
+
|
|
|
return bridge;
|
|
|
}
|
|
|
}
|
|
|
+ @Override
|
|
|
+ public void postMessage(Object message) {
|
|
|
+ this.msgHandler.postMessage(message.toString());
|
|
|
+ }
|
|
|
+
|
|
|
+ public void setWebExtensionPortProxy(WebExtensionPortProxy proxy) {
|
|
|
+ this.webExtensionPortProxy = proxy;
|
|
|
+ }
|
|
|
+
|
|
|
+ public WebExtensionPortProxy getWebExtensionPortProxy() {
|
|
|
+ return this.webExtensionPortProxy;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void setSessionState(GeckoSession.SessionState sessionState) {
|
|
|
+ this.mSessionState = sessionState;
|
|
|
+ }
|
|
|
}
|