Skip to content

Commit

Permalink
Android: move QtAccessibilityDelegate instance to QtActivityDelegateBase
Browse files Browse the repository at this point in the history
Similar to the display manager and the input delegate, keep the
accessibility delegate under the base class. Also, following the same
pattern as in the parent patch, assign a default instance for this in
the delegate in the constructor, and initialize anything later when
needed. Also, make sure calls for various objects under the
QtAccessibilityDelegate are safe and guarded.

Task-number: QTBUG-129704
Pick-to: 6.8
Change-Id: I14a57d8e0916127ae8fa00acb3265b92803087dc
Reviewed-by: Petri Virkkunen <[email protected]>
  • Loading branch information
Issam-b committed Oct 31, 2024
1 parent ca8ca21 commit af73c7a
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ class QtAccessibilityDelegate extends View.AccessibilityDelegate
private static final String DEFAULT_CLASS_NAME = "$VirtualChild";

private View m_view = null;
private final AccessibilityManager m_manager;
private final QtLayout m_layout;
private AccessibilityManager m_manager;
private QtLayout m_layout;

// The accessible object that currently has the "accessibility focus"
// usually indicated by a yellow rectangle on screen.
Expand All @@ -63,11 +63,16 @@ public boolean onHover(View v, MotionEvent event)
// e.g. one per window?
// FIXME make QtAccessibilityDelegate window based or verify current way works
// also for child windows: QTBUG-120685
QtAccessibilityDelegate(QtLayout layout)
QtAccessibilityDelegate() { }

