changeset 10845:808d535c4e15

8196011: Intermittent crash when using WebView from JFXPanel application Reviewed-by: arajkumar, kcr
author ghb
date Fri, 23 Feb 2018 09:21:06 +0530
parents 1438734a46e3
children 85ff3bc0c670
files modules/javafx.web/src/main/java/com/sun/javafx/webkit/InputMethodClientImpl.java modules/javafx.web/src/main/java/com/sun/webkit/WebPage.java modules/javafx.web/src/test/java/test/javafx/scene/web/WebPageTest.java
diffstat 3 files changed, 57 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/modules/javafx.web/src/main/java/com/sun/javafx/webkit/InputMethodClientImpl.java	Sat Feb 17 08:47:36 2018 -0800
+++ b/modules/javafx.web/src/main/java/com/sun/javafx/webkit/InputMethodClientImpl.java	Fri Feb 23 09:21:06 2018 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -29,8 +29,13 @@
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.FutureTask;
+import java.util.logging.Level;
+import java.util.logging.Logger;
 
 import com.sun.javafx.scene.input.ExtendedInputMethodRequests;
+import com.sun.webkit.Invoker;
 import javafx.geometry.Point2D;
 import javafx.scene.input.InputMethodEvent;
 import javafx.scene.input.InputMethodHighlight;
@@ -46,6 +51,8 @@
 public final class InputMethodClientImpl
     implements InputMethodClient, ExtendedInputMethodRequests
 {
+    private static final Logger log =
+            Logger.getLogger(InputMethodClientImpl.class.getName());
     private final WeakReference<WebView> wvRef;
     private final WebPage webPage;
 
@@ -118,16 +125,42 @@
 
     // InputMethodRequests implementation
     public Point2D getTextLocation(int offset) {
-        int[] loc = webPage.getClientTextLocation(offset);
-        WCPoint point = webPage.getPageClient().windowToScreen(
-                // We need lower left corner of the char bounds rectangle here
-                new WCPoint(loc[0], loc[1] + loc[3]));
-        return new Point2D(point.getIntX(), point.getIntY());
+        FutureTask<Point2D> f = new FutureTask<>(() -> {
+            int[] loc = webPage.getClientTextLocation(offset);
+            WCPoint point = webPage.getPageClient().windowToScreen(
+                    // We need lower left corner of the char bounds rectangle here
+                    new WCPoint(loc[0], loc[1] + loc[3]));
+            return new Point2D(point.getIntX(), point.getIntY());
+        });
+
+        Invoker.getInvoker().invokeOnEventThread(f);
+        Point2D result = null;
+        try {
+            result = f.get();
+        } catch (ExecutionException ex) {
+            log.log(Level.SEVERE, "InputMethodClientImpl.getTextLocation " + ex);
+        } catch (InterruptedException ex) {
+            log.log(Level.SEVERE, "InputMethodClientImpl.getTextLocation InterruptedException" + ex);
+        }
+        return result;
     }
 
     public int getLocationOffset(int x, int y) {
-        WCPoint point = webPage.getPageClient().windowToScreen(new WCPoint(0, 0));
-        return webPage.getClientLocationOffset(x - point.getIntX(), y - point.getIntY());
+        FutureTask<Integer> f = new FutureTask<>(() -> {
+            WCPoint point = webPage.getPageClient().windowToScreen(new WCPoint(0, 0));
+            return webPage.getClientLocationOffset(x - point.getIntX(), y - point.getIntY());
+        });
+
+        Invoker.getInvoker().invokeOnEventThread(f);
+        int location = 0;
+        try {
+            location = f.get();
+        } catch (ExecutionException ex) {
+            log.log(Level.SEVERE, "InputMethodClientImpl.getLocationOffset " + ex);
+        } catch (InterruptedException ex) {
+            log.log(Level.SEVERE, "InputMethodClientImpl.getTextLocation InterruptedException" + ex);
+        }
+        return location;
     }
 
     public void cancelLatestCommittedText() {
--- a/modules/javafx.web/src/main/java/com/sun/webkit/WebPage.java	Sat Feb 17 08:47:36 2018 -0800
+++ b/modules/javafx.web/src/main/java/com/sun/webkit/WebPage.java	Fri Feb 23 09:21:06 2018 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -918,6 +918,7 @@
                 log.log(Level.FINE, "getClientTextLocation() request for a disposed web page.");
                 return new int[] { 0, 0, 0, 0 };
             }
+            Invoker.getInvoker().checkEventThread();
             return twkGetTextLocation(getPage(), index);
 
         } finally {
@@ -932,6 +933,7 @@
                 log.log(Level.FINE, "getClientLocationOffset() request for a disposed web page.");
                 return 0;
             }
+            Invoker.getInvoker().checkEventThread();
             return twkGetInsertPositionOffset(getPage());
 
         } finally {
--- a/modules/javafx.web/src/test/java/test/javafx/scene/web/WebPageTest.java	Sat Feb 17 08:47:36 2018 -0800
+++ b/modules/javafx.web/src/test/java/test/javafx/scene/web/WebPageTest.java	Fri Feb 23 09:21:06 2018 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -89,4 +89,16 @@
         load(WebPageTest.class.getClassLoader().getResource(
                 "test/html/icutagparse.html").toExternalForm());
     }
+
+    @Test(expected = IllegalStateException.class)
+    public void testGetClientTextLocationFromNonEventThread() {
+        WebPage page = WebEngineShim.getPage(getEngine());
+        page.getClientTextLocation(0);
+    }
+
+    @Test(expected = IllegalStateException.class)
+    public void testGetClientLocationOffsetFromNonEventThread() {
+        WebPage page = WebEngineShim.getPage(getEngine());
+        page.getClientLocationOffset(0, 0);
+    }
 }