Bladeren bron

upgrade: 6.2.1 with geckoview new files

ryanemax 3 weken geleden
bovenliggende
commit
16d8d972ab

+ 45 - 0
6.2.1/capacitor/src/main/java/com/getcapacitor/Delegates.java

@@ -0,0 +1,45 @@
+package com.getcapacitor;
+
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.mozilla.geckoview.WebExtension;
+
+class MessageDelegate implements WebExtension.MessageDelegate {
+    WebExtensionPortProxy proxy;
+    WebExtension.PortDelegate portDelegate;
+    public MessageDelegate(WebExtensionPortProxy proxy,WebExtension.PortDelegate portDelegate) {
+        this.proxy = proxy;
+        this.portDelegate = portDelegate;
+    }
+
+    @Nullable
+    @Override
+    public void onConnect(@NonNull WebExtension.Port port) {
+        proxy.bindPort(port,portDelegate);
+    }
+}
+
+class PortDelegate implements WebExtension.PortDelegate {
+    WebExtensionPortProxy proxy;
+
+    public PortDelegate(WebExtensionPortProxy proxy) {
+        this.proxy = proxy;
+    }
+
+    @Override
+    public void onPortMessage(@NonNull Object message, @NonNull WebExtension.Port port) {
+        Log.i(PortDelegate.class.getSimpleName(),message.toString());
+        proxy.postMessage(message);
+    }
+
+    @NonNull
+    @Override
+    public void onDisconnect(@NonNull WebExtension.Port port) {
+        this.proxy.unBind();
+    }
+}

+ 5 - 0
6.2.1/capacitor/src/main/java/com/getcapacitor/IPostMessage.java

@@ -0,0 +1,5 @@
+package com.getcapacitor;
+
+public interface IPostMessage {
+        void postMessage(Object message);
+}

+ 51 - 0
6.2.1/capacitor/src/main/java/com/getcapacitor/WebExtensionPortProxy.java