void initLayoutAccessibility(QtLayout layout)
{
if (m_layout == null)
Log.w(TAG, "Unable to initialize the accessibility delegate with a null layout");

m_layout = layout;

m_manager = (AccessibilityManager) m_layout.getContext().getSystemService(Context.ACCESSIBILITY_SERVICE);
m_manager = m_layout.getContext().getSystemService(AccessibilityManager.class);
if (m_manager != null) {
AccessibilityManagerListener accServiceListener = new AccessibilityManagerListener();
if (!m_manager.addAccessibilityStateChangeListener(accServiceListener))
Expand All @@ -82,7 +87,7 @@ private class AccessibilityManagerListener implements AccessibilityManager.Acces
@Override
public void onAccessibilityStateChanged(boolean enabled)
{
if (Os.getenv("QT_ANDROID_DISABLE_ACCESSIBILITY") != null)
if (m_layout == null || Os.getenv("QT_ANDROID_DISABLE_ACCESSIBILITY") != null)
return;
if (enabled) {
try {
Expand Down Expand Up @@ -136,7 +141,7 @@ public AccessibilityNodeProvider getAccessibilityNodeProvider(View host)
// (user moves finger over screen to discover items on screen).
private boolean dispatchHoverEvent(MotionEvent event)
{
if (!m_manager.isTouchExplorationEnabled()) {
if (m_manager == null || !m_manager.isTouchExplorationEnabled()) {
return false;
}

Expand Down Expand Up @@ -177,7 +182,7 @@ void notifyObjectHide(int viewId, int parentId)
// Note: This code is mostly copied from
// AccessibilityNodeProvider::performAction, but we remove the
// focus only if the focused view id matches the one that was hidden.
if (m_focusedVirtualViewId == viewId) {
if (m_view != null && m_focusedVirtualViewId == viewId) {
m_focusedVirtualViewId = INVALID_ID;
m_view.invalidate();
sendEventForVirtualViewId(viewId,
Expand Down Expand Up @@ -212,7 +217,13 @@ void notifyObjectFocus(int viewId)

void notifyValueChanged(int viewId, String value)
{
if (m_manager == null)
return;

QtNative.runAction(() -> {
if (m_view == null)
return;

// Send a TYPE_ANNOUNCEMENT event with the new value

if ((viewId == INVALID_ID) || !m_manager.isEnabled()) {
Expand Down Expand Up @@ -255,7 +266,7 @@ void sendEventForVirtualViewId(int virtualViewId, int eventType)

void sendAccessibilityEvent(AccessibilityEvent event)
{
if (event == null)
if (m_view == null || event == null)
return;

final ViewGroup group = (ViewGroup) m_view.getParent();
Expand Down Expand Up @@ -292,12 +303,13 @@ private void setHoveredVirtualViewId(int virtualViewId)

private AccessibilityEvent getEventForVirtualViewId(int virtualViewId, int eventType)
{
if ((virtualViewId == INVALID_ID) || !m_manager.isEnabled()) {
final boolean isManagerEnabled = m_manager != null && m_manager.isEnabled();
if (m_view == null || !isManagerEnabled || (virtualViewId == INVALID_ID)) {
Log.w(TAG, "getEventForVirtualViewId for invalid view");
return null;
}

if (m_layout.getChildCount() == 0)
if (m_layout == null || m_layout.getChildCount() == 0)
return null;

final AccessibilityEvent event = AccessibilityEvent.obtain(eventType);
Expand Down Expand Up @@ -330,6 +342,9 @@ private void dumpNodes(int parentId)

private AccessibilityNodeInfo getNodeForView()
{
if (m_view == null || m_layout == null)
return AccessibilityNodeInfo.obtain();

// Since we don't want the parent to be focusable, but we can't remove
// actions from a node, copy over the necessary fields.
final AccessibilityNodeInfo result = AccessibilityNodeInfo.obtain(m_view);
Expand Down Expand Up @@ -391,6 +406,9 @@ private AccessibilityNodeInfo getNodeForView()

private AccessibilityNodeInfo getNodeForVirtualViewId(int virtualViewId)
{
if (m_view == null || m_layout == null)
return AccessibilityNodeInfo.obtain();

final AccessibilityNodeInfo node = AccessibilityNodeInfo.obtain();

node.setClassName(m_view.getClass().getName() + DEFAULT_CLASS_NAME);
Expand Down Expand Up @@ -456,6 +474,11 @@ public AccessibilityNodeInfo createAccessibilityNodeInfo(int virtualViewId)
@Override
public boolean performAction(int virtualViewId, int action, Bundle arguments)
{
if (m_view == null) {
Log.e(TAG, "Unable to perform action with a null view");
return false;
}

boolean handled = false;
//Log.i(TAG, "PERFORM ACTION: " + action + " on " + virtualViewId);
switch (action) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ class QtActivityDelegate extends QtActivityDelegateBase

private View m_dummyView = null;
private final HashMap<Integer, View> m_nativeViews = new HashMap<>();
private QtAccessibilityDelegate m_accessibilityDelegate = null;

QtActivityDelegate(Activity activity)
{
Expand Down Expand Up @@ -248,60 +247,45 @@ public void onAnimationStart(Animation animation) {
@Override
public void notifyLocationChange(int viewId)
{
if (m_accessibilityDelegate == null)
return;
m_accessibilityDelegate.notifyLocationChange(viewId);
getAccessibilityDelegate().notifyLocationChange(viewId);
}

@Override
public void notifyObjectHide(int viewId, int parentId)
{
if (m_accessibilityDelegate == null)
return;
m_accessibilityDelegate.notifyObjectHide(viewId, parentId);
getAccessibilityDelegate().notifyObjectHide(viewId, parentId);
}

@Override
public void notifyObjectShow(int parentId)
{
if (m_accessibilityDelegate == null)
return;
m_accessibilityDelegate.notifyObjectShow(parentId);
getAccessibilityDelegate().notifyObjectShow(parentId);
}

@Override
public void notifyObjectFocus(int viewId)
{
if (m_accessibilityDelegate == null)
return;
m_accessibilityDelegate.notifyObjectFocus(viewId);
getAccessibilityDelegate().notifyObjectFocus(viewId);
}

@Override
public void notifyValueChanged(int viewId, String value)
{
if (m_accessibilityDelegate == null)
return;
m_accessibilityDelegate.notifyValueChanged(viewId, value);
getAccessibilityDelegate().notifyValueChanged(viewId, value);
}

@Override
public void notifyScrolledEvent(int viewId)
{
if (m_accessibilityDelegate == null)
return;
m_accessibilityDelegate.notifyScrolledEvent(viewId);
getAccessibilityDelegate().notifyScrolledEvent(viewId);
}

@Override
public void initializeAccessibility()
{
QtNative.runAction(() -> {
// FIXME make QtAccessibilityDelegate window based
if (m_layout != null)
m_accessibilityDelegate = new QtAccessibilityDelegate(m_layout);
else
Log.w(QtTAG, "Null layout, failed to initialize accessibility delegate.");
getAccessibilityDelegate().initLayoutAccessibility(m_layout);
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ abstract class QtActivityDelegateBase
protected final HashMap<Integer, QtWindow> m_topLevelWindows = new HashMap<>();
protected final QtDisplayManager m_displayManager;
protected final QtInputDelegate m_inputDelegate;
private final QtAccessibilityDelegate m_accessibilityDelegate;

private boolean m_membersInitialized = false;
private boolean m_contextMenuVisible = false;
Expand All @@ -60,6 +61,7 @@ void setActionBarVisibility(boolean visible) {}
QtNative.setActivity(m_activity);
m_displayManager = new QtDisplayManager(m_activity);
m_inputDelegate = new QtInputDelegate(m_displayManager::updateFullScreen);
m_accessibilityDelegate = new QtAccessibilityDelegate();
}

QtDisplayManager displayManager() {
Expand All @@ -70,6 +72,10 @@ QtInputDelegate getInputDelegate() {
return m_inputDelegate;
}

QtAccessibilityDelegate getAccessibilityDelegate() {
return m_accessibilityDelegate;
}

void setContextMenuVisible(boolean contextMenuVisible)
{
m_contextMenuVisible = contextMenuVisible;
Expand Down

0 comments on commit af73c7a

Please sign in to comment.