8298644: JNI call of getCurrentComponent on a wrong thread

Reviewed-by: avu, serb, kizune
This commit is contained in:
Artem Semenov 2023-01-13 19:39:56 +00:00
parent 500b45e12d
commit 8cb25d3de4
4 changed files with 67 additions and 22 deletions
src/java.desktop
macosx
classes/sun/lwawt/macosx
native/libawt_lwawt/awt/a11y
share/classes
javax/swing
sun/swing

@ -42,7 +42,6 @@ import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.Arrays;
import java.util.function.Function;
import javax.accessibility.Accessible;
import javax.accessibility.AccessibleAction;
@ -67,6 +66,7 @@ import javax.swing.KeyStroke;
import sun.awt.AWTAccessor;
import sun.lwawt.LWWindowPeer;
import sun.swing.SwingAccessor;
class CAccessibility implements PropertyChangeListener {
private static Set<String> ignoredRoles;
@ -824,6 +824,18 @@ class CAccessibility implements PropertyChangeListener {
}, c);
}
// This method is called from the native in OutlineRowAccessibility.m
private static Accessible getAccessibleCurrentAccessible(Accessible a, Component c) {
if (a == null) return null;
return invokeAndWait(() -> {
AccessibleContext ac = a.getAccessibleContext();
if (ac != null) {
return SwingAccessor.getAccessibleComponentAccessor().getCurrentAccessible(ac);
}
return null;
}, c);
}
// This method is called from the native in ComboBoxAccessibility.m
private static Accessible getAccessibleComboboxValue(Accessible a, Component c) {
if (a == null) return null;

@ -32,9 +32,7 @@
#import "OutlineAccessibility.h"
#import "sun_lwawt_macosx_CAccessibility.h"
static jclass sjc_CAccessible = NULL;
#define GET_CACCESSIBLE_CLASS_RETURN(ret) \
GET_CLASS_RETURN(sjc_CAccessible, "sun/lwawt/macosx/CAccessible", ret);
static jclass sjc_CAccessibility = NULL;
@implementation OutlineRowAccessibility
@ -42,23 +40,11 @@ static jclass sjc_CAccessible = NULL;
- (jobject)currentAccessibleWithENV:(JNIEnv *)env
{
jobject jAxContext = getAxContext(env, fAccessible, fComponent);
if (jAxContext == NULL) return NULL;
jclass axContextClass = (*env)->GetObjectClass(env, jAxContext);
DECLARE_METHOD_RETURN(jm_getCurrentComponent, axContextClass, "getCurrentComponent", "()Ljava/awt/Component;", NULL);
jobject newComponent = (*env)->CallObjectMethod(env, jAxContext, jm_getCurrentComponent);
GET_CACCESSIBILITY_CLASS_RETURN(NULL);
DECLARE_STATIC_METHOD_RETURN(sjm_getAccessibleCurrentAccessible, sjc_CAccessibility, "getAccessibleCurrentAccessible", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljavax/accessibility/Accessible;", NULL);
jobject currentAccessible = (*env)->CallStaticObjectMethod(env, sjc_CAccessibility, sjm_getAccessibleCurrentAccessible, fAccessible, fComponent);
CHECK_EXCEPTION();
(*env)->DeleteLocalRef(env, jAxContext);
if (newComponent != NULL) {
GET_CACCESSIBLE_CLASS_RETURN(NULL);
DECLARE_STATIC_METHOD_RETURN(sjm_getCAccessible, sjc_CAccessible, "getCAccessible", "(Ljavax/accessibility/Accessible;)Lsun/lwawt/macosx/CAccessible;", NULL);
jobject currentAccessible = (*env)->CallStaticObjectMethod(env, sjc_CAccessible, sjm_getCAccessible, newComponent);
CHECK_EXCEPTION();
(*env)->DeleteLocalRef(env, newComponent);
return currentAccessible;
} else {
return NULL;
}
return currentAccessible;
}
// NSAccessibilityElement protocol methods

@ -92,6 +92,7 @@ import javax.swing.tree.TreeSelectionModel;
import sun.awt.AWTAccessor;
import sun.awt.AWTAccessor.MouseEventAccessor;
import sun.swing.SwingAccessor;
import sun.swing.SwingUtilities2;
import sun.swing.SwingUtilities2.Section;
@ -4740,6 +4741,26 @@ public class JTree extends JComponent implements Scrollable, Accessible
implements Accessible, AccessibleComponent, AccessibleSelection,
AccessibleAction {
static {
SwingAccessor.setAccessibleComponentAccessor(new AccessibleJTreeNodeAccessor());
}
private static class AccessibleJTreeNodeAccessor implements SwingAccessor.AccessibleComponentAccessor {
private AccessibleJTreeNodeAccessor() {}
@Override
public Accessible getCurrentAccessible(AccessibleContext ac) {
if (ac instanceof AccessibleJTreeNode) {
Component c = ((AccessibleJTreeNode) ac).getCurrentComponent();
if (c instanceof Accessible) {
return (Accessible)c;
}
}
return null;
}
}
private JTree tree = null;
private TreeModel treeModel = null;
private Object obj = null;

@ -25,10 +25,13 @@
package sun.swing;
import java.awt.*;
import java.awt.Component;
import java.awt.Point;
import java.lang.invoke.MethodHandles;
import javax.swing.*;
import javax.accessibility.Accessible;
import javax.accessibility.AccessibleContext;
import javax.swing.*;
import javax.swing.text.JTextComponent;
/**
@ -47,6 +50,14 @@ public final class SwingAccessor {
private SwingAccessor() {
}
/**
* This interface provides access to the renderer's accessibility component.
* For example, the renderer of a list element, a table cell, or a tree node
*/
public interface AccessibleComponentAccessor {
Accessible getCurrentAccessible(AccessibleContext ac);
}
/**
* An accessor for the JComponent class.
*/
@ -290,6 +301,21 @@ public final class SwingAccessor {
SwingAccessor.keyStrokeAccessor = accessor;
}
private static AccessibleComponentAccessor accessibleComponentAccessor = null;
public static AccessibleComponentAccessor getAccessibleComponentAccessor() {
var access = accessibleComponentAccessor;
if (access == null) {
ensureClassInitialized(JTree.class);
access = accessibleComponentAccessor;
}
return access;
}
public static void setAccessibleComponentAccessor(final AccessibleComponentAccessor accessibleAccessor) {
accessibleComponentAccessor = accessibleAccessor;
}
private static void ensureClassInitialized(Class<?> c) {
try {
MethodHandles.lookup().ensureInitialized(c);