Skip to content

Commit

Permalink
Added WebMessageChannel and WebMessageListener features, Updated Andr…
Browse files Browse the repository at this point in the history
…oid Gradle distributionUrl version to 5.6.4, AndroidInAppWebViewController.getCurrentWebViewPackage is available now starting from Android API 21+, Attempt to fix #665, fix #579, Fixed wrong mapping of NavigationAction class on Android for androidHasGesture and androidIsRedirect properties
  • Loading branch information
pichillilorenzo committed Mar 11, 2021
1 parent 54b31ca commit a408310
Show file tree
Hide file tree
Showing 43 changed files with 1,501 additions and 786 deletions.
738 changes: 0 additions & 738 deletions .idea/libraries/Dart_Packages.xml

This file was deleted.

4 changes: 3 additions & 1 deletion .idea/libraries/Flutter_Plugins.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
## 5.2.0

- Added `WebMessageChannel` and `WebMessageListener` features
- `AndroidInAppWebViewController.getCurrentWebViewPackage` is available now starting from Android API 21+.
- Updated Android Gradle distributionUrl version to `5.6.4`
- Attempt to fix "InAppBrowserActivity.onCreate NullPointerException - Attempt to invoke virtual method 'java.lang.String android.os.Bundle.getString(java.lang.String)' on a null object reference" [#665](https://github.com/pichillilorenzo/flutter_inappwebview/issues/665)
- Fixed "[iOS] Application crashes when processing onCreateWindow" [#579](https://github.com/pichillilorenzo/flutter_inappwebview/issues/579)
- Fixed wrong mapping of `NavigationAction` class on Android for `androidHasGesture` and `androidIsRedirect` properties

## 5.1.0+4

- Fixed "IOS scrolling crash the application" [#707](https://github.com/pichillilorenzo/flutter_inappwebview/issues/707)
Expand Down
2 changes: 1 addition & 1 deletion android/gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip
9 changes: 7 additions & 2 deletions android/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,13 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.pichillilorenzo.flutter_inappwebview">
<application>
<activity android:theme="@style/AppTheme" android:name="com.pichillilorenzo.flutter_inappwebview.in_app_browser.InAppBrowserActivity" android:configChanges="orientation|screenSize"></activity>
<activity android:theme="@style/ThemeTransparent" android:name="com.pichillilorenzo.flutter_inappwebview.chrome_custom_tabs.ChromeCustomTabsActivity" android:configChanges="orientation|screenSize"></activity>
<activity
android:theme="@style/AppTheme"
android:name="com.pichillilorenzo.flutter_inappwebview.in_app_browser.InAppBrowserActivity"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density" />
<activity
android:theme="@style/ThemeTransparent"
android:name="com.pichillilorenzo.flutter_inappwebview.chrome_custom_tabs.ChromeCustomTabsActivity" />
<receiver android:name="com.pichillilorenzo.flutter_inappwebview.chrome_custom_tabs.ActionBroadcastReceiver" />
<meta-data
android:name="io.flutter.embedded_views_preview"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
package com.pichillilorenzo.flutter_inappwebview;

import android.net.Uri;
import android.os.Build;
import android.util.Log;
import android.webkit.ValueCallback;
import android.webkit.WebView;

import androidx.annotation.NonNull;
import androidx.webkit.WebMessageCompat;
import androidx.webkit.WebMessagePortCompat;
import androidx.webkit.WebViewCompat;
import androidx.webkit.WebViewFeature;

Expand All @@ -16,9 +20,13 @@
import com.pichillilorenzo.flutter_inappwebview.types.SslCertificateExt;
import com.pichillilorenzo.flutter_inappwebview.types.URLRequest;
import com.pichillilorenzo.flutter_inappwebview.types.UserScript;
import com.pichillilorenzo.flutter_inappwebview.types.WebMessageChannel;
import com.pichillilorenzo.flutter_inappwebview.types.WebMessageListener;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import io.flutter.plugin.common.MethodCall;
Expand Down Expand Up @@ -505,6 +513,56 @@ public void onReceiveValue(Boolean value) {
result.success(false);
}
break;
case "createWebMessageChannel":
if (webView != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M &&
WebViewFeature.isFeatureSupported(WebViewFeature.CREATE_WEB_MESSAGE_CHANNEL)) {
result.success(webView.createCompatWebMessageChannel().toMap());
} else {
result.success(null);
}
break;
case "postWebMessage":
if (webView != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M &&
WebViewFeature.isFeatureSupported(WebViewFeature.POST_WEB_MESSAGE)) {
Map<String, Object> message = (Map<String, Object>) call.argument("message");
String targetOrigin = (String) call.argument("targetOrigin");
List<WebMessagePortCompat> ports = new ArrayList<>();
List<Map<String, Object>> portsMap = (List<Map<String, Object>>) message.get("ports");
if (portsMap != null) {
for (Map<String, Object> portMap : portsMap) {
String webMessageChannelId = (String) portMap.get("webMessageChannelId");
Integer index = (Integer) portMap.get("index");
WebMessageChannel webMessageChannel = webView.webMessageChannels.get(webMessageChannelId);
if (webMessageChannel != null) {
ports.add(webMessageChannel.ports.get(index));
}
}
}
WebMessageCompat webMessage = new WebMessageCompat((String) message.get("data"), ports.toArray(new WebMessagePortCompat[0]));
try {
WebViewCompat.postWebMessage(webView, webMessage, Uri.parse(targetOrigin));
result.success(true);
} catch (Exception e) {
result.error(LOG_TAG, e.getMessage(), null);
}
} else {
result.success(true);
}
break;
case "addWebMessageListener":
if (webView != null && WebViewFeature.isFeatureSupported(WebViewFeature.WEB_MESSAGE_LISTENER)) {
Map<String, Object> webMessageListenerMap = (Map<String, Object>) call.argument("webMessageListener");
WebMessageListener webMessageListener = WebMessageListener.fromMap(webMessageListenerMap);
try {
webView.addWebMessageListener(webMessageListener);
result.success(true);
} catch (Exception e) {
result.error(LOG_TAG, e.getMessage(), null);
}
} else {
result.success(true);
}
break;
default:
result.notImplemented();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.pichillilorenzo.flutter_inappwebview;

import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Build;
import android.webkit.ValueCallback;
import android.webkit.WebSettings;
Expand All @@ -9,6 +10,7 @@
import androidx.webkit.WebViewCompat;
import androidx.webkit.WebViewFeature;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -66,8 +68,20 @@ public void onReceiveValue(Boolean value) {
break;
case "getCurrentWebViewPackage":
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
result.success(
convertWebViewPackageToMap(WebViewCompat.getCurrentWebViewPackage(Shared.activity)));
result.success(convertWebViewPackageToMap(WebViewCompat.getCurrentWebViewPackage(Shared.activity)));
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
//with Android Lollipop (API 21) they started to update the WebView
//as a separate APK with the PlayStore and they added the
//getLoadedPackageInfo() method to the WebViewFactory class and this
//should handle the Android 7.0 behaviour changes too
try {
Class webViewFactory = Class.forName("android.webkit.WebViewFactory");
Method method = webViewFactory.getMethod("getLoadedPackageInfo");
PackageInfo pInfo = (PackageInfo) method.invoke(null);
result.success(convertWebViewPackageToMap(pInfo));
} catch (Exception e) {
result.success(null);
}
} else {
result.success(null);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,19 +65,16 @@ public class InAppBrowserActivity extends AppCompatActivity implements InAppBrow
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

if (savedInstanceState != null) {
return;
}

Bundle b = getIntent().getExtras();
assert b != null;
id = b.getString("id");
windowId = b.getInt("windowId");

channel = new MethodChannel(Shared.messenger, "com.pichillilorenzo/flutter_inappbrowser_" + id);

setContentView(R.layout.activity_web_view);

Map<String, Object> pullToRefreshInitialOptions = (Map<String, Object>) b.getSerializable("pullToRefreshInitialOptions");
Map<String, Object> pullToRefreshInitialOptions = (Map<String, Object>) b.getSerializable("pullToRefreshInitialOptions");
MethodChannel pullToRefreshLayoutChannel = new MethodChannel(Shared.messenger, "com.pichillilorenzo/flutter_inappwebview_pull_to_refresh_" + id);
PullToRefreshOptions pullToRefreshOptions = new PullToRefreshOptions();
pullToRefreshOptions.parse(pullToRefreshInitialOptions);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
import android.webkit.MimeTypeMap;
import android.util.Log;

import androidx.annotation.NonNull;

import com.pichillilorenzo.flutter_inappwebview.Shared;

import java.io.Serializable;
Expand All @@ -58,7 +60,7 @@ public InAppBrowserManager(BinaryMessenger messenger) {
}

@Override
public void onMethodCall(final MethodCall call, final Result result) {
public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result result) {
final Activity activity = Shared.activity;

switch (call.method) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import android.graphics.Color;
import android.graphics.Point;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
Expand Down Expand Up @@ -41,30 +41,28 @@
import android.webkit.WebHistoryItem;
import android.webkit.WebSettings;
import android.webkit.WebStorage;
import android.webkit.WebView;
import android.widget.HorizontalScrollView;
import android.widget.LinearLayout;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.webkit.JavaScriptReplyProxy;
import androidx.webkit.WebMessageCompat;
import androidx.webkit.WebViewCompat;
import androidx.webkit.WebViewFeature;

import com.pichillilorenzo.flutter_inappwebview.types.PluginScript;
import com.pichillilorenzo.flutter_inappwebview.types.PreferredContentModeOptionType;
import com.pichillilorenzo.flutter_inappwebview.types.UserContentController;
import com.pichillilorenzo.flutter_inappwebview.JavaScriptBridgeInterface;
import com.pichillilorenzo.flutter_inappwebview.R;
import com.pichillilorenzo.flutter_inappwebview.Shared;
import com.pichillilorenzo.flutter_inappwebview.Util;
import com.pichillilorenzo.flutter_inappwebview.content_blocker.ContentBlocker;
import com.pichillilorenzo.flutter_inappwebview.content_blocker.ContentBlockerAction;
import com.pichillilorenzo.flutter_inappwebview.content_blocker.ContentBlockerHandler;
import com.pichillilorenzo.flutter_inappwebview.content_blocker.ContentBlockerTrigger;
import com.pichillilorenzo.flutter_inappwebview.types.ContentWorld;
import com.pichillilorenzo.flutter_inappwebview.in_app_browser.InAppBrowserDelegate;
import com.pichillilorenzo.flutter_inappwebview.JavaScriptBridgeInterface;
import com.pichillilorenzo.flutter_inappwebview.R;
import com.pichillilorenzo.flutter_inappwebview.Shared;
import com.pichillilorenzo.flutter_inappwebview.types.URLRequest;
import com.pichillilorenzo.flutter_inappwebview.types.UserScript;
import com.pichillilorenzo.flutter_inappwebview.Util;
import com.pichillilorenzo.flutter_inappwebview.plugin_scripts_js.ConsoleLogJS;
import com.pichillilorenzo.flutter_inappwebview.plugin_scripts_js.InterceptAjaxRequestJS;
import com.pichillilorenzo.flutter_inappwebview.plugin_scripts_js.InterceptFetchRequestJS;
Expand All @@ -75,19 +73,25 @@
import com.pichillilorenzo.flutter_inappwebview.plugin_scripts_js.PluginScriptsUtil;
import com.pichillilorenzo.flutter_inappwebview.plugin_scripts_js.PrintJS;
import com.pichillilorenzo.flutter_inappwebview.plugin_scripts_js.PromisePolyfillJS;
import com.pichillilorenzo.flutter_inappwebview.types.ContentWorld;
import com.pichillilorenzo.flutter_inappwebview.types.PluginScript;
import com.pichillilorenzo.flutter_inappwebview.types.PreferredContentModeOptionType;
import com.pichillilorenzo.flutter_inappwebview.types.URLRequest;
import com.pichillilorenzo.flutter_inappwebview.types.UserContentController;
import com.pichillilorenzo.flutter_inappwebview.types.UserScript;
import com.pichillilorenzo.flutter_inappwebview.types.WebMessageChannel;
import com.pichillilorenzo.flutter_inappwebview.types.WebMessageListener;

import org.json.JSONObject;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.UUID;
import java.util.regex.Pattern;

Expand Down Expand Up @@ -140,6 +144,8 @@ final public class InAppWebView extends InputAwareWebView {
public Map<String, ValueCallback<String>> callAsyncJavaScriptCallbacks = new HashMap<>();
public Map<String, ValueCallback<String>> evaluateJavaScriptContentWorldCallbacks = new HashMap<>();

public Map<String, WebMessageChannel> webMessageChannels = new HashMap<>();

public InAppWebView(Context context) {
super(context);
}
Expand Down Expand Up @@ -1587,13 +1593,38 @@ public void onReceiveValue(String value) {
});
}

@TargetApi(Build.VERSION_CODES.M)
public WebMessageChannel createCompatWebMessageChannel() {
String id = UUID.randomUUID().toString();
WebMessageChannel webMessageChannel = new WebMessageChannel(id, this);
webMessageChannels.put(id, webMessageChannel);
return webMessageChannel;
}

public void addWebMessageListener(@NonNull WebMessageListener webMessageListener) {
WebViewCompat.addWebMessageListener(this, webMessageListener.jsObjectName, webMessageListener.allowedOriginRules, webMessageListener.listener);
}

public void disposeWebMessageChannels() {
for (WebMessageChannel webMessageChannel : webMessageChannels.values()) {
webMessageChannel.dispose();
}
webMessageChannels.clear();
}

// @Override
// protected void onWindowVisibilityChanged(int visibility) {
// if (visibility != View.GONE) super.onWindowVisibilityChanged(View.VISIBLE);
// }

@Override
public void dispose() {
if (windowId != null) {
InAppWebViewChromeClient.windowWebViewMessages.remove(windowId);
}
headlessHandler.removeCallbacksAndMessages(null);
mHandler.removeCallbacksAndMessages(null);
disposeWebMessageChannels();
removeAllViews();
if (checkContextMenuShouldBeClosedTask != null)
removeCallbacks(checkContextMenuShouldBeClosedTask);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ public void loadCustomJavaScriptOnPageFinished(WebView view) {
public void onPageStarted(WebView view, String url, Bitmap favicon) {
final InAppWebView webView = (InAppWebView) view;
webView.isLoading = true;

webView.disposeWebMessageChannels();
webView.userContentController.resetContentWorlds();
loadCustomJavaScriptOnPageStarted(webView);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ public Map<String, Object> toMap() {
Map<String, Object> navigationActionMap = new HashMap<>();
navigationActionMap.put("request", request.toMap());
navigationActionMap.put("isForMainFrame", isForMainFrame);
navigationActionMap.put("hasGesture", hasGesture);
navigationActionMap.put("isRedirect", isRedirect);
navigationActionMap.put("androidHasGesture", hasGesture);
navigationActionMap.put("androidIsRedirect", isRedirect);
return navigationActionMap;
}

Expand Down
Loading

0 comments on commit a408310

Please sign in to comment.