New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.

Issue 632214 link

Starred by 2 users

Issue metadata

Status: WontFix
Owner:
inactive
Closed: Aug 2016
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: Android
Pri: 3
Type: Bug



Sign in to add a comment

[NYC] Cannot select texts when webview is displayed inside a popup window

Project Member Reported by hush@chromium.org, Jul 28 2016

Issue description

Steps to reproduce:
1. create an app that opens a popup window that contains a webview
2. try to select some texts in the webview
3. observe that you can't select anything.
And logcat has the following message:
07-27 16:55:28.702   507  1094 W WindowManager: Attempted to add window with token that is a sub-window: android.os.BinderProxy@df784dd.  Aborting.
07-27 16:55:28.705   507   518 W WindowManager: Attempted to add window with token that is a sub-window: android.os.BinderProxy@df784dd.  Aborting.

Note:
On M, trying to select any text in a popupwindow will crash:
07-27 16:59:31.115 13096 13096 W System.err: android.view.WindowManager$BadTokenException: Unable to add window -- token android.view.ViewRootImpl$W@9baf123 is not valid; is your activity running?
07-27 16:59:31.116 13096 13096 W System.err: 	at android.view.ViewRootImpl.setView(ViewRootImpl.java:567)
07-27 16:59:31.116 13096 13096 W System.err: 	at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:310)
07-27 16:59:31.116 13096 13096 W System.err: 	at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:85)
07-27 16:59:31.116 13096 13096 W System.err: 	at android.widget.PopupWindow.invokePopup(PopupWindow.java:1258)
07-27 16:59:31.116 13096 13096 W System.err: 	at android.widget.PopupWindow.showAtLocation(PopupWindow.java:1032)
07-27 16:59:31.116 13096 13096 W System.err: 	at android.widget.PopupWindow.showAtLocation(PopupWindow.java:995)
07-27 16:59:31.116 13096 13096 W System.err: 	at org.chromium.content.browser.input.PopupTouchHandleDrawable.show(PopupTouchHandleDrawable.java:354)
07-27 16:59:31.116 13096 13096 W System.err: 	at org.chromium.android_webview.AwContents.nativeOnDraw(Native Method)
07-27 16:59:31.116 13096 13096 W System.err: 	at org.chromium.android_webview.AwContents.access$4500(AwContents.java:92)
07-27 16:59:31.116 13096 13096 W System.err: 	at org.chromium.android_webview.AwContents$AwViewMethodsImpl.onDraw(AwContents.java:2731)
07-27 16:59:31.117 13096 13096 W System.err: 	at org.chromium.android_webview.AwContents.onDraw(AwContents.java:1191)
07-27 16:59:31.117 13096 13096 W System.err: 	at com.android.webview.chromium.WebViewChromium.onDraw(WebViewChromium.java:1713)
07-27 16:59:31.117 13096 13096 W System.err: 	at android.webkit.WebView.onDraw(WebView.java:2486)
07-27 16:59:31.117 13096 13096 W System.err: 	at android.view.View.draw(View.java:16178)
07-27 16:59:31.117 13096 13096 W System.err: 	at android.view.View.updateDisplayListIfDirty(View.java:15174)
07-27 16:59:31.117 13096 13096 W System.err: 	at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3593)
07-27 16:59:31.117 13096 13096 W System.err: 	at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3573)
07-27 16:59:31.117 13096 13096 W System.err: 	at android.view.View.updateDisplayListIfDirty(View.java:15134)
07-27 16:59:31.117 13096 13096 W System.err: 	at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3593)
07-27 16:59:31.117 13096 13096 W System.err: 	at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3573)
07-27 16:59:31.117 13096 13096 W System.err: 	at android.view.View.updateDisplayListIfDirty(View.java:15134)
07-27 16:59:31.117 13096 13096 W System.err: 	at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3593)
07-27 16:59:31.117 13096 13096 W System.err: 	at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3573)
07-27 16:59:31.117 13096 13096 W System.err: 	at android.view.View.updateDisplayListIfDirty(View.java:15134)
07-27 16:59:31.117 13096 13096 W System.err: 	at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:281)
07-27 16:59:31.117 13096 13096 W System.err: 	at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:287)
07-27 16:59:31.117 13096 13096 W System.err: 	at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:322)
07-27 16:59:31.117 13096 13096 W System.err: 	at android.view.ViewRootImpl.draw(ViewRootImpl.java:2615)
07-27 16:59:31.117 13096 13096 W System.err: 	at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2434)
07-27 16:59:31.118 13096 13096 W System.err: 	at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2067)
07-27 16:59:31.118 13096 13096 W System.err: 	at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1107)
07-27 16:59:31.118 13096 13096 W System.err: 	at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6013)
07-27 16:59:31.118 13096 13096 W System.err: 	at android.view.Choreographer$CallbackRecord.run(Choreographer.java:858)
07-27 16:59:31.118 13096 13096 W System.err: 	at android.view.Choreographer.doCallbacks(Choreographer.java:670)
07-27 16:59:31.118 13096 13096 W System.err: 	at android.view.Choreographer.doFrame(Choreographer.java:606)
07-27 16:59:31.118 13096 13096 W System.err: 	at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:844)
07-27 16:59:31.118 13096 13096 W System.err: 	at android.os.Handler.handleCallback(Handler.java:739)
07-27 16:59:31.118 13096 13096 W System.err: 	at android.os.Handler.dispatchMessage(Handler.java:95)
07-27 16:59:31.118 13096 13096 W System.err: 	at android.os.Looper.loop(Looper.java:148)
07-27 16:59:31.118 13096 13096 W System.err: 	at android.app.ActivityThread.main(ActivityThread.java:5417)
07-27 16:59:31.118 13096 13096 W System.err: 	at java.lang.reflect.Method.invoke(Native Method)
07-27 16:59:31.118 13096 13096 W System.err: 	at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
07-27 16:59:31.118 13096 13096 W System.err: 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

 

