[NYC] Cannot select texts when webview is displayed inside a popup window |
||||||
Issue descriptionSteps 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)
,
Jul 28 2016
,
Jul 28 2016
Hmm, interesting. We were chatting recently about the possibility of switching them composited like in Chrome, this would be another reason.
,
Jul 28 2016
Well moreover, trying to select in versions lower than N causes it to crash. (same with html selects).
,
Jul 28 2016
Alex, is there a bug for compositing? And this won't solve the HTML select tag problem in tablet's right?
,
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).
,
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?
,
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);
}
}
,
Jul 28 2016
There's also the foolproof way: catch BadTokenException..
,
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.
,
Jul 28 2016
Sidenote: I believe this should affect WebViews in Presentations as well (since a Presentation is a special version of a Dialog)?
,
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.
,
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?
,
Jul 29 2016
Yeah, I'll give it a go when I have time :)
,
Aug 22 2016
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?
,
Aug 22 2016
make sure we don't crash and call it a day, probably
,
Aug 23 2016
So that would mean catching BadTokenException? Could we miss other related crashes if we do so?
,
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)
,
Aug 23 2016
not really, turns out catching BadTokenException is the only way to detect this edge case
,
Aug 23 2016
Oh. Well, that should be okay if that's what must be done.
,
Aug 23 2016
Alright, hush@ would you like to do this?
,
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.
,
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
,
Aug 23 2016
|
||||||
►
Sign in to add a comment |
||||||
Comment 1 by hush@chromium.org
, Jul 28 2016Components: Mobile>WebView
Status: Available (was: Untriaged)