8145984: [macosx] sun.lwawt.macosx.CAccessible leaks

Reviewed-by: serb, ptbrunet
This commit is contained in:
Anton Tarasov 2016-05-04 16:41:07 +03:00
parent 191e61e184
commit 6191c997a3
10 changed files with 296 additions and 88 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -25,12 +25,15 @@
package sun.lwawt.macosx; package sun.lwawt.macosx;
import sun.lwawt.LWWindowPeer;
import java.awt.*; import java.awt.*;
import java.beans.*; import java.beans.*;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.util.*; import java.util.*;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
import sun.awt.AWTAccessor;
import javax.accessibility.*; import javax.accessibility.*;
import javax.swing.*; import javax.swing.*;
@ -421,6 +424,8 @@ class CAccessibility implements PropertyChangeListener {
} }
public static AccessibleAction getAccessibleAction(final Accessible a, final Component c) { public static AccessibleAction getAccessibleAction(final Accessible a, final Component c) {
if (a == null) return null;
return invokeAndWait(new Callable<AccessibleAction>() { return invokeAndWait(new Callable<AccessibleAction>() {
public AccessibleAction call() throws Exception { public AccessibleAction call() throws Exception {
final AccessibleContext ac = a.getAccessibleContext(); final AccessibleContext ac = a.getAccessibleContext();
@ -667,4 +672,28 @@ class CAccessibility implements PropertyChangeListener {
} }
}, c); }, c);
} }
/**
* @return AWTView ptr, a peer of the CPlatformView associated with the toplevel container of the Accessible, if any
*/
private static long getAWTView(Accessible a) {
Accessible ax = CAccessible.getSwingAccessible(a);
if (!(ax instanceof Component)) return 0;
return invokeAndWait(new Callable<Long>() {
public Long call() throws Exception {
Component cont = (Component) ax;
while (cont != null && !(cont instanceof Window)) {
cont = cont.getParent();
}
if (cont != null) {
LWWindowPeer peer = (LWWindowPeer) AWTAccessor.getComponentAccessor().getPeer(cont);
if (peer != null) {
return ((CPlatformWindow) peer.getPlatformWindow()).getContentView().getAWTView();
}
}
return 0L;
}
}, (Component)ax);
}
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -264,6 +264,8 @@ class CAccessibleText {
final double localY = boundsUnion.getY(); final double localY = boundsUnion.getY();
final Point componentLocation = ac.getAccessibleComponent().getLocationOnScreen(); final Point componentLocation = ac.getAccessibleComponent().getLocationOnScreen();
if (componentLocation == null) return ret;
final double screenX = componentLocation.getX() + localX; final double screenX = componentLocation.getX() + localX;
final double screenY = componentLocation.getY() + localY; final double screenY = componentLocation.getY() + localY;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -62,6 +62,8 @@
- (void) deliverJavaMouseEvent: (NSEvent *) event; - (void) deliverJavaMouseEvent: (NSEvent *) event;
- (jobject) awtComponent:(JNIEnv *)env; - (jobject) awtComponent:(JNIEnv *)env;
+ (AWTView *) awtView:(JNIEnv *)env ofAccessible:(jobject)jaccessible;
// Input method-related events // Input method-related events
- (void)setInputMethod:(jobject)inputMethod; - (void)setInputMethod:(jobject)inputMethod;
- (void)abandonInput; - (void)abandonInput;

View File

@ -29,6 +29,7 @@
#import "AWTWindow.h" #import "AWTWindow.h"
#import "JavaComponentAccessibility.h" #import "JavaComponentAccessibility.h"
#import "JavaTextAccessibility.h" #import "JavaTextAccessibility.h"
#import "JavaAccessibilityUtilities.h"
#import "GeomUtilities.h" #import "GeomUtilities.h"
#import "OSVersion.h" #import "OSVersion.h"
#import "ThreadUtilities.h" #import "ThreadUtilities.h"
@ -129,7 +130,7 @@ static BOOL shouldUsePressAndHold() {
self.cglLayer = nil; self.cglLayer = nil;
JNIEnv *env = [ThreadUtilities getJNIEnvUncached]; JNIEnv *env = [ThreadUtilities getJNIEnvUncached];
(*env)->DeleteGlobalRef(env, m_cPlatformView); (*env)->DeleteWeakGlobalRef(env, m_cPlatformView);
m_cPlatformView = NULL; m_cPlatformView = NULL;
if (fInputMethodLOCKABLE != NULL) if (fInputMethodLOCKABLE != NULL)
@ -396,7 +397,11 @@ static BOOL shouldUsePressAndHold() {
static JNF_CLASS_CACHE(jc_PlatformView, "sun/lwawt/macosx/CPlatformView"); static JNF_CLASS_CACHE(jc_PlatformView, "sun/lwawt/macosx/CPlatformView");
static JNF_MEMBER_CACHE(jm_deliverMouseEvent, jc_PlatformView, "deliverMouseEvent", "(Lsun/lwawt/macosx/NSEvent;)V"); static JNF_MEMBER_CACHE(jm_deliverMouseEvent, jc_PlatformView, "deliverMouseEvent", "(Lsun/lwawt/macosx/NSEvent;)V");
JNFCallVoidMethod(env, m_cPlatformView, jm_deliverMouseEvent, jEvent); jobject jlocal = (*env)->NewLocalRef(env, m_cPlatformView);
if (!(*env)->IsSameObject(env, jlocal, NULL)) {
JNFCallVoidMethod(env, jlocal, jm_deliverMouseEvent, jEvent);
(*env)->DeleteLocalRef(env, jlocal);
}
(*env)->DeleteLocalRef(env, jEvent); (*env)->DeleteLocalRef(env, jEvent);
} }
@ -459,8 +464,11 @@ static BOOL shouldUsePressAndHold() {
static JNF_CLASS_CACHE(jc_PlatformView, "sun/lwawt/macosx/CPlatformView"); static JNF_CLASS_CACHE(jc_PlatformView, "sun/lwawt/macosx/CPlatformView");
static JNF_MEMBER_CACHE(jm_deliverKeyEvent, jc_PlatformView, static JNF_MEMBER_CACHE(jm_deliverKeyEvent, jc_PlatformView,
"deliverKeyEvent", "(Lsun/lwawt/macosx/NSEvent;)V"); "deliverKeyEvent", "(Lsun/lwawt/macosx/NSEvent;)V");
JNFCallVoidMethod(env, m_cPlatformView, jm_deliverKeyEvent, jEvent); jobject jlocal = (*env)->NewLocalRef(env, m_cPlatformView);
if (!(*env)->IsSameObject(env, jlocal, NULL)) {
JNFCallVoidMethod(env, jlocal, jm_deliverKeyEvent, jEvent);
(*env)->DeleteLocalRef(env, jlocal);
}
if (characters != NULL) { if (characters != NULL) {
(*env)->DeleteLocalRef(env, characters); (*env)->DeleteLocalRef(env, characters);
} }
@ -475,7 +483,12 @@ static BOOL shouldUsePressAndHold() {
JNIEnv *env = [ThreadUtilities getJNIEnv]; JNIEnv *env = [ThreadUtilities getJNIEnv];
static JNF_CLASS_CACHE(jc_PlatformView, "sun/lwawt/macosx/CPlatformView"); static JNF_CLASS_CACHE(jc_PlatformView, "sun/lwawt/macosx/CPlatformView");
static JNF_MEMBER_CACHE(jm_deliverResize, jc_PlatformView, "deliverResize", "(IIII)V"); static JNF_MEMBER_CACHE(jm_deliverResize, jc_PlatformView, "deliverResize", "(IIII)V");
JNFCallVoidMethod(env, m_cPlatformView, jm_deliverResize, x,y,w,h);
jobject jlocal = (*env)->NewLocalRef(env, m_cPlatformView);
if (!(*env)->IsSameObject(env, jlocal, NULL)) {
JNFCallVoidMethod(env, jlocal, jm_deliverResize, x,y,w,h);
(*env)->DeleteLocalRef(env, jlocal);
}
} }
@ -504,7 +517,11 @@ static BOOL shouldUsePressAndHold() {
*/ */
static JNF_CLASS_CACHE(jc_CPlatformView, "sun/lwawt/macosx/CPlatformView"); static JNF_CLASS_CACHE(jc_CPlatformView, "sun/lwawt/macosx/CPlatformView");
static JNF_MEMBER_CACHE(jm_deliverWindowDidExposeEvent, jc_CPlatformView, "deliverWindowDidExposeEvent", "()V"); static JNF_MEMBER_CACHE(jm_deliverWindowDidExposeEvent, jc_CPlatformView, "deliverWindowDidExposeEvent", "()V");
JNFCallVoidMethod(env, m_cPlatformView, jm_deliverWindowDidExposeEvent); jobject jlocal = (*env)->NewLocalRef(env, m_cPlatformView);
if (!(*env)->IsSameObject(env, jlocal, NULL)) {
JNFCallVoidMethod(env, jlocal, jm_deliverWindowDidExposeEvent);
(*env)->DeleteLocalRef(env, jlocal);
}
/* /*
} }
*/ */
@ -541,7 +558,13 @@ static BOOL shouldUsePressAndHold() {
} }
return NULL; return NULL;
} }
jobject peer = JNFGetObjectField(env, m_cPlatformView, jf_Peer);
jobject peer = NULL;
jobject jlocal = (*env)->NewLocalRef(env, m_cPlatformView);
if (!(*env)->IsSameObject(env, jlocal, NULL)) {
peer = JNFGetObjectField(env, jlocal, jf_Peer);
(*env)->DeleteLocalRef(env, jlocal);
}
static JNF_CLASS_CACHE(jc_LWWindowPeer, "sun/lwawt/LWWindowPeer"); static JNF_CLASS_CACHE(jc_LWWindowPeer, "sun/lwawt/LWWindowPeer");
static JNF_MEMBER_CACHE(jf_Target, jc_LWWindowPeer, "target", "Ljava/awt/Component;"); static JNF_MEMBER_CACHE(jf_Target, jc_LWWindowPeer, "target", "Ljava/awt/Component;");
if (peer == NULL) { if (peer == NULL) {
@ -549,12 +572,27 @@ static BOOL shouldUsePressAndHold() {
JNFDumpJavaStack(env); JNFDumpJavaStack(env);
return NULL; return NULL;
} }
return JNFGetObjectField(env, peer, jf_Target); jobject comp = JNFGetObjectField(env, peer, jf_Target);
(*env)->DeleteLocalRef(env, peer);
return comp;
}
+ (AWTView *) awtView:(JNIEnv*)env ofAccessible:(jobject)jaccessible
{
static JNF_STATIC_MEMBER_CACHE(jm_getAWTView, sjc_CAccessibility, "getAWTView", "(Ljavax/accessibility/Accessible;)J");
jlong jptr = JNFCallStaticLongMethod(env, jm_getAWTView, jaccessible);
if (jptr == 0) return nil;
return (AWTView *)jlong_to_ptr(jptr);
} }
- (id)getAxData:(JNIEnv*)env - (id)getAxData:(JNIEnv*)env
{ {
return [[[JavaComponentAccessibility alloc] initWithParent:self withEnv:env withAccessible:[self awtComponent:env] withIndex:-1 withView:self withJavaRole:nil] autorelease]; jobject jcomponent = [self awtComponent:env];
id ax = [[[JavaComponentAccessibility alloc] initWithParent:self withEnv:env withAccessible:jcomponent withIndex:-1 withView:self withJavaRole:nil] autorelease];
(*env)->DeleteLocalRef(env, jcomponent);
return ax;
} }
- (NSArray *)accessibilityAttributeNames - (NSArray *)accessibilityAttributeNames
@ -1299,7 +1337,7 @@ Java_sun_lwawt_macosx_CPlatformView_nativeCreateView
JNF_COCOA_ENTER(env); JNF_COCOA_ENTER(env);
NSRect rect = NSMakeRect(originX, originY, width, height); NSRect rect = NSMakeRect(originX, originY, width, height);
jobject cPlatformView = (*env)->NewGlobalRef(env, obj); jobject cPlatformView = (*env)->NewWeakGlobalRef(env, obj);
[ThreadUtilities performOnMainThreadWaiting:YES block:^(){ [ThreadUtilities performOnMainThreadWaiting:YES block:^(){

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -35,9 +35,9 @@
{ {
self = [super init]; self = [super init];
if (self) { if (self) {
fAccessibleAction = JNFNewGlobalRef(env, accessibleAction); fAccessibleAction = JNFNewWeakGlobalRef(env, accessibleAction);
fIndex = index; fIndex = index;
fComponent = JNFNewGlobalRef(env, component); fComponent = JNFNewWeakGlobalRef(env, component);
} }
return self; return self;
} }
@ -46,10 +46,10 @@
{ {
JNIEnv *env = [ThreadUtilities getJNIEnvUncached]; JNIEnv *env = [ThreadUtilities getJNIEnvUncached];
JNFDeleteGlobalRef(env, fAccessibleAction); JNFDeleteWeakGlobalRef(env, fAccessibleAction);
fAccessibleAction = NULL; fAccessibleAction = NULL;
JNFDeleteGlobalRef(env, fComponent); JNFDeleteWeakGlobalRef(env, fComponent);
fComponent = NULL; fComponent = NULL;
[super dealloc]; [super dealloc];
@ -61,7 +61,18 @@
JNIEnv* env = [ThreadUtilities getJNIEnv]; JNIEnv* env = [ThreadUtilities getJNIEnv];
return JNFJavaToNSString(env, JNFCallStaticObjectMethod(env, jm_getAccessibleActionDescription, fAccessibleAction, fIndex, fComponent)); // AWT_THREADING Safe (AWTRunLoopMode) jobject fCompLocal = (*env)->NewLocalRef(env, fComponent);
if ((*env)->IsSameObject(env, fCompLocal, NULL)) {
return @"unknown";
}
NSString *str = nil;
jobject jstr = JNFCallStaticObjectMethod(env, jm_getAccessibleActionDescription, fAccessibleAction, fIndex, fCompLocal);
if (jstr != NULL) {
NSString *str = JNFJavaToNSString(env, jstr); // AWT_THREADING Safe (AWTRunLoopMode)
(*env)->DeleteLocalRef(env, jstr);
}
(*env)->DeleteLocalRef(env, fCompLocal);
return str == nil ? @"unknown" : str;
} }
- (void)perform - (void)perform
@ -82,9 +93,9 @@
{ {
self = [super init]; self = [super init];
if (self) { if (self) {
fTabGroup = JNFNewGlobalRef(env, tabGroup); fTabGroup = JNFNewWeakGlobalRef(env, tabGroup);
fIndex = index; fIndex = index;
fComponent = JNFNewGlobalRef(env, component); fComponent = JNFNewWeakGlobalRef(env, component);
} }
return self; return self;
} }
@ -93,10 +104,10 @@
{ {
JNIEnv *env = [ThreadUtilities getJNIEnvUncached]; JNIEnv *env = [ThreadUtilities getJNIEnvUncached];
JNFDeleteGlobalRef(env, fTabGroup); JNFDeleteWeakGlobalRef(env, fTabGroup);
fTabGroup = NULL; fTabGroup = NULL;
JNFDeleteGlobalRef(env, fComponent); JNFDeleteWeakGlobalRef(env, fComponent);
fComponent = NULL; fComponent = NULL;
[super dealloc]; [super dealloc];

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -77,7 +77,9 @@ NSString *getJavaRole(JNIEnv *env, jobject axComponent, jobject component)
jobject axRole = JNFCallStaticObjectMethod(env, sjm_getAccessibleRole, axComponent, component); // AWT_THREADING Safe (AWTRunLoopMode) jobject axRole = JNFCallStaticObjectMethod(env, sjm_getAccessibleRole, axComponent, component); // AWT_THREADING Safe (AWTRunLoopMode)
if (axRole == NULL) return @"unknown"; if (axRole == NULL) return @"unknown";
return JNFJavaToNSString(env, axRole); NSString* str = JNFJavaToNSString(env, axRole);
(*env)->DeleteLocalRef(env, axRole);
return str;
} }
jobject getAxSelection(JNIEnv *env, jobject axContext, jobject component) jobject getAxSelection(JNIEnv *env, jobject axContext, jobject component)
@ -126,21 +128,27 @@ BOOL isVertical(JNIEnv *env, jobject axContext, jobject component)
{ {
static JNF_STATIC_MEMBER_CACHE(jm_VERTICAL, sjc_AccessibleState, "VERTICAL", "Ljavax/accessibility/AccessibleState;"); static JNF_STATIC_MEMBER_CACHE(jm_VERTICAL, sjc_AccessibleState, "VERTICAL", "Ljavax/accessibility/AccessibleState;");
jobject axVertState = JNFGetStaticObjectField(env, jm_VERTICAL); jobject axVertState = JNFGetStaticObjectField(env, jm_VERTICAL);
return containsAxState(env, axContext, axVertState, component); BOOL vertical = containsAxState(env, axContext, axVertState, component);
(*env)->DeleteLocalRef(env, axVertState);
return vertical;
} }
BOOL isHorizontal(JNIEnv *env, jobject axContext, jobject component) BOOL isHorizontal(JNIEnv *env, jobject axContext, jobject component)
{ {
static JNF_STATIC_MEMBER_CACHE(jm_HORIZONTAL, sjc_AccessibleState, "HORIZONTAL", "Ljavax/accessibility/AccessibleState;"); static JNF_STATIC_MEMBER_CACHE(jm_HORIZONTAL, sjc_AccessibleState, "HORIZONTAL", "Ljavax/accessibility/AccessibleState;");
jobject axHorizState = JNFGetStaticObjectField(env, jm_HORIZONTAL); jobject axHorizState = JNFGetStaticObjectField(env, jm_HORIZONTAL);
return containsAxState(env, axContext, axHorizState, component); BOOL horizontal = containsAxState(env, axContext, axHorizState, component);
(*env)->DeleteLocalRef(env, axHorizState);
return horizontal;
} }
BOOL isShowing(JNIEnv *env, jobject axContext, jobject component) BOOL isShowing(JNIEnv *env, jobject axContext, jobject component)
{ {
static JNF_STATIC_MEMBER_CACHE(jm_SHOWING, sjc_AccessibleState, "SHOWING", "Ljavax/accessibility/AccessibleState;"); static JNF_STATIC_MEMBER_CACHE(jm_SHOWING, sjc_AccessibleState, "SHOWING", "Ljavax/accessibility/AccessibleState;");
jobject axVisibleState = JNFGetStaticObjectField(env, jm_SHOWING); jobject axVisibleState = JNFGetStaticObjectField(env, jm_SHOWING);
return containsAxState(env, axContext, axVisibleState, component); BOOL showing = containsAxState(env, axContext, axVisibleState, component);
(*env)->DeleteLocalRef(env, axVisibleState);
return showing;
} }
NSPoint getAxComponentLocationOnScreen(JNIEnv *env, jobject axComponent, jobject component) NSPoint getAxComponentLocationOnScreen(JNIEnv *env, jobject axComponent, jobject component)

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -75,7 +75,6 @@ static jobject sAccessibilityClass = NULL;
static NSMutableDictionary *sAttributeNamesForRoleCache = nil; static NSMutableDictionary *sAttributeNamesForRoleCache = nil;
static NSObject *sAttributeNamesLOCK = nil; static NSObject *sAttributeNamesLOCK = nil;
@interface TabGroupAccessibility : JavaComponentAccessibility { @interface TabGroupAccessibility : JavaComponentAccessibility {
NSInteger _numTabs; NSInteger _numTabs;
} }
@ -137,8 +136,11 @@ static NSObject *sAttributeNamesLOCK = nil;
fView = [view retain]; fView = [view retain];
fJavaRole = [javaRole retain]; fJavaRole = [javaRole retain];
fAccessible = JNFNewGlobalRef(env, accessible); fAccessible = (*env)->NewWeakGlobalRef(env, accessible);
fComponent = JNFNewGlobalRef(env, [(AWTView *)fView awtComponent:env]);
jobject jcomponent = [(AWTView *)fView awtComponent:env];
fComponent = (*env)->NewWeakGlobalRef(env, jcomponent);
(*env)->DeleteLocalRef(env, jcomponent);
fIndex = index; fIndex = index;
@ -166,10 +168,10 @@ static NSObject *sAttributeNamesLOCK = nil;
JNIEnv *env = [ThreadUtilities getJNIEnvUncached]; JNIEnv *env = [ThreadUtilities getJNIEnvUncached];
JNFDeleteGlobalRef(env, fAccessible); (*env)->DeleteWeakGlobalRef(env, fAccessible);
fAccessible = NULL; fAccessible = NULL;
JNFDeleteGlobalRef(env, fComponent); (*env)->DeleteWeakGlobalRef(env, fComponent);
fComponent = NULL; fComponent = NULL;
[fParent release]; [fParent release];
@ -279,7 +281,7 @@ static NSObject *sAttributeNamesLOCK = nil;
+ (NSArray *)childrenOfParent:(JavaComponentAccessibility *)parent withEnv:(JNIEnv *)env withChildrenCode:(NSInteger)whichChildren allowIgnored:(BOOL)allowIgnored + (NSArray *)childrenOfParent:(JavaComponentAccessibility *)parent withEnv:(JNIEnv *)env withChildrenCode:(NSInteger)whichChildren allowIgnored:(BOOL)allowIgnored
{ {
jobjectArray jchildrenAndRoles = JNFCallStaticObjectMethod(env, jm_getChildrenAndRoles, parent->fAccessible, parent->fComponent, whichChildren, allowIgnored); // AWT_THREADING Safe (AWTRunLoop) jobjectArray jchildrenAndRoles = (jobjectArray)JNFCallStaticObjectMethod(env, jm_getChildrenAndRoles, parent->fAccessible, parent->fComponent, whichChildren, allowIgnored); // AWT_THREADING Safe (AWTRunLoop)
if (jchildrenAndRoles == NULL) return nil; if (jchildrenAndRoles == NULL) return nil;
jsize arrayLen = (*env)->GetArrayLength(env, jchildrenAndRoles); jsize arrayLen = (*env)->GetArrayLength(env, jchildrenAndRoles);
@ -294,14 +296,21 @@ static NSObject *sAttributeNamesLOCK = nil;
NSString *childJavaRole = nil; NSString *childJavaRole = nil;
if (jchildJavaRole != NULL) { if (jchildJavaRole != NULL) {
childJavaRole = JNFJavaToNSString(env, JNFGetObjectField(env, jchildJavaRole, sjf_key)); jobject jkey = JNFGetObjectField(env, jchildJavaRole, sjf_key);
childJavaRole = JNFJavaToNSString(env, jkey);
(*env)->DeleteLocalRef(env, jkey);
} }
JavaComponentAccessibility *child = [self createWithParent:parent accessible:jchild role:childJavaRole index:childIndex withEnv:env withView:parent->fView]; JavaComponentAccessibility *child = [self createWithParent:parent accessible:jchild role:childJavaRole index:childIndex withEnv:env withView:parent->fView];
(*env)->DeleteLocalRef(env, jchild);
(*env)->DeleteLocalRef(env, jchildJavaRole);
[children addObject:child]; [children addObject:child];
childIndex++; childIndex++;
} }
(*env)->DeleteLocalRef(env, jchildrenAndRoles);
return children; return children;
} }
@ -310,7 +319,7 @@ static NSObject *sAttributeNamesLOCK = nil;
jobject jcomponent = [(AWTView *)view awtComponent:env]; jobject jcomponent = [(AWTView *)view awtComponent:env];
jint index = JNFCallStaticIntMethod(env, sjm_getAccessibleIndexInParent, jaccessible, jcomponent); jint index = JNFCallStaticIntMethod(env, sjm_getAccessibleIndexInParent, jaccessible, jcomponent);
NSString *javaRole = getJavaRole(env, jaccessible, jcomponent); NSString *javaRole = getJavaRole(env, jaccessible, jcomponent);
(*env)->DeleteLocalRef(env, jcomponent);
return [self createWithAccessible:jaccessible role:javaRole index:index withEnv:env withView:view]; return [self createWithAccessible:jaccessible role:javaRole index:index withEnv:env withView:view];
} }
@ -325,7 +334,10 @@ static NSObject *sAttributeNamesLOCK = nil;
jobject jCAX = [JavaComponentAccessibility getCAccessible:jaccessible withEnv:env]; jobject jCAX = [JavaComponentAccessibility getCAccessible:jaccessible withEnv:env];
if (jCAX == NULL) return nil; if (jCAX == NULL) return nil;
JavaComponentAccessibility *value = (JavaComponentAccessibility *) jlong_to_ptr(JNFGetLongField(env, jCAX, jf_ptr)); JavaComponentAccessibility *value = (JavaComponentAccessibility *) jlong_to_ptr(JNFGetLongField(env, jCAX, jf_ptr));
if (value != nil) return [[value retain] autorelease]; if (value != nil) {
(*env)->DeleteLocalRef(env, jCAX);
return [[value retain] autorelease];
}
// otherwise, create a new instance // otherwise, create a new instance
JavaComponentAccessibility *newChild = nil; JavaComponentAccessibility *newChild = nil;
@ -348,6 +360,7 @@ static NSObject *sAttributeNamesLOCK = nil;
// must hard retain pointer poked into Java object // must hard retain pointer poked into Java object
[newChild retain]; [newChild retain];
JNFSetLongField(env, jCAX, jf_ptr, ptr_to_jlong(newChild)); JNFSetLongField(env, jCAX, jf_ptr, ptr_to_jlong(newChild));
(*env)->DeleteLocalRef(env, jCAX);
// return autoreleased instance // return autoreleased instance
return [newChild autorelease]; return [newChild autorelease];
@ -380,7 +393,7 @@ static NSObject *sAttributeNamesLOCK = nil;
// Get all the other accessibility attributes states we need in one swell foop. // Get all the other accessibility attributes states we need in one swell foop.
// javaRole isn't pulled in because we need protected access to AccessibleRole.key // javaRole isn't pulled in because we need protected access to AccessibleRole.key
jbooleanArray attributeStates = JNFCallStaticObjectMethod(env, jm_getInitialAttributeStates, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop) jbooleanArray attributeStates = (jbooleanArray)JNFCallStaticObjectMethod(env, jm_getInitialAttributeStates, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
if (attributeStates == NULL) return nil; if (attributeStates == NULL) return nil;
jboolean *attributeStatesArray = (*env)->GetBooleanArrayElements(env, attributeStates, 0); jboolean *attributeStatesArray = (*env)->GetBooleanArrayElements(env, attributeStates, 0);
if (attributeStatesArray == NULL) { if (attributeStatesArray == NULL) {
@ -475,6 +488,7 @@ static NSObject *sAttributeNamesLOCK = nil;
JavaAxAction *action = [[JavaAxAction alloc] initWithEnv:env withAccessibleAction:axAction withIndex:0 withComponent:fComponent]; JavaAxAction *action = [[JavaAxAction alloc] initWithEnv:env withAccessibleAction:axAction withIndex:0 withComponent:fComponent];
[fActions setObject:action forKey:[self isMenu] ? NSAccessibilityPickAction : NSAccessibilityPressAction]; [fActions setObject:action forKey:[self isMenu] ? NSAccessibilityPickAction : NSAccessibilityPressAction];
[action release]; [action release];
(*env)->DeleteLocalRef(env, axAction);
} }
} }
@ -485,7 +499,9 @@ static NSObject *sAttributeNamesLOCK = nil;
- (id)parent - (id)parent
{ {
static JNF_CLASS_CACHE(sjc_Window, "java/awt/Window");
static JNF_STATIC_MEMBER_CACHE(sjm_getAccessibleParent, sjc_CAccessibility, "getAccessibleParent", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljavax/accessibility/Accessible;"); static JNF_STATIC_MEMBER_CACHE(sjm_getAccessibleParent, sjc_CAccessibility, "getAccessibleParent", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljavax/accessibility/Accessible;");
static JNF_STATIC_MEMBER_CACHE(sjm_getSwingAccessible, sjc_CAccessible, "getSwingAccessible", "(Ljavax/accessibility/Accessible;)Ljavax/accessibility/Accessible;");
if(fParent == nil) { if(fParent == nil) {
JNIEnv* env = [ThreadUtilities getJNIEnv]; JNIEnv* env = [ThreadUtilities getJNIEnv];
@ -495,10 +511,21 @@ static NSObject *sAttributeNamesLOCK = nil;
if (jparent == NULL) { if (jparent == NULL) {
fParent = fView; fParent = fView;
} else { } else {
fParent = [JavaComponentAccessibility createWithAccessible:jparent withEnv:env withView:fView]; AWTView *view = fView;
jobject jax = JNFCallStaticObjectMethod(env, sjm_getSwingAccessible, fAccessible);
if (JNFIsInstanceOf(env, jax, &sjc_Window)) {
// In this case jparent is an owner toplevel and we should retrieve its own view
view = [AWTView awtView:env ofAccessible:jparent];
}
if (view != nil) {
fParent = [JavaComponentAccessibility createWithAccessible:jparent withEnv:env withView:view];
}
if (fParent == nil) { if (fParent == nil) {
fParent = fView; fParent = fView;
} }
(*env)->DeleteLocalRef(env, jparent);
(*env)->DeleteLocalRef(env, jax );
} }
[fParent retain]; [fParent retain];
} }
@ -546,7 +573,10 @@ static NSObject *sAttributeNamesLOCK = nil;
return NO; return NO;
} }
return isShowing(env, [self axContextWithEnv:env], fComponent); jobject axContext = [self axContextWithEnv:env];
BOOL showing = isShowing(env, axContext, fComponent);
(*env)->DeleteLocalRef(env, axContext);
return showing;
} }
// the array of names for each role is cached in the sAttributeNamesForRoleCache // the array of names for each role is cached in the sAttributeNamesForRoleCache
@ -723,7 +753,12 @@ static NSObject *sAttributeNamesLOCK = nil;
JNIEnv* env = [ThreadUtilities getJNIEnv]; JNIEnv* env = [ThreadUtilities getJNIEnv];
jobject val = JNFCallStaticObjectMethod(env, sjm_getAccessibleDescription, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop) jobject val = JNFCallStaticObjectMethod(env, sjm_getAccessibleDescription, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
return JNFJavaToNSString(env, val); if (val == NULL) {
return @"unknown";
}
NSString* str = JNFJavaToNSString(env, val);
(*env)->DeleteLocalRef(env, val);
return str;
} }
- (BOOL)accessibilityIsHelpAttributeSettable - (BOOL)accessibilityIsHelpAttributeSettable
@ -739,7 +774,12 @@ static NSObject *sAttributeNamesLOCK = nil;
JNIEnv* env = [ThreadUtilities getJNIEnv]; JNIEnv* env = [ThreadUtilities getJNIEnv];
jobject axValue = JNFCallStaticObjectMethod(env, jm_getMaximumAccessibleValue, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop) jobject axValue = JNFCallStaticObjectMethod(env, jm_getMaximumAccessibleValue, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
return JNFJavaToNSNumber(env, axValue); if (axValue == NULL) {
return [NSNumber numberWithInt:0];
}
NSNumber* num = JNFJavaToNSNumber(env, axValue);
(*env)->DeleteLocalRef(env, axValue);
return num;
} }
- (BOOL)accessibilityIsMaxValueAttributeSettable - (BOOL)accessibilityIsMaxValueAttributeSettable
@ -755,7 +795,12 @@ static NSObject *sAttributeNamesLOCK = nil;
JNIEnv* env = [ThreadUtilities getJNIEnv]; JNIEnv* env = [ThreadUtilities getJNIEnv];
jobject axValue = JNFCallStaticObjectMethod(env, jm_getMinimumAccessibleValue, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop) jobject axValue = JNFCallStaticObjectMethod(env, jm_getMinimumAccessibleValue, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
return JNFJavaToNSNumber(env, axValue); if (axValue == NULL) {
return [NSNumber numberWithInt:0];
}
NSNumber* num = JNFJavaToNSNumber(env, axValue);
(*env)->DeleteLocalRef(env, axValue);
return num;
} }
- (BOOL)accessibilityIsMinValueAttributeSettable - (BOOL)accessibilityIsMinValueAttributeSettable
@ -770,13 +815,16 @@ static NSObject *sAttributeNamesLOCK = nil;
// cmcnote - should batch these two calls into one that returns an array of two bools, one for vertical and one for horiz // cmcnote - should batch these two calls into one that returns an array of two bools, one for vertical and one for horiz
if (isVertical(env, axContext, fComponent)) { if (isVertical(env, axContext, fComponent)) {
(*env)->DeleteLocalRef(env, axContext);
return NSAccessibilityVerticalOrientationValue; return NSAccessibilityVerticalOrientationValue;
} }
if (isHorizontal(env, axContext, fComponent)) { if (isHorizontal(env, axContext, fComponent)) {
(*env)->DeleteLocalRef(env, axContext);
return NSAccessibilityHorizontalOrientationValue; return NSAccessibilityHorizontalOrientationValue;
} }
(*env)->DeleteLocalRef(env, axContext);
return nil; return nil;
} }
@ -808,6 +856,7 @@ static NSObject *sAttributeNamesLOCK = nil;
// Get the java screen coords, and make a NSPoint of the bottom left of the AxComponent. // Get the java screen coords, and make a NSPoint of the bottom left of the AxComponent.
NSSize size = getAxComponentSize(env, axComponent, fComponent); NSSize size = getAxComponentSize(env, axComponent, fComponent);
NSPoint point = getAxComponentLocationOnScreen(env, axComponent, fComponent); NSPoint point = getAxComponentLocationOnScreen(env, axComponent, fComponent);
(*env)->DeleteLocalRef(env, axComponent);
point.y += size.height; point.y += size.height;
@ -857,8 +906,9 @@ static NSObject *sAttributeNamesLOCK = nil;
JNIEnv* env = [ThreadUtilities getJNIEnv]; JNIEnv* env = [ThreadUtilities getJNIEnv];
jobject axRole = JNFCallStaticObjectMethod(env, jm_getAccessibleRoleDisplayString, fAccessible, fComponent); jobject axRole = JNFCallStaticObjectMethod(env, jm_getAccessibleRoleDisplayString, fAccessible, fComponent);
if(axRole != NULL) { if (axRole != NULL) {
value = JNFJavaToNSString(env, axRole); value = JNFJavaToNSString(env, axRole);
(*env)->DeleteLocalRef(env, axRole);
} else { } else {
value = @"unknown"; value = @"unknown";
} }
@ -893,7 +943,9 @@ static NSObject *sAttributeNamesLOCK = nil;
- (NSValue *)accessibilitySizeAttribute { - (NSValue *)accessibilitySizeAttribute {
JNIEnv* env = [ThreadUtilities getJNIEnv]; JNIEnv* env = [ThreadUtilities getJNIEnv];
jobject axComponent = JNFCallStaticObjectMethod(env, sjm_getAccessibleComponent, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop) jobject axComponent = JNFCallStaticObjectMethod(env, sjm_getAccessibleComponent, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
return [NSValue valueWithSize:getAxComponentSize(env, axComponent, fComponent)]; NSValue* size = [NSValue valueWithSize:getAxComponentSize(env, axComponent, fComponent)];
(*env)->DeleteLocalRef(env, axComponent);
return size;
} }
- (BOOL)accessibilityIsSizeAttributeSettable - (BOOL)accessibilityIsSizeAttributeSettable
@ -952,7 +1004,12 @@ static NSObject *sAttributeNamesLOCK = nil;
JNIEnv* env = [ThreadUtilities getJNIEnv]; JNIEnv* env = [ThreadUtilities getJNIEnv];
jobject val = JNFCallStaticObjectMethod(env, sjm_getAccessibleName, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop) jobject val = JNFCallStaticObjectMethod(env, sjm_getAccessibleName, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
return JNFJavaToNSString(env, val); if (val == NULL) {
return @"unknown";
}
NSString* str = JNFJavaToNSString(env, val);
(*env)->DeleteLocalRef(env, val);
return str;
} }
- (BOOL)accessibilityIsTitleAttributeSettable - (BOOL)accessibilityIsTitleAttributeSettable
@ -984,8 +1041,20 @@ static NSObject *sAttributeNamesLOCK = nil;
// a text value is taken care of in JavaTextAccessibility // a text value is taken care of in JavaTextAccessibility
// cmcnote should coalesce these calls into one java call // cmcnote should coalesce these calls into one java call
NSNumber *num = nil;
jobject axValue = JNFCallStaticObjectMethod(env, sjm_getAccessibleValue, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop) jobject axValue = JNFCallStaticObjectMethod(env, sjm_getAccessibleValue, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
return JNFJavaToNSNumber(env, JNFCallStaticObjectMethod(env, jm_getCurrentAccessibleValue, axValue, fComponent)); // AWT_THREADING Safe (AWTRunLoop) if (axValue != NULL) {
jobject str = JNFCallStaticObjectMethod(env, jm_getCurrentAccessibleValue, axValue, fComponent);
if (str != NULL) {
num = JNFJavaToNSNumber(env, str); // AWT_THREADING Safe (AWTRunLoop)
(*env)->DeleteLocalRef(env, str);
}
(*env)->DeleteLocalRef(env, axValue);
}
if (num == nil) {
num = [NSNumber numberWithInt:0];
}
return num;
} }
- (BOOL)accessibilityIsValueAttributeSettable - (BOOL)accessibilityIsValueAttributeSettable
@ -1084,7 +1153,10 @@ static NSObject *sAttributeNamesLOCK = nil;
id value = nil; id value = nil;
if (JNFIsInstanceOf(env, jparent, &jc_Container)) { if (JNFIsInstanceOf(env, jparent, &jc_Container)) {
jobject jaccessible = JNFCallStaticObjectMethod(env, jm_accessibilityHitTest, jparent, (jfloat)point.x, (jfloat)point.y); // AWT_THREADING Safe (AWTRunLoop) jobject jaccessible = JNFCallStaticObjectMethod(env, jm_accessibilityHitTest, jparent, (jfloat)point.x, (jfloat)point.y); // AWT_THREADING Safe (AWTRunLoop)
value = [JavaComponentAccessibility createWithAccessible:jaccessible withEnv:env withView:fView]; if (jaccessible != NULL) {
value = [JavaComponentAccessibility createWithAccessible:jaccessible withEnv:env withView:fView];
(*env)->DeleteLocalRef(env, jaccessible);
}
} }
if (value == nil) { if (value == nil) {
@ -1116,6 +1188,7 @@ static NSObject *sAttributeNamesLOCK = nil;
if (JNFIsInstanceOf(env, focused, &sjc_Accessible)) { if (JNFIsInstanceOf(env, focused, &sjc_Accessible)) {
value = [JavaComponentAccessibility createWithAccessible:focused withEnv:env withView:fView]; value = [JavaComponentAccessibility createWithAccessible:focused withEnv:env withView:fView];
} }
(*env)->DeleteLocalRef(env, focused);
} }
if (value == nil) { if (value == nil) {
@ -1222,38 +1295,46 @@ JNF_COCOA_EXIT(env);
for (i = 0; i < _numTabs; i++) { for (i = 0; i < _numTabs; i++) {
aTab = (JavaComponentAccessibility *)[tabs objectAtIndex:i]; aTab = (JavaComponentAccessibility *)[tabs objectAtIndex:i];
if ([aTab isAccessibleWithEnv:env forAccessible:selAccessible]) { if ([aTab isAccessibleWithEnv:env forAccessible:selAccessible]) {
(*env)->DeleteLocalRef(env, selAccessible);
return aTab; return aTab;
} }
} }
(*env)->DeleteLocalRef(env, selAccessible);
return nil; return nil;
} }
- (NSArray *)tabControlsWithEnv:(JNIEnv *)env withTabGroupAxContext:(jobject)axContext withTabCode:(NSInteger)whichTabs allowIgnored:(BOOL)allowIgnored - (NSArray *)tabControlsWithEnv:(JNIEnv *)env withTabGroupAxContext:(jobject)axContext withTabCode:(NSInteger)whichTabs allowIgnored:(BOOL)allowIgnored
{ {
jobjectArray jtabsAndRoles = JNFCallStaticObjectMethod(env, jm_getChildrenAndRoles, fAccessible, fComponent, whichTabs, allowIgnored); // AWT_THREADING Safe (AWTRunLoop) jobjectArray jtabsAndRoles = (jobjectArray)JNFCallStaticObjectMethod(env, jm_getChildrenAndRoles, fAccessible, fComponent, whichTabs, allowIgnored); // AWT_THREADING Safe (AWTRunLoop)
if(jtabsAndRoles == NULL) return nil; if(jtabsAndRoles == NULL) return nil;
jsize arrayLen = (*env)->GetArrayLength(env, jtabsAndRoles); jsize arrayLen = (*env)->GetArrayLength(env, jtabsAndRoles);
if (arrayLen == 0) return nil; if (arrayLen == 0) {
(*env)->DeleteLocalRef(env, jtabsAndRoles);
return nil;
}
NSMutableArray *tabs = [NSMutableArray arrayWithCapacity:(arrayLen/2)]; NSMutableArray *tabs = [NSMutableArray arrayWithCapacity:(arrayLen/2)];
// all of the tabs have the same role, so we can just find out what that is here and use it for all the tabs // all of the tabs have the same role, so we can just find out what that is here and use it for all the tabs
jobject jtabJavaRole = (*env)->GetObjectArrayElement(env, jtabsAndRoles, 1); // the array entries alternate between tab/role, starting with tab. so the first role is entry 1. jobject jtabJavaRole = (*env)->GetObjectArrayElement(env, jtabsAndRoles, 1); // the array entries alternate between tab/role, starting with tab. so the first role is entry 1.
if (jtabJavaRole == NULL) return nil; if (jtabJavaRole == NULL) {
(*env)->DeleteLocalRef(env, jtabsAndRoles);
NSString *tabJavaRole = JNFJavaToNSString(env, JNFGetObjectField(env, jtabJavaRole, sjf_key)); return nil;
}
jobject jkey = JNFGetObjectField(env, jtabJavaRole, sjf_key);
NSString *tabJavaRole = JNFJavaToNSString(env, jkey);
(*env)->DeleteLocalRef(env, jkey);
NSInteger i; NSInteger i;
NSUInteger tabIndex = (whichTabs >= 0) ? whichTabs : 0; // if we're getting one particular child, make sure to set its index correctly NSUInteger tabIndex = (whichTabs >= 0) ? whichTabs : 0; // if we're getting one particular child, make sure to set its index correctly
for(i = 0; i < arrayLen; i+=2) { for(i = 0; i < arrayLen; i+=2) {
jobject jtab = (*env)->GetObjectArrayElement(env, jtabsAndRoles, i); jobject jtab = (*env)->GetObjectArrayElement(env, jtabsAndRoles, i);
JavaComponentAccessibility *tab = [[[TabGroupControlAccessibility alloc] initWithParent:self withEnv:env withAccessible:jtab withIndex:tabIndex withTabGroup:axContext withView:[self view] withJavaRole:tabJavaRole] autorelease]; JavaComponentAccessibility *tab = [[[TabGroupControlAccessibility alloc] initWithParent:self withEnv:env withAccessible:jtab withIndex:tabIndex withTabGroup:axContext withView:[self view] withJavaRole:tabJavaRole] autorelease];
(*env)->DeleteLocalRef(env, jtab);
[tabs addObject:tab]; [tabs addObject:tab];
tabIndex++; tabIndex++;
} }
(*env)->DeleteLocalRef(env, jtabsAndRoles);
return tabs; return tabs;
} }
@ -1272,7 +1353,9 @@ JNF_COCOA_EXIT(env);
{ {
JNIEnv *env = [ThreadUtilities getJNIEnv]; JNIEnv *env = [ThreadUtilities getJNIEnv];
jobject axContext = [self axContextWithEnv:env]; jobject axContext = [self axContextWithEnv:env];
return [self tabControlsWithEnv:env withTabGroupAxContext:axContext withTabCode:JAVA_AX_ALL_CHILDREN allowIgnored:NO]; id tabs = [self tabControlsWithEnv:env withTabGroupAxContext:axContext withTabCode:JAVA_AX_ALL_CHILDREN allowIgnored:NO];
(*env)->DeleteLocalRef(env, axContext);
return tabs;
} }
- (BOOL)accessibilityIsTabsAttributeSettable - (BOOL)accessibilityIsTabsAttributeSettable
@ -1292,7 +1375,9 @@ JNF_COCOA_EXIT(env);
{ {
JNIEnv *env = [ThreadUtilities getJNIEnv]; JNIEnv *env = [ThreadUtilities getJNIEnv];
jobject axContext = [self axContextWithEnv:env]; jobject axContext = [self axContextWithEnv:env];
return [self contentsWithEnv:env withTabGroupAxContext:axContext withTabCode:JAVA_AX_ALL_CHILDREN allowIgnored:NO]; NSArray* cont = [self contentsWithEnv:env withTabGroupAxContext:axContext withTabCode:JAVA_AX_ALL_CHILDREN allowIgnored:NO];
(*env)->DeleteLocalRef(env, axContext);
return cont;
} }
- (BOOL)accessibilityIsContentsAttributeSettable - (BOOL)accessibilityIsContentsAttributeSettable
@ -1305,7 +1390,9 @@ JNF_COCOA_EXIT(env);
{ {
JNIEnv *env = [ThreadUtilities getJNIEnv]; JNIEnv *env = [ThreadUtilities getJNIEnv];
jobject axContext = [self axContextWithEnv:env]; jobject axContext = [self axContextWithEnv:env];
return [self currentTabWithEnv:env withAxContext:axContext]; id val = [self currentTabWithEnv:env withAxContext:axContext];
(*env)->DeleteLocalRef(env, axContext);
return val;
} }
- (BOOL)accessibilityIsValueAttributeSettable - (BOOL)accessibilityIsValueAttributeSettable
@ -1322,6 +1409,7 @@ JNF_COCOA_EXIT(env);
JNIEnv *env = [ThreadUtilities getJNIEnv]; JNIEnv *env = [ThreadUtilities getJNIEnv];
jobject axContext = [self axContextWithEnv:env]; jobject axContext = [self axContextWithEnv:env];
setAxContextSelection(env, axContext, fIndex, fComponent); setAxContextSelection(env, axContext, fIndex, fComponent);
(*env)->DeleteLocalRef(env, axContext);
} }
- (NSArray *)accessibilityChildrenAttribute - (NSArray *)accessibilityChildrenAttribute
@ -1357,6 +1445,7 @@ JNF_COCOA_EXIT(env);
result = children; result = children;
} }
} }
(*env)->DeleteLocalRef(env, axContext);
} else { } else {
result = [super accessibilityArrayAttributeValues:attribute index:index maxCount:maxCount]; result = [super accessibilityArrayAttributeValues:attribute index:index maxCount:maxCount];
} }
@ -1375,7 +1464,7 @@ static BOOL ObjectEquals(JNIEnv *env, jobject a, jobject b, jobject component);
self = [super initWithParent:parent withEnv:env withAccessible:accessible withIndex:index withView:view withJavaRole:javaRole]; self = [super initWithParent:parent withEnv:env withAccessible:accessible withIndex:index withView:view withJavaRole:javaRole];
if (self) { if (self) {
if (tabGroup != NULL) { if (tabGroup != NULL) {
fTabGroupAxContext = JNFNewGlobalRef(env, tabGroup); fTabGroupAxContext = JNFNewWeakGlobalRef(env, tabGroup);
} else { } else {
fTabGroupAxContext = NULL; fTabGroupAxContext = NULL;
} }
@ -1388,7 +1477,7 @@ static BOOL ObjectEquals(JNIEnv *env, jobject a, jobject b, jobject component);
JNIEnv *env = [ThreadUtilities getJNIEnvUncached]; JNIEnv *env = [ThreadUtilities getJNIEnvUncached];
if (fTabGroupAxContext != NULL) { if (fTabGroupAxContext != NULL) {
JNFDeleteGlobalRef(env, fTabGroupAxContext); JNFDeleteWeakGlobalRef(env, fTabGroupAxContext);
fTabGroupAxContext = NULL; fTabGroupAxContext = NULL;
} }
@ -1399,9 +1488,14 @@ static BOOL ObjectEquals(JNIEnv *env, jobject a, jobject b, jobject component);
{ {
JNIEnv *env = [ThreadUtilities getJNIEnv]; JNIEnv *env = [ThreadUtilities getJNIEnv];
jobject axContext = [self axContextWithEnv:env]; jobject axContext = [self axContextWithEnv:env];
jobject selAccessible = getAxContextSelection(env, [self tabGroup], fIndex, fComponent);
// Returns the current selection of the page tab list // Returns the current selection of the page tab list
return [NSNumber numberWithBool:ObjectEquals(env, axContext, getAxContextSelection(env, [self tabGroup], fIndex, fComponent), fComponent)]; id val = [NSNumber numberWithBool:ObjectEquals(env, axContext, selAccessible, fComponent)];
(*env)->DeleteLocalRef(env, selAccessible);
(*env)->DeleteLocalRef(env, axContext);
return val;
} }
- (void)getActionsWithEnv:(JNIEnv *)env - (void)getActionsWithEnv:(JNIEnv *)env
@ -1416,7 +1510,8 @@ static BOOL ObjectEquals(JNIEnv *env, jobject a, jobject b, jobject component);
if (fTabGroupAxContext == NULL) { if (fTabGroupAxContext == NULL) {
JNIEnv* env = [ThreadUtilities getJNIEnv]; JNIEnv* env = [ThreadUtilities getJNIEnv];
jobject tabGroupAxContext = [(JavaComponentAccessibility *)[self parent] axContextWithEnv:env]; jobject tabGroupAxContext = [(JavaComponentAccessibility *)[self parent] axContextWithEnv:env];
fTabGroupAxContext = JNFNewGlobalRef(env, tabGroupAxContext); fTabGroupAxContext = JNFNewWeakGlobalRef(env, tabGroupAxContext);
(*env)->DeleteLocalRef(env, tabGroupAxContext);
} }
return fTabGroupAxContext; return fTabGroupAxContext;
} }
@ -1451,8 +1546,10 @@ static BOOL ObjectEquals(JNIEnv *env, jobject a, jobject b, jobject component);
if ([[aElement accessibilityRoleAttribute] isEqualToString:NSAccessibilityScrollBarRole]) { if ([[aElement accessibilityRoleAttribute] isEqualToString:NSAccessibilityScrollBarRole]) {
jobject elementAxContext = [aElement axContextWithEnv:env]; jobject elementAxContext = [aElement axContextWithEnv:env];
if (isHorizontal(env, elementAxContext, fComponent)) { if (isHorizontal(env, elementAxContext, fComponent)) {
(*env)->DeleteLocalRef(env, elementAxContext);
return aElement; return aElement;
} }
(*env)->DeleteLocalRef(env, elementAxContext);
} }
} }
@ -1478,8 +1575,10 @@ static BOOL ObjectEquals(JNIEnv *env, jobject a, jobject b, jobject component);
if ([[aElement accessibilityRoleAttribute] isEqualToString:NSAccessibilityScrollBarRole]) { if ([[aElement accessibilityRoleAttribute] isEqualToString:NSAccessibilityScrollBarRole]) {
jobject elementAxContext = [aElement axContextWithEnv:env]; jobject elementAxContext = [aElement axContextWithEnv:env];
if (isVertical(env, elementAxContext, fComponent)) { if (isVertical(env, elementAxContext, fComponent)) {
(*env)->DeleteLocalRef(env, elementAxContext);
return aElement; return aElement;
} }
(*env)->DeleteLocalRef(env, elementAxContext);
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -112,7 +112,9 @@ NSValue *javaIntArrayToNSRangeValue(JNIEnv* env, jintArray array) {
// if it's static text, the AppKit AXValue is the java accessibleName // if it's static text, the AppKit AXValue is the java accessibleName
jobject axName = JNFCallStaticObjectMethod(env, sjm_getAccessibleName, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop) jobject axName = JNFCallStaticObjectMethod(env, sjm_getAccessibleName, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
if (axName != NULL) { if (axName != NULL) {
return JNFJavaToNSString(env, axName); NSString* str = JNFJavaToNSString(env, axName);
(*env)->DeleteLocalRef(env, axName);
return str;
} }
// value is still nil if no accessibleName for static text. Below, try to get the accessibleText. // value is still nil if no accessibleName for static text. Below, try to get the accessibleText.
} }
@ -120,12 +122,18 @@ NSValue *javaIntArrayToNSRangeValue(JNIEnv* env, jintArray array) {
// cmcnote: inefficient to make three distinct JNI calls. Coalesce. radr://3951923 // cmcnote: inefficient to make three distinct JNI calls. Coalesce. radr://3951923
jobject axText = JNFCallStaticObjectMethod(env, sjm_getAccessibleText, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop) jobject axText = JNFCallStaticObjectMethod(env, sjm_getAccessibleText, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
if (axText == NULL) return nil; if (axText == NULL) return nil;
(*env)->DeleteLocalRef(env, axText);
jobject axEditableText = JNFCallStaticObjectMethod(env, sjm_getAccessibleEditableText, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop) jobject axEditableText = JNFCallStaticObjectMethod(env, sjm_getAccessibleEditableText, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
if (axEditableText == NULL) return nil; if (axEditableText == NULL) return nil;
static JNF_STATIC_MEMBER_CACHE(jm_getTextRange, sjc_CAccessibleText, "getTextRange", "(Ljavax/accessibility/AccessibleEditableText;IILjava/awt/Component;)Ljava/lang/String;"); static JNF_STATIC_MEMBER_CACHE(jm_getTextRange, sjc_CAccessibleText, "getTextRange", "(Ljavax/accessibility/AccessibleEditableText;IILjava/awt/Component;)Ljava/lang/String;");
NSString *string = JNFJavaToNSString(env, JNFCallStaticObjectMethod(env, jm_getTextRange, axEditableText, 0, getAxTextCharCount(env, axEditableText, fComponent), fComponent)); // AWT_THREADING Safe (AWTRunLoop) jobject jrange = JNFCallStaticObjectMethod(env, jm_getTextRange, axEditableText, 0, getAxTextCharCount(env, axEditableText, fComponent), fComponent);
NSString *string = JNFJavaToNSString(env, jrange); // AWT_THREADING Safe (AWTRunLoop)
(*env)->DeleteLocalRef(env, jrange);
(*env)->DeleteLocalRef(env, axEditableText);
if (string == nil) string = @""; if (string == nil) string = @"";
return string; return string;
} }
@ -139,6 +147,7 @@ NSValue *javaIntArrayToNSRangeValue(JNIEnv* env, jintArray array) {
JNIEnv* env = [ThreadUtilities getJNIEnv]; JNIEnv* env = [ThreadUtilities getJNIEnv];
jobject axEditableText = JNFCallStaticObjectMethod(env, sjm_getAccessibleEditableText, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop) jobject axEditableText = JNFCallStaticObjectMethod(env, sjm_getAccessibleEditableText, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
if (axEditableText == NULL) return NO; if (axEditableText == NULL) return NO;
(*env)->DeleteLocalRef(env, axEditableText);
return YES; return YES;
} }
@ -157,7 +166,9 @@ NSValue *javaIntArrayToNSRangeValue(JNIEnv* env, jintArray array) {
static JNF_STATIC_MEMBER_CACHE(jm_getSelectedText, sjc_CAccessibleText, "getSelectedText", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljava/lang/String;"); static JNF_STATIC_MEMBER_CACHE(jm_getSelectedText, sjc_CAccessibleText, "getSelectedText", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljava/lang/String;");
jobject axText = JNFCallStaticObjectMethod(env, jm_getSelectedText, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop) jobject axText = JNFCallStaticObjectMethod(env, jm_getSelectedText, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
if (axText == NULL) return @""; if (axText == NULL) return @"";
return JNFJavaToNSString(env, axText); NSString* str = JNFJavaToNSString(env, axText);
(*env)->DeleteLocalRef(env, axText);
return str;
} }
- (BOOL)accessibilityIsSelectedTextAttributeSettable - (BOOL)accessibilityIsSelectedTextAttributeSettable
@ -220,7 +231,9 @@ NSValue *javaIntArrayToNSRangeValue(JNIEnv* env, jintArray array) {
// also, static text doesn't always have accessibleText. if axText is null, should get the charcount of the accessibleName instead // also, static text doesn't always have accessibleText. if axText is null, should get the charcount of the accessibleName instead
JNIEnv *env = [ThreadUtilities getJNIEnv]; JNIEnv *env = [ThreadUtilities getJNIEnv];
jobject axText = JNFCallStaticObjectMethod(env, sjm_getAccessibleText, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop) jobject axText = JNFCallStaticObjectMethod(env, sjm_getAccessibleText, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
return [NSNumber numberWithInt:getAxTextCharCount(env, axText, fComponent)]; NSNumber* num = [NSNumber numberWithInt:getAxTextCharCount(env, axText, fComponent)];
(*env)->DeleteLocalRef(env, axText);
return num;
} }
- (BOOL)accessibilityIsNumberOfCharactersAttributeSettable - (BOOL)accessibilityIsNumberOfCharactersAttributeSettable
@ -285,7 +298,7 @@ NSValue *javaIntArrayToNSRangeValue(JNIEnv* env, jintArray array) {
JNIEnv *env = [ThreadUtilities getJNIEnv]; JNIEnv *env = [ThreadUtilities getJNIEnv];
static JNF_STATIC_MEMBER_CACHE(jm_getBoundsForRange, sjc_CAccessibleText, "getBoundsForRange", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;II)[D"); static JNF_STATIC_MEMBER_CACHE(jm_getBoundsForRange, sjc_CAccessibleText, "getBoundsForRange", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;II)[D");
jdoubleArray axBounds = JNFCallStaticObjectMethod(env, jm_getBoundsForRange, fAccessible, fComponent, range.location, range.length); // AWT_THREADING Safe (AWTRunLoop) jdoubleArray axBounds = (jdoubleArray)JNFCallStaticObjectMethod(env, jm_getBoundsForRange, fAccessible, fComponent, range.location, range.length); // AWT_THREADING Safe (AWTRunLoop)
if (axBounds == NULL) return nil; if (axBounds == NULL) return nil;
// We cheat because we know that the array is 4 elements long (x, y, width, height) // We cheat because we know that the array is 4 elements long (x, y, width, height)
@ -324,7 +337,7 @@ NSValue *javaIntArrayToNSRangeValue(JNIEnv* env, jintArray array) {
JNIEnv *env = [ThreadUtilities getJNIEnv]; JNIEnv *env = [ThreadUtilities getJNIEnv];
static JNF_STATIC_MEMBER_CACHE(jm_getRangeForLine, sjc_CAccessibleText, "getRangeForLine", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;I)[I"); static JNF_STATIC_MEMBER_CACHE(jm_getRangeForLine, sjc_CAccessibleText, "getRangeForLine", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;I)[I");
jintArray axTextRange = JNFCallStaticObjectMethod(env, jm_getRangeForLine, fAccessible, fComponent, [line intValue]); // AWT_THREADING Safe (AWTRunLoop) jintArray axTextRange = (jintArray)JNFCallStaticObjectMethod(env, jm_getRangeForLine, fAccessible, fComponent, [line intValue]); // AWT_THREADING Safe (AWTRunLoop)
if (axTextRange == NULL) return nil; if (axTextRange == NULL) return nil;
return javaIntArrayToNSRangeValue(env,axTextRange); return javaIntArrayToNSRangeValue(env,axTextRange);
@ -350,10 +363,12 @@ NSValue *javaIntArrayToNSRangeValue(JNIEnv* env, jintArray array) {
JNIEnv *env = [ThreadUtilities getJNIEnv]; JNIEnv *env = [ThreadUtilities getJNIEnv];
static JNF_STATIC_MEMBER_CACHE(jm_getStringForRange, sjc_CAccessibleText, "getStringForRange", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;II)Ljava/lang/String;"); static JNF_STATIC_MEMBER_CACHE(jm_getStringForRange, sjc_CAccessibleText, "getStringForRange", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;II)Ljava/lang/String;");
jstring jstringForRange = JNFCallStaticObjectMethod(env, jm_getStringForRange, fAccessible, fComponent, range.location, range.length); // AWT_THREADING Safe (AWTRunLoop) jstring jstringForRange = (jstring)JNFCallStaticObjectMethod(env, jm_getStringForRange, fAccessible, fComponent, range.location, range.length); // AWT_THREADING Safe (AWTRunLoop)
if (jstringForRange == NULL) return @""; if (jstringForRange == NULL) return @"";
return JNFJavaToNSString(env, jstringForRange); NSString* str = JNFJavaToNSString(env, jstringForRange);
(*env)->DeleteLocalRef(env, jstringForRange);
return str;
} }
// //
@ -406,7 +421,7 @@ NSValue *javaIntArrayToNSRangeValue(JNIEnv* env, jintArray array) {
JNIEnv *env = [ThreadUtilities getJNIEnv]; JNIEnv *env = [ThreadUtilities getJNIEnv];
static JNF_STATIC_MEMBER_CACHE(jm_getRangeForIndex, sjc_CAccessibleText, "getRangeForIndex", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;I)[I"); static JNF_STATIC_MEMBER_CACHE(jm_getRangeForIndex, sjc_CAccessibleText, "getRangeForIndex", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;I)[I");
jintArray axTextRange = JNFCallStaticObjectMethod(env, jm_getRangeForIndex, fAccessible, fComponent, index); // AWT_THREADING Safe (AWTRunLoop) jintArray axTextRange = (jintArray)JNFCallStaticObjectMethod(env, jm_getRangeForIndex, fAccessible, fComponent, index); // AWT_THREADING Safe (AWTRunLoop)
if (axTextRange == NULL) return nil; if (axTextRange == NULL) return nil;
return javaIntArrayToNSRangeValue(env, axTextRange); return javaIntArrayToNSRangeValue(env, axTextRange);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -31,7 +31,7 @@
@interface CGLLayer : CAOpenGLLayer @interface CGLLayer : CAOpenGLLayer
{ {
@private @private
JNFJObjectWrapper *javaLayer; JNFWeakJObjectWrapper *javaLayer;
// intermediate buffer, used the RQ lock to synchronize // intermediate buffer, used the RQ lock to synchronize
GLuint textureID; GLuint textureID;
@ -45,7 +45,7 @@
#endif /* REMOTELAYER */ #endif /* REMOTELAYER */
} }
@property (nonatomic, retain) JNFJObjectWrapper *javaLayer; @property (nonatomic, retain) JNFWeakJObjectWrapper *javaLayer;
@property (readwrite, assign) GLuint textureID; @property (readwrite, assign) GLuint textureID;
@property (readwrite, assign) GLenum target; @property (readwrite, assign) GLenum target;
@property (readwrite, assign) float textureWidth; @property (readwrite, assign) float textureWidth;
@ -57,7 +57,7 @@
@property (nonatomic, retain) NSObject<JRSRemoteLayer> *jrsRemoteLayer; @property (nonatomic, retain) NSObject<JRSRemoteLayer> *jrsRemoteLayer;
#endif #endif
- (id) initWithJavaLayer:(JNFJObjectWrapper *)javaLayer; - (id) initWithJavaLayer:(JNFWeakJObjectWrapper *)javaLayer;
- (void) blitTexture; - (void) blitTexture;
@end @end

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -46,7 +46,7 @@ extern NSOpenGLContext *sharedContext;
@synthesize jrsRemoteLayer; @synthesize jrsRemoteLayer;
#endif #endif
- (id) initWithJavaLayer:(JNFJObjectWrapper *)layer; - (id) initWithJavaLayer:(JNFWeakJObjectWrapper *)layer;
{ {
AWT_ASSERT_APPKIT_THREAD; AWT_ASSERT_APPKIT_THREAD;
// Initialize ourselves // Initialize ourselves
@ -133,6 +133,15 @@ AWT_ASSERT_APPKIT_THREAD;
{ {
AWT_ASSERT_APPKIT_THREAD; AWT_ASSERT_APPKIT_THREAD;
JNIEnv *env = [ThreadUtilities getJNIEnv];
static JNF_CLASS_CACHE(jc_JavaLayer, "sun/java2d/opengl/CGLLayer");
static JNF_MEMBER_CACHE(jm_drawInCGLContext, jc_JavaLayer, "drawInCGLContext", "()V");
jobject javaLayerLocalRef = [self.javaLayer jObjectWithEnv:env];
if ((*env)->IsSameObject(env, javaLayerLocalRef, NULL)) {
return;
}
// Set the current context to the one given to us. // Set the current context to the one given to us.
CGLSetCurrentContext(glContext); CGLSetCurrentContext(glContext);
@ -141,12 +150,7 @@ AWT_ASSERT_APPKIT_THREAD;
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
glViewport(0, 0, textureWidth, textureHeight); glViewport(0, 0, textureWidth, textureHeight);
JNIEnv *env = [ThreadUtilities getJNIEnv];
static JNF_CLASS_CACHE(jc_JavaLayer, "sun/java2d/opengl/CGLLayer");
static JNF_MEMBER_CACHE(jm_drawInCGLContext, jc_JavaLayer, "drawInCGLContext", "()V");
jobject javaLayerLocalRef = [self.javaLayer jObjectWithEnv:env];
JNFCallVoidMethod(env, javaLayerLocalRef, jm_drawInCGLContext); JNFCallVoidMethod(env, javaLayerLocalRef, jm_drawInCGLContext);
(*env)->DeleteLocalRef(env, javaLayerLocalRef); (*env)->DeleteLocalRef(env, javaLayerLocalRef);
@ -171,7 +175,7 @@ Java_sun_java2d_opengl_CGLLayer_nativeCreateLayer
JNF_COCOA_ENTER(env); JNF_COCOA_ENTER(env);
JNFJObjectWrapper *javaLayer = [JNFJObjectWrapper wrapperWithJObject:obj withEnv:env]; JNFWeakJObjectWrapper *javaLayer = [JNFWeakJObjectWrapper wrapperWithJObject:obj withEnv:env];
[ThreadUtilities performOnMainThreadWaiting:YES block:^(){ [ThreadUtilities performOnMainThreadWaiting:YES block:^(){
AWT_ASSERT_APPKIT_THREAD; AWT_ASSERT_APPKIT_THREAD;