Comment 1 by hush@chromium.org, Jul 28 2016

Cc: sgu...@chromium.org aelias@chromium.org boliu@chromium.org
Components: Mobile>WebView
Status: Available (was: Untriaged)
I think the issue is that we implement the selection handlers as popup windows. And Android does not support opening popup window in another popup window.

Comment 2 by hush@chromium.org, Jul 28 2016

Labels: OS-Android

Comment 3 by aelias@chromium.org, Jul 28 2016

Cc: amaralp@chromium.org siev...@chromium.org
Hmm, interesting.  We were chatting recently about the possibility of switching them composited like in Chrome, this would be another reason.

Comment 4 by sgu...@chromium.org, Jul 28 2016

Well moreover, trying to select in versions lower than N causes it to crash. (same with html selects).

Comment 5 by sgu...@chromium.org, Jul 28 2016

Alex, is there a bug for compositing? 

And this won't solve the HTML select tag problem in tablet's right?

Comment 6 by aelias@chromium.org, Jul 28 2016

We don't have a meta bug for compositing them, just a bunch of bugs on the symptoms.

For select tags, it wouldn't solve them per se, it would require a separate, analogous change with the same tradeoff (no more ability to spill out of the WebView).

Comment 7 by boliu@chromium.org, Jul 28 2016

This looks like the classic "trying to create a window with an application context" exception though. What *context* was passed into the webview? Can we detect it's not an activity and not create any pop up windows from it at all?

Taking a step back, I haven't seen any apps that put a webview into a popup window. Any particular reason we are worried about this now?

Comment 8 by hush@chromium.org, Jul 28 2016

WebView is created with an activity context.
The code is this in case you wonder:
import android.app.Activity;
import android.os.Bundle;
import android.os.Message;
import android.util.Log;
import android.view.Gravity;
import android.view.ViewGroup.LayoutParams;
import android.webkit.WebChromeClient;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.LinearLayout;
import android.widget.PopupWindow;

public class MainActivity extends Activity {

    private final String TAG = "PopUpWindow";
    private PopupWindow mPopUp;
    private LinearLayout mLayout;
    private LayoutParams mParams;
    private LinearLayout mMainLayout;
    private WebView mWebView;


    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mLayout = new LinearLayout(this);
        mMainLayout = new LinearLayout(this);

        mWebView = new WebView(this);
        mWebView.getSettings().setJavaScriptEnabled(true);
        mWebView.getSettings().setSupportMultipleWindows(true);