@@ -0,0 +1,51 @@
+package com.getcapacitor;
+
+
+import android.util.Log;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.mozilla.geckoview.WebExtension;
+
+/**
+ * Proxy for WebExtension.Port and IPostMessage
+ */
+public class WebExtensionPortProxy {
+    WebExtension.Port mPort;
+    IPostMessage proxy;
+
+    WebExtensionPortProxy(IPostMessage proxy) {
+        this.proxy = proxy;
+    }
+   
+    public void bindPort(WebExtension.Port port, WebExtension.PortDelegate delegate) {
+        mPort = port;
+        mPort.setDelegate(delegate);
+    }
+
+    public void unBind() {
+        mPort = null;
+    }
+    /**
+     * post message to Native
+     */
+    public void postMessage(Object message) {
+        Log.i(WebExtensionPortProxy.class.getSimpleName(), message.toString());
+        if (proxy != null)
+            proxy.postMessage(message);
+    }
+    /**
+     * eval js
+     */
+    public void eval(String js) {
+        if (mPort != null) {
+            try {
+                JSONObject json = new JSONObject().put("type", "pageScript").put("payload", js);
+                mPort.postMessage(json);
+                Log.i(WebExtensionPortProxy.class.getSimpleName(), json.toString());
+            } catch (JSONException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+}

+ 53 - 0
6.2.1/capacitor/src/main/java/com/getcapacitor/WebviewExtension.java

@@ -0,0 +1,53 @@
+/**
+ * Boxing some api for compatible
+ */
+package com.getcapacitor;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+
+import org.mozilla.geckoview.GeckoResult;
+import org.mozilla.geckoview.GeckoSession;
+import org.mozilla.geckoview.GeckoView;
+
+public class WebviewExtension {
+    private GeckoView webview;
+    private boolean cansGoBack;
+    public WebviewExtension(GeckoView geckoView){
+        this.webview=geckoView;
+    }
+    public boolean canGoBack(){
+        return cansGoBack;
+    }
+    public void goBack(){
+        this.webview.getSession().goBack();
+    }
+    public GeckoSession getSession(){
+        return this.webview.getSession();
+    }
+    public void setSession(GeckoSession session){
+        this.webview.setSession(session);
+        this.webview.getSession().setNavigationDelegate(new GeckoSession.NavigationDelegate() {
+            @Override
+            public void onCanGoBack(@NonNull GeckoSession session, boolean canGoBack) {
+                cansGoBack = canGoBack;
+            }
+        });
+        this.webview.getSession().setPermissionDelegate(new GeckoSession.PermissionDelegate() {
+            @Nullable
+            @Override
+            public GeckoResult<Integer> onContentPermissionRequest(@NonNull GeckoSession session, @NonNull ContentPermission perm) {
+                 if(perm.permission == GeckoSession.PermissionDelegate.PERMISSION_AUTOPLAY_AUDIBLE|| perm.permission == GeckoSession.PermissionDelegate.PERMISSION_AUTOPLAY_INAUDIBLE){
+                    GeckoResult s = new GeckoResult<Integer>();
+                    return GeckoResult.fromValue(ContentPermission.VALUE_ALLOW);
+                }else {
+                     return GeckoSession.PermissionDelegate.super.onContentPermissionRequest(session, perm);
+                 }
+            }}
+        );
+    }
+    public GeckoView getWebview() {
+        return webview;
+    }
+}

+ 43 - 0
6.2.1/capacitor/src/main/java/com/getcapacitor/cordova/CapacitorCordovaGeckoViewCookieManager.java

@@ -0,0 +1,43 @@
+package com.getcapacitor.cordova;
+
+import android.webkit.CookieManager;
+import android.webkit.WebView;
+
+import org.apache.cordova.ICordovaCookieManager;
+import org.mozilla.geckoview.GeckoView;
+
+public class CapacitorCordovaGeckoViewCookieManager implements ICordovaCookieManager {
+    protected final GeckoView webView;
+    private final CookieManager cookieManager;
+    public CapacitorCordovaGeckoViewCookieManager(GeckoView webview) {
+        webView = webview;
+        cookieManager = CookieManager.getInstance();
+        CookieManager.setAcceptFileSchemeCookies(true);
+//        cookieManager.setAcceptThirdPartyCookies(webView, true);
+    }
+    @Override
+    public void setCookiesEnabled(boolean accept) {
+        // TODO: 2022/10/19 not implement it
+    }
+
+    @Override
+    public void setCookie(String url, String value) {
+// TODO: 2022/10/19 not implement it
+    }
+
+    @Override
+    public String getCookie(String url) {
+        // TODO: 2022/10/19 not implement it
+        return null;
+    }
+
+    @Override
+    public void clearCookies() {
+// TODO: 2022/10/19 not implement it
+    }
+
+    @Override
+    public void flush() {
+// TODO: 2022/10/19 not implement it
+    }
+}

+ 303 - 0
6.2.1/capacitor/src/main/java/com/getcapacitor/cordova/MockCordovaGeckoviewImpl.java

@@ -0,0 +1,303 @@
+package com.getcapacitor.cordova;
+
+import android.content.Context;
+import android.content.Intent;
+import android.os.Handler;
+import android.text.TextUtils;
+import android.view.View;
+import android.webkit.ValueCallback;
+import android.webkit.WebChromeClient;
+import com.getcapacitor.WebExtensionPortProxy;
+import org.apache.cordova.CordovaInterface;
+import org.apache.cordova.CordovaPreferences;
+import org.apache.cordova.CordovaResourceApi;
+import org.apache.cordova.CordovaWebView;
+import org.apache.cordova.CordovaWebViewEngine;
+import org.apache.cordova.ICordovaCookieManager;
+import org.apache.cordova.NativeToJsMessageQueue;
+import org.apache.cordova.PluginEntry;
+import org.apache.cordova.PluginManager;
+import org.apache.cordova.PluginResult;
+import org.mozilla.geckoview.GeckoView;
+
+import java.util.List;
+import java.util.Map;
+
+import fi.iki.elonen.NanoHTTPD;
+
+public class MockCordovaGeckoviewImpl implements CordovaWebView {
+
+    private Context context;
+    private PluginManager pluginManager;
+    private CordovaPreferences preferences;
+    private CordovaResourceApi resourceApi;
+    private NativeToJsMessageQueue nativeToJsMessageQueue;
+    private CordovaInterface cordova;
+    private CapacitorCordovaGeckoViewCookieManager cookieManager;
+    private GeckoView webView;
+    private boolean hasPausedEver;
+    private NanoHTTPD httpd;
+    private WebExtensionPortProxy proxy;
+    private CapacitorEvalBridgeMode mode;
+    public MockCordovaGeckoviewImpl(Context context){
+        this.context=context;
+    }
+    @Override
+    public void init(CordovaInterface cordova, List<PluginEntry> pluginEntries, CordovaPreferences preferences) {
+        this.cordova = cordova;
+        this.preferences = preferences;
+        this.pluginManager = new PluginManager(this, this.cordova, pluginEntries);
+        this.resourceApi = new CordovaResourceApi(this.context, this.pluginManager);
+        this.pluginManager.init();
+    }
+    public void init(CordovaInterface cordova, List<PluginEntry> pluginEntries, CordovaPreferences preferences,GeckoView webView){
+        this.cordova = cordova;
+        this.webView = webView;
+        this.preferences = preferences;
+        this.pluginManager = new PluginManager(this, this.cordova, pluginEntries);
+        this.resourceApi = new CordovaResourceApi(this.context, this.pluginManager);
+        nativeToJsMessageQueue = new NativeToJsMessageQueue();
+        mode = new MockCordovaGeckoviewImpl.CapacitorEvalBridgeMode(webView, this.cordova);
+        nativeToJsMessageQueue.addBridgeMode(mode);
+        nativeToJsMessageQueue.setBridgeMode(0);
+        this.cookieManager = new CapacitorCordovaGeckoViewCookieManager(webView);
+        this.pluginManager.init();
+    }
+    public void setProxy(WebExtensionPortProxy proxy){
+        this.proxy = proxy;
+        mode.setProxy(proxy);
+    }
+    public void setHttpServer(NanoHTTPD server){
+        this.httpd=server;
+    }
+    public static class CapacitorEvalBridgeMode extends NativeToJsMessageQueue.BridgeMode {
+
+        private final GeckoView webView;
+        private final CordovaInterface cordova;
+        private WebExtensionPortProxy proxy;
+        public CapacitorEvalBridgeMode(GeckoView webView, CordovaInterface cordova) {
+            this.webView = webView;
+            this.cordova = cordova;
+        }
+        public void setProxy(WebExtensionPortProxy proxy){
+            this.proxy = proxy;
+        }
+        @Override
+        public void onNativeToJsMessageAvailable(final NativeToJsMessageQueue queue) {
+            cordova
+                    .getActivity()
+                    .runOnUiThread(
+                            () -> {
+                                String js = queue.popAndEncodeAsJs();
+                                if (js != null) {
+                                        proxy.eval(js);
+                                }
+                            }
+                    );
+        }
+    }
+
+    @Override
+    public boolean isInitialized() {
+        return cordova != null;
+    }
+
+    @Override
+    public View getView() {
+        return this.webView;
+    }
+
+    @Override
+    public void loadUrlIntoView(String url, boolean recreatePlugins) {
+        if (url.equals("about:blank") || url.startsWith("javascript:")) {
+            webView.getSession().loadUri(url);
+            return;
+        }
+    }
+
+    @Override
+    public void stopLoading() {
+        webView.getSession().stop();
+    }
+
+    @Override
+    public boolean canGoBack() {
+        return false;
+    }
+
+    @Override
+    public void clearCache() {
+
+    }
+
+    @Override
+    public void clearCache(boolean b) {
+
+    }
+
+    @Override
+    public void clearHistory() {
+
+    }
+
+    @Override
+    public boolean backHistory() {
+        return false;
+    }
+
+    @Override
+    public void handlePause(boolean keepRunning) {
+        if (!isInitialized()) {
+            return;
+        }
+        hasPausedEver = true;
+        pluginManager.onPause(keepRunning);
+        triggerDocumentEvent("pause");
+        // If app doesn't want to run in background
+        if (!keepRunning) {
+            // Pause JavaScript timers. This affects all webviews within the app!
+            this.setPaused(true);
+        }
+    }
+
+    @Override
+    public void onNewIntent(Intent intent) {
+        if (this.pluginManager != null) {
+            this.pluginManager.onNewIntent(intent);
+        }
+    }
+
+    @Override
+    public void handleResume(boolean keepRunning) {
+        if (!isInitialized()) {
+            return;
+        }
+        this.setPaused(false);
+        this.pluginManager.onResume(keepRunning);
+        if (hasPausedEver) {
+            triggerDocumentEvent("resume");
+        }
+    }
+    @Override
+    public void handleStart() {
+        if (!isInitialized()) {
+            return;
+        }
+        pluginManager.onStart();
+    }
+
+    @Override
+    public void handleStop() {
+        if (!isInitialized()) {
+            return;
+        }
+        pluginManager.onStop();
+    }
+
+    @Override
+    public void handleDestroy() {
+        if (!isInitialized()) {
+            return;
+        }
+        this.pluginManager.onDestroy();
+
+        if(this.httpd!=null)httpd.stop();
+    }
+
+    @Override
+    public void sendJavascript(String statememt) {
+        nativeToJsMessageQueue.addJavaScript(statememt);
+    }
+
+    public void eval(final String js, final ValueCallback<String> callback) {
+        if(TextUtils.isEmpty(js))
+            return ;
+        Handler mainHandler = new Handler(context.getMainLooper());
+//        mainHandler.post(() -> webView.evaluateJavascript(js, callback));
+        try {
+            proxy.eval(js);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    public void triggerDocumentEvent(final String eventName) {
+        eval("window.Capacitor.triggerEvent('" + eventName + "', 'document');", s -> {});
+    }
+
+    @Override
+    public void showWebPage(String url, boolean openExternal, boolean clearHistory, Map<String, Object> params) {}
+
+    @Override
+    public boolean isCustomViewShowing() {
+        return false;
+    }
+
+    @Override
+    public void showCustomView(View view, WebChromeClient.CustomViewCallback callback) {}
+
+    @Override
+    public void hideCustomView() {}
+
+    @Override
+    public CordovaResourceApi getResourceApi() {
+        return this.resourceApi;
+    }
+
+    @Override
+    public void setButtonPlumbedToJs(int keyCode, boolean override) {}
+
+    @Override
+    public boolean isButtonPlumbedToJs(int keyCode) {
+        return false;
+    }
+
+    @Override
+    public void sendPluginResult(PluginResult cr, String callbackId) {
+        nativeToJsMessageQueue.addPluginResult(cr, callbackId);
+    }
+
+    @Override
+    public PluginManager getPluginManager() {
+        return this.pluginManager;
+    }
+
+    @Override
+    public CordovaWebViewEngine getEngine() {
+        return null;
+    }
+
+    @Override
+    public CordovaPreferences getPreferences() {
+        return this.preferences;
+    }
+
+    @Override
+    public ICordovaCookieManager getCookieManager() {
+        return cookieManager;
+    }
+
+    @Override
+    public String getUrl() {
+        return "";
+    }
+
+    @Override
+    public Context getContext() {
+        return this.webView.getContext();
+    }
+
+    @Override
+    public void loadUrl(String url) {
+        loadUrlIntoView(url, true);
+    }
+
+    @Override
+    public Object postMessage(String id, Object data) {
+        return pluginManager.postMessage(id, data);
+    }
+
+    public void setPaused(boolean value) {
+//        empty implementation
+    }
+}

+ 105 - 0
6.2.1/capacitor/src/main/java/com/getcapacitor/httpserver/SimpleHttpServer.java

@@ -0,0 +1,105 @@
+package com.getcapacitor.httpserver;
+
+import static com.getcapacitor.Logger.config;
+
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.net.Uri;
+import android.text.TextUtils;
+import android.util.Log;
+import android.webkit.WebResourceRequest;
+import android.webkit.WebResourceResponse;
+
+import com.getcapacitor.Bridge;
+import com.getcapacitor.JSExport;
+import com.getcapacitor.JSExportException;
+import com.getcapacitor.Logger;
+import com.getcapacitor.PluginConfig;
+import com.getcapacitor.PluginHandle;
+import com.getcapacitor.WebViewLocalServer;
+//import com.getcapacitor.android.BuildConfig;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.nio.charset.StandardCharsets;
+import java.util.HashMap;
+import java.util.Map;
+
+import fi.iki.elonen.NanoHTTPD;
+
+class FileDownloadResponse extends NanoHTTPD.Response {
+    public FileDownloadResponse(String mimeType, InputStream inputStream, Long length) {
+        super(Status.OK, mimeType, inputStream, length);
+    }
+}
+class NanoHttpDRequest implements WebResourceRequest{
+    Uri uri;
+    Map<String,String> headers=new HashMap<>();
+    String method;
+    int port=0;
+    public NanoHttpDRequest(NanoHTTPD.IHTTPSession session,int port){
+        this.uri=Uri.parse("http://"+session.getRemoteHostName()+":"+port+session.getUri());
+        this.headers=session.getHeaders();
+        this.method=session.getMethod().name();
+        this.port=port;
+    }
+    @Override
+    public Uri getUrl() {
+        return uri;
+    }
+
+    @Override
+    public boolean isForMainFrame() {
+        return false;
+    }
+
+    @Override
+    public boolean isRedirect() {
+        return false;
+    }
+
+    @Override
+    public boolean hasGesture() {
+        return false;
+    }
+
+    @Override
+    public String getMethod() {
+        return method;
+    }
+
+    @Override
+    public Map<String, String> getRequestHeaders() {
+        return headers;
+    }
+}
+
+public class SimpleHttpServer extends NanoHTTPD {
+    Context context;
+    Bridge bridge;
+    public SimpleHttpServer(Context context, Bridge bridge) {
+        super(bridge.getConfig().getPort());
+        this.context = context;
+        this.bridge = bridge;
+    }
+    @Override
+    public Response serve(IHTTPSession session) {
+        WebResourceRequest request = new NanoHttpDRequest(session,getListeningPort());
+        WebResourceResponse response = this.bridge.getLocalServer().shouldInterceptRequest(request);
+        Response result = null;
+        InputStream inputStream = null;
+        try {
+            inputStream = response.getData();
+            int length = inputStream.available();
+            String mimeType = response.getMimeType();
+            result = new FileDownloadResponse(mimeType,inputStream,(long)length);
+        } catch (IOException e) {
+            e.printStackTrace();
+            result = newFixedLengthResponse(Response.Status.NOT_FOUND,"text","File not found");
+        }
+        return result;
+    }
+}