Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Fix for a11y crash on iOS #12990

Merged
merged 5 commits into from
Oct 8, 2019
Merged

Fix for a11y crash on iOS #12990

merged 5 commits into from
Oct 8, 2019

Conversation

dnfield
Copy link
Contributor

@dnfield dnfield commented Oct 8, 2019

Without this change, we're seeing logs like:

[AXRuntimeCommon] This class 'FlutterSemanticsObject' is not a known serializable element and returning it as an accessibility element may lead to crashes
[AXRuntimeCommon] This class 'SemanticsObject' is not a known serializable element and returning it as an accessibility element may lead to crashes
[AXRuntimeCommon] This class 'SemanticsObjectContainer' is not a known serializable element and returning it as an accessibility element may lead to crashes

which is actually leading to the crash reported in flutter/flutter#42018

The documentation around these isn't so great, but it looks like right now we're implicitly implementing these interfaces and iOS wants us to be more explicit. The container object seems like it's ok as well because we're setting isAccessibilityElement to NO, which is what you're supposed to do for containers.

Still need to come up with a good test for this - I need some additional access to reproduce the internal customer's crash locally, which I should have in the near term.

/cc @gaaclarke @jkurtw

/cc @goderbauer @cbracken @jmagman who hopefully know something about why this will or will not work 😆

Copy link
Member

@gaaclarke gaaclarke left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The thing that is a bit of a hangup for me is making the containers UIAccessibilityElements. I've read through the documentation a bit and I think our UIAccessibilityContainer should just be the FlutterView itself. It should override the accessibilityElements method and return the UIAccessibilityElements we calculated in the last update semantics pass. Making the containers inherit from UIAccessibilityElement seems a bit of a hack to give the containers the secret sauce to make them work in lieu of a UIView.

Reworking that is not a trivial change though probably. With adequate testing I'm willing to accept this with the hopes that we someday make the change I proposed.

@dnfield
Copy link
Contributor Author

dnfield commented Oct 8, 2019

Making the containers inherit from UIAccessibilityElement seems a bit of a hack to give the containers the secret sauce to make them work in lieu of a UIView.

I think we'll still need containers in there - I don't think they can all be direct children of the UIView.

@@ -109,7 +109,7 @@ - (instancetype)init {
- (instancetype)initWithBridge:(fml::WeakPtr<flutter::AccessibilityBridge>)bridge uid:(int32_t)uid {
FML_DCHECK(bridge) << "bridge must be set";
FML_DCHECK(uid >= kRootNodeId);
self = [super init];
self = [super initWithAccessibilityContainer:bridge->view()];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here and everywhere else this is called: I believe not all SemanticsObjects have the view as an accessibility container. There are some intermediate a11y containers that we create. Shouldn't the SemanticsObjects be attached to their container, not the root?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem is we don't know the containers at this point - but it seems to work because we later assign it to the right container when we actually create the container.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There should probably at least be a comment here then. And I am wondering how we can assure that it is going to be assigned the right container....

@goderbauer
Copy link
Member

We can't just remove all containers and make all of our semantics objects children of the view. The containers give the a11y hierarchy structure (which VoiceOver uses to move a11y focus to the correct next element) and you also need containers to implement scrolling etc.

@goderbauer
Copy link
Member

Have you tried that VoiceOver still works as expected? We totally need better automated testing for this :(

@dnfield
Copy link
Contributor Author

dnfield commented Oct 8, 2019

I can't come up with a good integration test for this. The reproduction is: turn on voiceover on an app with a scrollable that goes beyond the extent of the screen and use three fingers to scroll the list.

We don't have any tests that use Voiceover. We should, but we don't. It's a non-trivial task to do so - I've filed an issue for that. I'll see if I can at least make the changes to the a11y bridge more testable...

@dnfield
Copy link
Contributor Author

dnfield commented Oct 8, 2019

I've manually confirmed that a11y still works on iOS with these changes. Writing a test for this will require creating a new test harness for iOS. I'm going to take that up in a follow up PR. For now I'd like to get this merged to unblock the internal customer.

@dnfield dnfield marked this pull request as ready for review October 8, 2019 23:05
@dnfield
Copy link
Contributor Author

dnfield commented Oct 8, 2019

Framework redness is expected ATM due to manual roll needed.

@dnfield dnfield merged commit 2f352d6 into flutter:master Oct 8, 2019
@dnfield dnfield deleted the ios_a11y_crash branch October 8, 2019 23:37
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Oct 9, 2019
engine-flutter-autoroll added a commit to flutter/flutter that referenced this pull request Oct 9, 2019
git@github.com:flutter/engine.git/compare/c635d70c7266...21b8224

git log c635d70..21b8224 --no-merges --oneline
2019-10-08 gspencergoog@users.noreply.github.com Send AccessibilityEvent.TYPE_VIEW_FOCUSED when input focus is set. (flutter/engine#12746)
2019-10-08 dnfield@google.com Fix for a11y crash on iOS (flutter/engine#12990)
2019-10-08 katelovett@google.com Link Semantics Typo (flutter/engine#13009)
2019-10-08 ferhat@gmail.com [web] Add support for path transform (flutter/engine#12794)
2019-10-08 jason-simmons@users.noreply.github.com Auto-formatter fixes for BUILD.gn files (flutter/engine#13005)
2019-10-08 bkonyi@google.com Unblock SIGPROF on flutter_tester start (flutter/engine#12813)
2019-10-08 mouad.debbar@gmail.com [web] Update the url when route is replaced (flutter/engine#13003)
2019-10-08 katelovett@google.com Missing link flag (flutter/engine#13001)
2019-10-08 30870216+gaaclarke@users.noreply.github.com Started setting our debug background task id to invalid after completion. (flutter/engine#12999)
2019-10-08 ychris@google.com Add `onUnregistered` callback in 'Texture' and 'FlutterTexture' (flutter/engine#12695)


If this roll has caused a breakage, revert this CL and stop the roller
using the controls here:
https://autoroll.skia.org/r/flutter-engine-flutter-autoroll
Please CC chinmaygarde@google.com on the revert to ensure that a human
is aware of the problem.

To report a problem with the AutoRoller itself, please file a bug:
https://bugs.chromium.org/p/skia/issues/entry?template=Autoroller+Bug

Documentation for the AutoRoller is here:
https://skia.googlesource.com/buildbot/+/master/autoroll/README.md
Inconnu08 pushed a commit to Inconnu08/flutter that referenced this pull request Nov 26, 2019
git@github.com:flutter/engine.git/compare/c635d70c7266...21b8224

git log c635d70..21b8224 --no-merges --oneline
2019-10-08 gspencergoog@users.noreply.github.com Send AccessibilityEvent.TYPE_VIEW_FOCUSED when input focus is set. (flutter/engine#12746)
2019-10-08 dnfield@google.com Fix for a11y crash on iOS (flutter/engine#12990)
2019-10-08 katelovett@google.com Link Semantics Typo (flutter/engine#13009)
2019-10-08 ferhat@gmail.com [web] Add support for path transform (flutter/engine#12794)
2019-10-08 jason-simmons@users.noreply.github.com Auto-formatter fixes for BUILD.gn files (flutter/engine#13005)
2019-10-08 bkonyi@google.com Unblock SIGPROF on flutter_tester start (flutter/engine#12813)
2019-10-08 mouad.debbar@gmail.com [web] Update the url when route is replaced (flutter/engine#13003)
2019-10-08 katelovett@google.com Missing link flag (flutter/engine#13001)
2019-10-08 30870216+gaaclarke@users.noreply.github.com Started setting our debug background task id to invalid after completion. (flutter/engine#12999)
2019-10-08 ychris@google.com Add `onUnregistered` callback in 'Texture' and 'FlutterTexture' (flutter/engine#12695)


If this roll has caused a breakage, revert this CL and stop the roller
using the controls here:
https://autoroll.skia.org/r/flutter-engine-flutter-autoroll
Please CC chinmaygarde@google.com on the revert to ensure that a human
is aware of the problem.

To report a problem with the AutoRoller itself, please file a bug:
https://bugs.chromium.org/p/skia/issues/entry?template=Autoroller+Bug

Documentation for the AutoRoller is here:
https://skia.googlesource.com/buildbot/+/master/autoroll/README.md
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants