changeset 6559:528413726c6e

[Accessibility, Win] Accessibility Crash on Windows due to bad order of View objects
author Felipe Heidrich <felipe.heidrich@oracle.com>
date Thu, 27 Mar 2014 15:09:45 -0700
parents ea3a56fc511b
children 9957b53164ae
files modules/graphics/src/main/java/com/sun/glass/ui/mac/MacAccessible.java modules/graphics/src/main/java/com/sun/glass/ui/win/WinAccessible.java modules/graphics/src/main/java/javafx/scene/Node.java modules/graphics/src/main/java/javafx/scene/Parent.java modules/graphics/src/main/java/javafx/scene/Scene.java modules/graphics/src/main/java/javafx/scene/accessibility/Accessible.java
diffstat 6 files changed, 79 insertions(+), 31 deletions(-) [+]
line wrap: on
line diff
--- a/modules/graphics/src/main/java/com/sun/glass/ui/mac/MacAccessible.java	Thu Mar 27 16:31:52 2014 -0400
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/mac/MacAccessible.java	Thu Mar 27 15:09:45 2014 -0700
@@ -608,10 +608,9 @@
         switch (notification) {
             case SELECTED_TAB:
             case SELECTED_PAGE: {
-                Scene scene = (Scene)getAttribute(SCENE);
-                if (scene != null) {
-                    PlatformAccessible acc = scene.getAccessible().impl_getDelegate();
-                    long id = acc.getView().getNativeView();
+                View view = getRootView((Scene)getAttribute(SCENE));
+                if (view != null) {
+                    long id = view.getNativeView();
                     NSAccessibilityPostNotification(id, MacNotifications.NSAccessibilityFocusedUIElementChangedNotification.ptr);
                 }
                 return;
@@ -657,6 +656,18 @@
         return peer;
     }
 
+    @SuppressWarnings("deprecation")
+    private View getRootView(Scene scene) {
+        if (scene == null) return null;
+        Accessible acc = scene.getAccessible();
+        if (acc == null) return null;
+        MacAccessible macAcc = (MacAccessible)acc.impl_getDelegate();
+        if (macAcc == null || macAcc.isDisposed()) return null;
+        View view = macAcc.getView();
+        if (view == null || view.isClosed()) return null;
+        return view;
+    }
+
     static long getAccessible(Node node) {
         if (node == null) return 0L;
         Accessible acc = node.getAccessible();
@@ -857,8 +868,9 @@
             case NSAccessibilityWindowAttribute:
             case NSAccessibilityTopLevelUIElementAttribute: {
                 Scene scene = (Scene)result;
-                PlatformAccessible acc = scene.getAccessible().impl_getDelegate();
-                result = acc.getView().getWindow().getNativeWindow();
+                View view = getRootView(scene);
+                if (view == null) return null;
+                result = view.getWindow().getNativeWindow();
                 break;
             }
             case NSAccessibilitySubroleAttribute: {
@@ -912,10 +924,9 @@
                     result = getAccessible((Parent)result);
                 } else {
                     /* Root node: return the NSView (instead of acc.getNativeAccessible()) */
-                    Scene scene = (Scene)getAttribute(SCENE);
-                    if (scene == null) return null;
-                    MacAccessible acc = (MacAccessible)scene.getAccessible().impl_getDelegate();
-                    result = acc.getView().getNativeView();
+                    View view = getRootView((Scene)getAttribute(SCENE));
+                    if (view == null) return null;
+                    result = view.getNativeView();
                 }
                 result = NSAccessibilityUnignoredAncestor((long)result);
                 break;
@@ -931,10 +942,8 @@
                  * NSAccessibilityPositionAttribute requires the point relative
                  * to the lower-left corner in screen.
                  */
-                Scene scene = (Scene)getAttribute(SCENE);
-                if (scene != null) {
-                    PlatformAccessible sceneAcc = scene.getAccessible().impl_getDelegate();
-                    View view = sceneAcc.getView();
+                View view = getRootView((Scene)getAttribute(SCENE));
+                if (view != null) {
                     Screen screen = view.getWindow().getScreen();
                     float height = screen.getHeight();
                     Bounds bounds = (Bounds)result;
--- a/modules/graphics/src/main/java/com/sun/glass/ui/win/WinAccessible.java	Thu Mar 27 16:31:52 2014 -0400
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/win/WinAccessible.java	Thu Mar 27 15:09:45 2014 -0700
@@ -233,6 +233,8 @@
 
     @Override
     public void sendNotification(Attribute notification) {
+        if (isDisposed()) return;
+
         switch (notification) {
             case FOCUS_NODE:
                 if (getView() != null) {
@@ -656,11 +658,14 @@
                 if (Boolean.FALSE.equals(focus)) {
                     Scene scene = (Scene)getAttribute(SCENE);
                     if (scene != null) {
-                        Node node = (Node)scene.getAccessible().getAttribute(FOCUS_NODE);
-                        if (node != null) {
-                            Node item = (Node)node.getAccessible().getAttribute(FOCUS_ITEM);
-                            if (getAccessible(item) == peer) {
-                                focus = true;
+                        Accessible acc = scene.getAccessible();
+                        if (acc != null) {
+                            Node node = (Node)acc.getAttribute(FOCUS_NODE);
+                            if (node != null) {
+                                Node item = (Node)node.getAccessible().getAttribute(FOCUS_ITEM);
+                                if (getAccessible(item) == peer) {
+                                    focus = true;
+                                }
                             }
                         }
                     }
@@ -734,13 +739,14 @@
     }
 
     long get_FragmentRoot() {
-        if (isDisposed()) return 0;
+        if (isDisposed()) return 0L;
         Scene scene = (Scene)getAttribute(SCENE);
-        if (scene != null) {
-            Accessible acc = scene.getAccessible();
-            return ((WinAccessible)acc.impl_getDelegate()).getNativeAccessible();
-        }
-        return 0L;
+        if (scene == null) return 0L;
+        Accessible acc = scene.getAccessible();
+        if (acc == null) return 0L;
+        WinAccessible winAcc = (WinAccessible)acc.impl_getDelegate();
+        if (winAcc == null || winAcc.isDisposed()) return 0L;
+        return winAcc.getNativeAccessible();
     }
 
     long[] GetEmbeddedFragmentRoots() {
@@ -782,11 +788,12 @@
                     if (node == null) {
                         /* scene root node case */
                         Scene scene = (Scene)getAttribute(SCENE);
-                        if (scene != null) {
-                            Accessible acc = scene.getAccessible();
-                            WinAccessible winAcc = (WinAccessible)acc.impl_getDelegate();
-                            return winAcc.getNativeAccessible();
-                        }
+                        if (scene == null) return 0L;
+                        Accessible acc = scene.getAccessible();
+                        if (acc == null) return 0L;
+                        WinAccessible winAcc = (WinAccessible)acc.impl_getDelegate();
+                        if (winAcc == null || winAcc.isDisposed()) return 0L;
+                        return winAcc.getNativeAccessible();
                     }
                 }
                 break;
--- a/modules/graphics/src/main/java/javafx/scene/Node.java	Thu Mar 27 16:31:52 2014 -0400
+++ b/modules/graphics/src/main/java/javafx/scene/Node.java	Thu Mar 27 15:09:45 2014 -0700
@@ -9203,5 +9203,14 @@
         }
         return accessible;
     }
+
+    void releaseAccessible() {
+        Accessible acc = this.accessible;
+        if (acc != null) {
+            accessible = null;
+            acc.dispose();
+        }
+    }
+
 }
 
--- a/modules/graphics/src/main/java/javafx/scene/Parent.java	Thu Mar 27 16:31:52 2014 -0400
+++ b/modules/graphics/src/main/java/javafx/scene/Parent.java	Thu Mar 27 15:09:45 2014 -0700
@@ -1786,4 +1786,13 @@
             default: return super.accGetAttribute(attribute, parameters);
         }
     }
+
+    void releaseAccessible() {
+        super.releaseAccessible();
+        for (int i=0, max=children.size(); i<max; i++) {
+            final Node node = children.get(i);
+            node.releaseAccessible();
+        }
+    }
+
 }
--- a/modules/graphics/src/main/java/javafx/scene/Scene.java	Thu Mar 27 16:31:52 2014 -0400
+++ b/modules/graphics/src/main/java/javafx/scene/Scene.java	Thu Mar 27 15:09:45 2014 -0700
@@ -713,6 +713,9 @@
         if (accessible != null) {
             accessible.dispose();
             accessible = null;
+            disposeAccessibles();
+            Node root = getRoot();
+            if (root != null) root.releaseAccessible();
         }
 
         PerformanceTracker.logEvent("Scene.disposePeer finished");
@@ -6152,6 +6155,15 @@
      * @treatAsPrivate
      */
     public Accessible getAccessible() {
+        /*
+         * The accessible for the Scene should never be
+         * requested when the peer is not set.
+         * This can only happen in a error case where a
+         * descender of this Scene was not disposed and 
+         * it still being used by the AT client and trying
+         * to reach to the top level window.
+         */
+        if (impl_peer == null) return null;
         if (accessible == null) {
             accessible = new Accessible() {
                 @Override public Object getAttribute(Attribute attribute,
--- a/modules/graphics/src/main/java/javafx/scene/accessibility/Accessible.java	Thu Mar 27 16:31:52 2014 -0400
+++ b/modules/graphics/src/main/java/javafx/scene/accessibility/Accessible.java	Thu Mar 27 15:09:45 2014 -0700
@@ -88,6 +88,8 @@
      * @param notification the attribute which value has changed
      */
     public void sendNotification(Attribute notification) {
-        delegate.sendNotification(notification);
+        if (delegate != null) {
+            delegate.sendNotification(notification);
+        }
     }
 }