Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

App crashing with "supportMultipleWindows:true" #388

Open
rajeshzmoke opened this issue Jun 9, 2020 · 11 comments
Open

App crashing with "supportMultipleWindows:true" #388

rajeshzmoke opened this issue Jun 9, 2020 · 11 comments

Comments

@rajeshzmoke
Copy link

rajeshzmoke commented Jun 9, 2020

Environment

[✓] Flutter (Channel stable, v1.17.3, on Mac OS X 10.14.6 18G103, locale en-IN)
    • Flutter version 1.17.3 at /Users/dhruv/Desktop/flutter
    • Framework revision b041144f83 (5 days ago), 2020-06-04 09:26:11 -0700
    • Engine revision ee76268252
    • Dart version 2.8.4

[✓] Android toolchain - develop for Android devices (Android SDK version 29.0.3)
    • Android SDK at /Users/dhruv/Library/Android/sdk
    • Platform android-29, build-tools 29.0.3
    • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 1.8.0_212-release-1586-b4-5784211)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 11.3.1)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Xcode 11.3.1, Build version 11C505
    • CocoaPods version 1.8.4

[✓] Android Studio (version 3.6)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin version 45.1.1
    • Dart plugin version 192.7761
    • Java version OpenJDK Runtime Environment (build 1.8.0_212-release-1586-b4-5784211)

[✓] VS Code (version 1.45.1)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.11.0

[✓] Connected device (1 available)
    • Android SDK built for x86 • emulator-5554 • android-x86 • Android 10 (API 29) (emulator)

• No issues found!

flutter_inappwebview: ^3.3.0+3

Description

App crashing when clicking on a link that opens in a new tab,
Expected behavior: loading inital url and then when clicking on a button in the webview open a new new window/ tab

Current behavior: loading initial url and when clicking on a button in the webview crashes the app

Steps to reproduce

InAppWebView(
        key: widget.key,
        initialOptions: InAppWebViewGroupOptions(
            android: AndroidInAppWebViewOptions(
              supportMultipleWindows: true,
            ),
            crossPlatform: InAppWebViewOptions(
              debuggingEnabled: true,
              javaScriptEnabled: true,
              useShouldOverrideUrlLoading: true,
            )),
        onCreateWindow: (controller, onCreateWindowRequest) async {
          print(onCreateWindowRequest);
          controller.loadUrl(url: onCreateWindowRequest.url);

          // await launch(onCreateWindowRequest.url);

          return true;
        },
        shouldOverrideUrlLoading: (controller, shouldOverrideUrlLoadingRequest) async {
          return ShouldOverrideUrlLoadingAction.ALLOW;
        },
        onWebViewCreated: (InAppWebViewController controller) {
          if (mounted) {
            setCookie(controller);
          }
        },
        onLoadError: (
          InAppWebViewController controller,
          String url,
          int code,
          String message,
        ) {
          print(message);
        },
        onLoadHttpError: (
          InAppWebViewController controller,
          String url,
          int code,
          String message,
        ) {
          print(message);
        },
        onProgressChanged: (InAppWebViewController controller, int progress) async {
          if (mounted) {
          
            if (progress > 50) {
              controller.injectCSSCode(source: ".sn-l__navBar-wrapper{display:none};");
            }
          }
        },
        onLoadStart: (InAppWebViewController controller, String url) {
          if (mounted) {
            if (url.startsWith(widget.url)) {
            }
          }
        },
        onLoadStop: (InAppWebViewController controller, String url) {
          if (mounted) {
            controller.injectCSSCode(source: ".sn-l__navBar-wrapper{display:none};");
          }
        },
      )

Stacktrace/Logcat

