1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-10 23:44:24 +00:00

Android: Fix a couple of accessibility-related crashes

These crashes could be seen in the DemoRunner when selecting items in
nested PopupMenu windows.
This commit is contained in:
reuk 2022-05-23 19:59:57 +01:00
parent 61b26e4e35
commit 2b1745272e
No known key found for this signature in database
GPG key ID: 9ADCD339CFC98A11
5 changed files with 24 additions and 5 deletions

View file

@ -63,7 +63,6 @@ AccessibilityHandler::AccessibilityHandler (Component& comp,
interfaces (std::move (interfacesIn)),
nativeImpl (createNativeImpl (*this))
{
notifyAccessibilityEventInternal (*this, InternalAccessibilityEvent::elementCreated);
}
AccessibilityHandler::~AccessibilityHandler()

View file

@ -3308,6 +3308,18 @@ AccessibilityHandler* Component::getAccessibilityHandler()
|| accessibilityHandler->getTypeIndex() != std::type_index (typeid (*this)))
{
accessibilityHandler = createAccessibilityHandler();
// On Android, notifying that an element was created can cause the system to request
// the accessibility node info for the new element. If we're not careful, this will lead
// to recursive calls, as each time an element is created, new node info will be requested,
// causing an element to be created, causing a new info request...
// By assigning the accessibility handler before notifying the system that an element was
// created, the if() predicate above should evaluate to false on recursive calls,
// terminating the recursion.
if (accessibilityHandler != nullptr)
notifyAccessibilityEventInternal (*accessibilityHandler, InternalAccessibilityEvent::elementCreated);
else
jassertfalse; // createAccessibilityHandler must return non-null
}
return accessibilityHandler.get();

View file

@ -87,7 +87,7 @@ struct HeaderItemComponent : public PopupMenu::CustomComponent
std::unique_ptr<AccessibilityHandler> createAccessibilityHandler() override
{
return nullptr;
return createIgnoredAccessibilityHandler (*this);
}
const Options& options;
@ -275,7 +275,8 @@ private:
std::unique_ptr<AccessibilityHandler> createAccessibilityHandler() override
{
return item.isSeparator ? nullptr : std::make_unique<ItemAccessibilityHandler> (*this);
return item.isSeparator ? createIgnoredAccessibilityHandler (*this)
: std::make_unique<ItemAccessibilityHandler> (*this);
}
//==============================================================================

View file

@ -481,10 +481,15 @@ public:
case ACTION_CLICK:
{
// Invoking the action may delete this handler
const WeakReference<AccessibilityNativeHandle> savedHandle { this };
if ((accessibilityHandler.getCurrentState().isCheckable() && accessibilityHandler.getActions().invoke (AccessibilityActionType::toggle))
|| accessibilityHandler.getActions().invoke (AccessibilityActionType::press))
{
if (savedHandle != nullptr)
sendAccessibilityEventImpl (accessibilityHandler, TYPE_VIEW_CLICKED, 0);
return true;
}
@ -742,6 +747,8 @@ private:
//==============================================================================
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AccessibilityNativeHandle)
JUCE_DECLARE_WEAK_REFERENCEABLE (AccessibilityNativeHandle)
};
std::unordered_map<int, AccessibilityHandler*> AccessibilityNativeHandle::virtualViewIdMap;

View file

@ -247,7 +247,7 @@ std::unique_ptr<AccessibilityHandler> ToolbarItemComponent::createAccessibilityH
&& itemId != ToolbarItemFactory::flexibleSpacerId);
if (! shouldItemBeAccessible)
return nullptr;
return createIgnoredAccessibilityHandler (*this);
return std::make_unique<ButtonAccessibilityHandler> (*this, AccessibilityRole::button);
}