        mWebView.setWebChromeClient(new WebChromeClient() {
            @Override
            public boolean onCreateWindow(WebView view, boolean dialog, boolean userGesture, Message resultMsg) {
                if (mPopUp != null && mPopUp.isShowing()) {
                    mPopUp.dismiss();
                    mPopUp = null;
                    return false;
                }
                WebView.WebViewTransport transport = (WebView.WebViewTransport) resultMsg.obj;
                final WebView popupWebView = new WebView(view.getContext());
                popupWebView.setWebViewClient(new WebViewClient() {
                    @Override
                    public boolean shouldOverrideUrlLoading(WebView view, String url) {
                        android.util.Log.w(TAG, "popup webview ShouldOverride" + url);
                        return false;
                    }
                    @Override
                    public void onPageFinished(WebView view, String url) {
                        android.util.Log.w(TAG, "popup webview onPageFinished" + url);
                    }
                });
                popupWebView.getSettings().setJavaScriptEnabled(true);
                mLayout.addView(popupWebView);
                mPopUp = new PopupWindow(view.getContext());
                mPopUp.setContentView(mLayout);
                mPopUp.showAtLocation(mMainLayout, Gravity.BOTTOM, 0, 0);
                mPopUp.update(400,400,800,800);
                transport.setWebView(popupWebView);
                resultMsg.sendToTarget();
                return true;
            }
        });
        mWebView.setWebViewClient(new WebViewClient() {
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                Log.d(TAG, "ShouldOverrideUrlLoading main Webview" + url);
                return false;
            }
        });

        final String url = "https://output.jsbin.com/penade";
        String customHtml = "<html><body><h1>Hello, Test</h1>" +
                "<button type=\"button\" onclick=\"window.open('"+ url + "');\">" +
                "Clicking here to create a popup</button>" +
                "</body></html>";
        mWebView.loadData(customHtml, "text/html", "UTF-8");
        mParams = new LayoutParams(LayoutParams.WRAP_CONTENT,
                LayoutParams.WRAP_CONTENT);
        mLayout.setOrientation(LinearLayout.VERTICAL);
        mMainLayout.addView(mWebView, mParams);
        setContentView(mMainLayout);
    }
}


Comment 9 by boliu@chromium.org, Jul 28 2016

There's also the foolproof way: catch BadTokenException..

Comment 10 by hush@chromium.org, Jul 28 2016

sure that will make the crash go away (which is better than crashing) but the user still can't select texts I think, because the selection handles' creation is just blocked.

Actually, this probably affects textView in a popup window, too. I will confirm tomorrow. Maybe Android will be willing to make a change to support popup window in a popup window.
Cc: gsennton@chromium.org
Sidenote: I believe this should affect WebViews in Presentations as well (since a Presentation is a special version of a Dialog)?

Comment 12 by hush@chromium.org, Jul 28 2016

I've tested selecting TextView inside a PopupWindow. You can't.
The code to disallow this is here:
https://cs.corp.google.com/android/frameworks/base/core/java/android/widget/Editor.java?rcl=9382c5a7e4f2e6b90d2fa0810a2074701483496f&l=611
The popup window's LayoutParams.type == WindowManager.LayoutParams.FIRST_SUB_WINDOW.

So at least we're no worse than TextViews on Android platform.

Comment 13 by hush@chromium.org, Jul 28 2016

re #11: I'm not sure Dialogs are treated the same as PopupWindows.
Can you try and whip up a simple test app?
Yeah, I'll give it a go when I have time :)
So, what is the consensus here? Are we intending to do anything about this or will we just wait until the change from #3 is implemented?

Comment 16 by boliu@chromium.org, Aug 22 2016

make sure we don't crash and call it a day, probably
So that would mean catching BadTokenException? Could we miss other related crashes if we do so?

Comment 18 by torne@chromium.org, Aug 23 2016

If we wrap it "closely" around the places where we try to make popup windows, then it's pretty much only going to catch the places where we don't have a parent window in our context, so it shouldn't be too bad. But I think Bo meant testing upfront the way hush noted Editor does in #12? (i.e. avoiding the call in the first place if we know we're in a situation that will throw)

Comment 19 by boliu@chromium.org, Aug 23 2016

not really, turns out catching BadTokenException is the only way to detect this edge case

Comment 20 by torne@chromium.org, Aug 23 2016

Oh. Well, that should be okay if that's what must be done.
Owner: hush@chromium.org
Status: Assigned (was: Available)
Alright, hush@ would you like to do this?

Comment 22 by hush@chromium.org, Aug 23 2016

I think we can do something like #19 to just not crash on the popupwindow and reach "bug parity" with Android's TextView. We still can't bring up the selection handles, until we switch the selection handles' implementation or Android fixes the bug.

Comment 23 by hush@chromium.org, Aug 23 2016

Okay I don't think there is anything to do. We already catch the exception and that's why we don't crash in NYC. I was probably testing using an old webview on M in the original report.

https://cs.chromium.org/chromium/src/content/public/android/java/src/org/chromium/content/browser/input/PopupTouchHandleDrawable.java?rcl=0&l=457

Comment 24 by hush@chromium.org, Aug 23 2016

Status: WontFix (was: Assigned)

Sign in to add a comment