System.err(20202): java.lang.NullPointerException: Attempt to read from field 'android.view.WindowManager$LayoutParams android.view.ViewRootImpl.mWindowAttributes' on a null object reference
W/System.err(20202): 	at android.view.inputmethod.InputMethodManager.startInputInner(InputMethodManager.java:1625)
W/System.err(20202): 	at android.view.inputmethod.InputMethodManager.checkFocus(InputMethodManager.java:1864)
W/System.err(20202): 	at android.view.inputmethod.InputMethodManager.isActive(InputMethodManager.java:1183)
W/System.err(20202): 	at LM.a(PG:2)
W/System.err(20202): 	at org.chromium.content.browser.input.ImeAdapterImpl.n(PG:230)
W/System.err(20202): 	at org.chromium.content.browser.input.ImeAdapterImpl.f(PG:280)
W/System.err(20202): 	at org.chromium.content.browser.input.ImeAdapterImpl.onConnectedToRenderProcess(PG:481)
W/System.err(20202): 	at org.chromium.content.browser.framehost.NavigationControllerImpl.nativeLoadUrl(Native Method)
W/System.err(20202): 	at org.chromium.content.browser.framehost.NavigationControllerImpl.a(PG:67)
W/System.err(20202): 	at org.chromium.android_webview.AwContents.b(PG:602)
W/System.err(20202): 	at org.chromium.android_webview.AwContents.a(PG:437)
W/System.err(20202): 	at org.chromium.android_webview.AwContents.b(PG:442)
W/System.err(20202): 	at com.android.webview.chromium.WebViewChromium.loadUrl(PG:251)
W/System.err(20202): 	at android.webkit.WebView.loadUrl(WebView.java:727)
W/System.err(20202): 	at io.flutter.plugins.webviewflutter.FlutterWebView.<init>(FlutterWebView.java:113)
W/System.err(20202): 	at io.flutter.plugins.webviewflutter.WebViewFactory.create(WebViewFactory.java:29)
W/System.err(20202): 	at io.flutter.plugin.platform.SingleViewPresentation.onCreate(SingleViewPresentation.java:179)
W/System.err(20202): 	at android.app.Dialog.dispatchOnCreate(Dialog.java:421)
W/System.err(20202): 	at android.app.Dialog.show(Dialog.java:315)
W/System.err(20202): 	at android.app.Presentation.show(Presentation.java:250)
W/System.err(20202): 	at io.flutter.plugin.platform.VirtualDisplayController.<init>(VirtualDisplayController.java:94)
W/System.err(20202): 	at io.flutter.plugin.platform.VirtualDisplayController.create(VirtualDisplayController.java:47)
W/System.err(20202): 	at io.flutter.plugin.platform.PlatformViewsController$1.createPlatformView(PlatformViewsController.java:112)
W/System.err(20202): 	at io.flutter.embedding.engine.systemchannels.PlatformViewsChannel$1.create(PlatformViewsChannel.java:95)
W/System.err(20202): 	at io.flutter.embedding.engine.systemchannels.PlatformViewsChannel$1.onMethodCall(PlatformViewsChannel.java:59)
W/System.err(20202): 	at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler.onMessage(MethodChannel.java:226)
W/System.err(20202): 	at io.flutter.embedding.engine.dart.DartMessenger.handleMessageFromDart(DartMessenger.java:85)
W/System.err(20202): 	at io.flutter.embedding.engine.FlutterJNI.handlePlatformMessage(FlutterJNI.java:631)
W/System.err(20202): 	at android.os.MessageQueue.nativePollOnce(Native Method)
W/System.err(20202): 	at android.os.MessageQueue.next(MessageQueue.java:336)
W/System.err(20202): 	at android.os.Looper.loop(Looper.java:174)
W/System.err(20202): 	at android.app.ActivityThread.main(ActivityThread.java:7356)
W/System.err(20202): 	at java.lang.reflect.Method.invoke(Native Method)
W/System.err(20202): 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
W/System.err(20202): 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
D/EGL_emulation(20202): eglMakeCurrent: 0xb1657fc0: ver 3 0 (tinfo 0xbda1ed10)
E/eglCodecCommon(20202): glUtilsParamSize: unknow param 0x000088ef
E/eglCodecCommon(20202): glUtilsParamSize: unknow param 0x000088ef
D/eglCodecCommon(20202): setVertexArrayObject: set vao to 5 (5) 0 0
F/chromium(20202): [FATAL:jni_android.cc(249)] Please include Java exception stack in crash report
F/libc    (20202): Fatal signal 5 (SIGTRAP), code 128 (SI_KERNEL), fault addr 0x0 in tid 20202 (ensibull.mobile), pid 20202 (ensibull.mobile)
@alex-min
Copy link

alex-min commented Jun 23, 2020

I had the same bug and I found how it happens, it happens when the onCreateWindow.url is 'about:blank' if you do

  onCreateWindow: (controller, onCreateWindow) {
        controller.loadUrl(url: 'https://www.google.com');
      },

the error disappear, not sure now I can load the blank tab yet then though.

@pichillilorenzo
Copy link
Owner

.. open a new window/ tab ..

You need yourself to implement webview tab features, InAppWebView widget is not a browser, but a WebView. The onCreateWindow is just an event that intercepts this intent. If you want to open a new InAppWebView widget, you need to implement it yourself, like creating a browser app.

@alex-min I cannot reproduce your error. This example is working fine when I click on <a target="_blank" href="about:blank">TEST TEST TEST</a>:

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';

Future main() async {
  WidgetsFlutterBinding.ensureInitialized();
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => new _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        home: InAppWebViewPage()
    );
  }
}

class InAppWebViewPage extends StatefulWidget {
  @override
  _InAppWebViewPageState createState() => new _InAppWebViewPageState();
}

