Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix talkback in hybrid composition while using FlutterFragmentActivity #22429

Merged
merged 6 commits into from Nov 12, 2020

Conversation

blasten
Copy link

@blasten blasten commented Nov 10, 2020

To support TalkBack while using platform views, we detect whether the view is in a virtual display or in the view hierarchy. Currently, we assume that if the view is in a FlutterActivity context, then it's in a view hierarchy.

This breaks cases like FlutterFragmentActivity or hosting a FlutterView in a custom Activity (add-to-app).

Fixes flutter/flutter#68970

@@ -52,7 +52,7 @@
*/
@Keep
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
class SingleViewPresentation extends Presentation {
public class SingleViewPresentation extends Presentation {
Copy link
Author

Choose a reason for hiding this comment

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

we should look into re-organizing the packages in the embedding. The current structure isn't well suited, and ends up requiring public classes when they aren't intended to be used outside of the embedding internal implementation. cc @xster

Copy link
Member

Choose a reason for hiding this comment

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

Sure, we can definitely re-organize things (which is easier if most things stay private to avoid breaking changes). It's low-priority on my mind so far since I don't have many concrete needs for refactoring. What's on your mind?

Copy link
Author

Choose a reason for hiding this comment

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

which is easier if most things stay private to avoid breaking changes

Right. Although, for the time being we should be able to use https://code.google.com/archive/p/doclava/wikis/JavadocTags.wiki#@hide.

Copy link
Contributor

@amirh amirh left a comment

Choose a reason for hiding this comment

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

nit: describing the nature of the change and the reason behind it in the PR description helps making the review easier and may help future code archeologists

@@ -558,7 +558,7 @@ public AccessibilityNodeInfo createAccessibilityNodeInfo(int virtualViewId) {
if (semanticsNode.platformViewId != -1) {
View embeddedView =
platformViewsAccessibilityDelegate.getPlatformViewById(semanticsNode.platformViewId);
boolean childUsesVirtualDisplay = !(embeddedView.getContext() instanceof FlutterActivity);
boolean childUsesVirtualDisplay = embeddedView.getContext() instanceof PresentationContext;
Copy link
Contributor

Choose a reason for hiding this comment

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

This isn't very robust, nothing stops platform views from providing their own contexts. Can we track the platform view type within the embedding code so that childUsesVirtualDisplay can't be changed by plugin code?

Copy link
Author

Choose a reason for hiding this comment

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

Under what situation someone just ignores the context passed to the factory when creating the view? PresentationContext has some logic like isCalledFromAlertDialog, does it mean that we support not using that functionality?

Copy link
Contributor

Choose a reason for hiding this comment

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

One doesn't have to ignore the context passed in, Android provides ContextWrapper which lets you change just the thing you need in the context. If that is done the instanceOf check will not check for what you want.

Copy link
Author

Choose a reason for hiding this comment

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

so given that we will deprecate this code in the near future, what about we use ContextWrapper#getBaseContext() to get the original context?

Copy link
Contributor

Choose a reason for hiding this comment

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

What's the deprecation timeline?
Is it hard to track a bit for whether this is a HC or VD platform view?

Copy link
Contributor

@amirh amirh Nov 11, 2020

Choose a reason for hiding this comment

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

BTW isn't the robustness of this check important for both the VD and HC use cases?

Copy link
Author

@blasten blasten Nov 11, 2020

Choose a reason for hiding this comment

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

On Android 10, b/171449547 is broken if the view is in a virtual display.

For HC, this check should always work since PresentationContext isn't a public API. Once VD is deprecated, this check will not exist as platform views using VD will use HC automatically. Deprecating VD doesn't break public APIs, we would just need to change the implementation of AndroidView in the framework.

Copy link
Contributor

Choose a reason for hiding this comment

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

Good point about PresentationContext not being public (though technically you just turned it public in this PR, is @hide for non-Android-SDK code enforces anything or does it just prune Javadocs?)
I see your point that this is likely not going to break folks anytime soon, however assuming a robust fix (keeping track of the kind of view) requires no more than a couple hours of work my preference would be to keep on the safe side.
My concern would be that we will end up staying with VDs for longer than we think right now and some non standard use-case (of a replaced context) will turn into a debugging nightmare.

Copy link
Author

Choose a reason for hiding this comment

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

The patch ended up being smaller. PTAL.

@hide would hide it from the public documentation. I wish it had the same meaning it has for the Android-SDK code :)

Copy link
Contributor

Choose a reason for hiding this comment

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

Shorter than this thread 😄

Thanks!

@blasten blasten requested a review from amirh November 11, 2020 23:42
Copy link
Contributor

@amirh amirh left a comment

Choose a reason for hiding this comment

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

LGTM

@blasten blasten merged commit 091b6cc into flutter:master Nov 12, 2020
@blasten blasten deleted the talkback_hybrid_composition branch November 12, 2020 18:30
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Nov 13, 2020
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Nov 13, 2020
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Nov 13, 2020
chaselatta pushed a commit to chaselatta/engine that referenced this pull request Nov 30, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
4 participants