class _InAppWebViewPageState extends State<InAppWebViewPage> {
  InAppWebViewController _webViewController;

  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
            title: Text("InAppWebView")
        ),
        body: SafeArea(
            child: Column(children: <Widget>[
              Expanded(
                child: Container(
                  margin: const EdgeInsets.all(20.0),
                  decoration:
                  BoxDecoration(border: Border.all(color: Colors.blueAccent)),
                  child: InAppWebView(
                    initialData: InAppWebViewInitialData(
                        data: """
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Flutter InAppWebView</title>
</head>
<body class="text-center">
    <a target="_blank" href="about:blank">TEST TEST TEST</a>
</body>
</html>
                      """
                    ),
                    initialHeaders: {},
                    initialOptions: InAppWebViewGroupOptions(
                        crossPlatform: InAppWebViewOptions(
                          debuggingEnabled: true,
                          useShouldOverrideUrlLoading: true,
                        ),
                        android: AndroidInAppWebViewOptions(
                            supportMultipleWindows: true
                        )
                    ),
                    onWebViewCreated: (InAppWebViewController controller) {
                      print("onWebViewCreated");
                      _webViewController = controller;
                    },
                    onCreateWindow: (controller, onCreateWindowRequest) async {
                      print("onCreateWindow called");
                      controller.loadUrl(url: onCreateWindowRequest.url);
                    },
                    onLoadStart: (InAppWebViewController controller, String url) {
                      print("onLoadStart $url");
                    },
                    onLoadStop: (InAppWebViewController controller, String url) async {
                      print("onLoadStop $url");
                    },
                  ),
                ),
              ),
            ]))
    );
  }
}

Could you share the URL that contains the link of your blank tab?
@rajeshzmoke if you can, you too, otherwise I cannot debug this error.

Also, this error happens on all devices and in all cases?
Thanks

@alex-min
Copy link

After more investigation, it does happen from some urls and not others, I'm not sure what causes it, google.com is totally fine but I was trying to integrate plaid.com and the plaid window is a 100% crash. You can try to navigate to this url with loadUrl: https://cdn.plaid.com/link/v2/stable/sandbox-oauth-login.html?redirect_uri=https%3A%2F%2Fcdn.plaid.com%2Flink%2Fv2%2Fstable%2Foauth.html&state=eyJvYXV0aF9zdGF0ZV9pZCI6Ijk0ZjJhN2RkLTVlYzMtNDYxNC1hZWQ4LWI0MDFiZjgyZWE5NiIsInVzZV9vYXV0aF9jYWxsYmFjayI6ZmFsc2UsInBsYWlkX2VudiI6InNhbmRib3gifQ. So I'm not sure what js api causes it, difficult to say.

@alex-min
Copy link

let me know if you can reproduce as well

@pichillilorenzo
Copy link
Owner

pichillilorenzo commented Jun 23, 2020

@alex-min This is working fine:

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';

Future main() async {
  WidgetsFlutterBinding.ensureInitialized();
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => new _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        home: InAppWebViewPage()
    );
  }
}

class InAppWebViewPage extends StatefulWidget {
  @override
  _InAppWebViewPageState createState() => new _InAppWebViewPageState();
}

class _InAppWebViewPageState extends State<InAppWebViewPage> {
  InAppWebViewController _webViewController;

  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
            title: Text("InAppWebView")
        ),
        body: SafeArea(
            child: Column(children: <Widget>[
              Expanded(
                child: Container(
                  child: InAppWebView(
                    initialData: InAppWebViewInitialData(
                        data: """
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Flutter InAppWebView</title>
</head>
<body class="text-center">
    <a target="_blank" href="https://cdn.plaid.com/link/v2/stable/sandbox-oauth-login.html?redirect_uri=https%3A%2F%2Fcdn.plaid.com%2Flink%2Fv2%2Fstable%2Foauth.html&state=eyJvYXV0aF9zdGF0ZV9pZCI6Ijk0ZjJhN2RkLTVlYzMtNDYxNC1hZWQ4LWI0MDFiZjgyZWE5NiIsInVzZV9vYXV0aF9jYWxsYmFjayI6ZmFsc2UsInBsYWlkX2VudiI6InNhbmRib3gifQ">TEST TEST TEST</a>
</body>
</html>
                      """
                    ),
                    initialHeaders: {},
                    initialOptions: InAppWebViewGroupOptions(
                        crossPlatform: InAppWebViewOptions(
                          debuggingEnabled: true,
                          useShouldOverrideUrlLoading: true,
                        ),
                        android: AndroidInAppWebViewOptions(
                            supportMultipleWindows: true
                        )
                    ),
                    onWebViewCreated: (InAppWebViewController controller) {
                      print("onWebViewCreated");
                      _webViewController = controller;
                    },
                    onCreateWindow: (controller, onCreateWindowRequest) async {
                      print("onCreateWindow called with URL ${onCreateWindowRequest.url}");
                      controller.loadUrl(url: onCreateWindowRequest.url);
                    },
                    onLoadStart: (InAppWebViewController controller, String url) {
                      print("onLoadStart $url");
                    },
                    onLoadStop: (InAppWebViewController controller, String url) async {
                      print("onLoadStop $url");
                    },
                  ),
                ),
              ),
            ]))
    );
  }
}

test_on_create_window

@alex-min
Copy link

That also works for me, I will try to reduce it to a minimum test case

@alex-min
Copy link

alex-min commented Jun 23, 2020

here you go, if you replace the html by that you can trigger it

InAppWebViewInitialData(data: """
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Flutter InAppWebView</title>
</head>
<body class="text-center">
    <a id="test">TEST TEST TEST</a>
    <script>
      document.getElementById('test').onclick = () => {
        let w = window.open('https://cdn.plaid.com/link/v2/stable/sandbox-oauth-login.html?redirect_uri=https%3A%2F%2Fcdn.plaid.com%2Flink%2Fv2%2Fstable%2Foauth.html&state=eyJvYXV0aF9zdGF0ZV9pZCI6Ijk0ZjJhN2RkLTVlYzMtNDYxNC1hZWQ4LWI0MDFiZjgyZWE5NiIsInVzZV9vYXV0aF9jYWxsYmFjayI6ZmFsc2UsInBsYWlkX2VudiI6InNhbmRib3gifQ', 'test');
        w.focus();
        setInterval(() => {
          console.log(w.closed);
          console.log(w.opener);
        }, 1000);
      }
    </script>
</body>
</html>
                      """)

@pichillilorenzo
Copy link
Owner

I tried it but I didn't have any error. Instead, I received about:blank as URL of onCreateWindow event. Using javascript is a little bit problematic.

So, I'm thinking to re-implement the onCreateWindow event in another way, adding also the onCloseWindow event (in android, for example, is the https://developer.android.com/reference/android/webkit/WebChromeClient#onCloseWindow(android.webkit.WebView) event). I need to think about how to make it work in Flutter.

@alex-min
Copy link

Ah interesting, there's maybe something different on my config, this sample triggers 100% of the time the crash on my end. Actually it seems to be more the .closed & .opener which seems to cause problems for me rather than the window.open(), I've added them because it's what plaid.com does in a setInterval (I've spied with object proxies to find that) and that what I think makes the page crash.

here is my flutter doctor if it can help you:

[✓] Flutter (Channel stable, v1.17.4, on Linux, locale fr_FR.UTF-8)
    • Flutter version 1.17.4 at /usr/share/flutter
    • Framework revision 1ad9baa8b9 (il y a 6 jours), 2020-06-17 14:41:16 -0700
    • Engine revision ee76268252
    • Dart version 2.8.4

 
[✓] Android toolchain - develop for Android devices (Android SDK version 29.0.2)
    • Android SDK at /home/alex/Android/Sdk
    • Platform android-30, build-tools 29.0.2
    • ANDROID_HOME = /home/alex/Android/Sdk
    • Java binary at: /home/alex/android/android-studio/jre/bin/java
    • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6222593)
    • All Android licenses accepted.

[✓] Android Studio (version 4.0)
    • Android Studio at /home/alex/android/android-studio
    • Flutter plugin version 46.0.2
    • Dart plugin version 193.7361
    • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6222593)

[✓] Connected device (1 available)
    • Android SDK built for x86 • emulator-5554 • android-x86 • Android 10 (API 29) (emulator)

• No issues found!

Let me know if I can help you with any command, the traceback I have is identical of the one of @rajeshzmoke

@rajeshzmoke
Copy link
Author

@alex-min @pichillilorenzo so what i've found is that when debugging in an android emulator i get an actual url in onCreateWindow callback but when i run it in release mode, i get an about blank.

also i know for a fact that the webapp which i open in webview does a window.post() to the new tab that is being opened.

We have stopped fixing this issue on flutter side as i couldnt find any feasible library or a way to fix this and instead make the new url make api call instead of using window.post() in the webapp, which is a reasonable workaround for us

@pichillilorenzo
Copy link
Owner

For example, at this moment, the Android onCreateWindow implementation can be found here:

public boolean onCreateWindow(WebView view, boolean isDialog, boolean isUserGesture, final Message resultMsg) {

If needed, I create a temp WebView to get the URL and then I destroy it.
Instead, I need to change it in order to be able to create an InAppWebView instance from the Flutter side, otherwise, the created WebView will result in an always closed window.
Also, this should be done on iOS.

I need to think about it and how to do that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants