-
Notifications
You must be signed in to change notification settings - Fork 6k
Fix array == null error in AccessibilityBridge #35540
Conversation
|
It looks like this pull request may not have tests. Please make sure to add tests before merging. If you need an exemption to this rule, contact Hixie on the #hackers channel in Chat (don't just cc him here, he won't see it! He's on Discord!). If you are not sure if you need tests, consider this rule of thumb: the purpose of a test is to make sure someone doesn't accidentally revert the fix. Ask yourself, is there anything in your PR that you feel it is important we not accidentally revert back to how it was before your fix? Reviewers: Read the Tree Hygiene page and make sure this patch meets those guidelines before LGTMing. |
|
Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). View this failed invocation of the CLA check for more information. For the most up to date status, view the checks section at the bottom of the pull request. |
|
Will any one review this commit? |
| globalTransform = new float[16]; | ||
| } | ||
| if (transform == null) { | ||
| transform = new float[16]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this and the thing above be initialized to an identity transformation?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cc @Hixie who may have context as the author of the original null check that initialized all matrix elements to zero.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
better than crash
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cc @Hixie who may have context as the author of the original null check that initialized all matrix elements to zero.
Hope merge, plz
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be initialized during the SemanticsNode.updateWith. The only possible case I can think of is the framework sent a semantics node with child that is not in the update list. This feels like a bug in the framework side. Do you have a reproducible code?
|
From PR triage: @stuartmorgan Do you know who would be the right reviewer for this change? Should the concern from @chinmaygarde be addressed? |
|
@chunhtai Are you familiar with this code? It looks like you are one of the people who has been most active in this file. |
|
@GuaiYiHu Can you provide a reproduction of the crash so we can investigate what the correct course of action is? Either mitigate the crash with this PR or fix the upstream root bug. |
|
I think this is a safe fix either way and the same pattern followed elsewhere is being followed here. |
|
I am ok if we add an assert so that we still have a chance to catch the root cause but avoiding crash in production. @GuaiYiHu Can you add an assert that it should never be null? |
sure |
9e69811 to
9d3c709
Compare
| if (globalTransform == null) { | ||
| globalTransform = new float[16]; | ||
| } | ||
| if (transform == null) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I imagine you still need another condition to initialize it so it won't crash in release code.
I did try to compile a custom engine in release mode, but it looks like the assertion will still crash the app. @GaryQian Do you know if the assertionError will be ignored in release mode?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You meant the exception will be thrown only on debug mode, right? Shall BuildConfig.DEBUG work?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah I think BuildConfig.DEBUG is probably the best way to do this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
will reedit it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added a comment
4eb7240 to
b383392
Compare
|
@chunhtai Pushed again, all checks have passed, please review, thanks a lot. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, I don't think there is a good way to test this change. This is adding an instrument to catch something should happen in the first place.
| if (transform == null) { | ||
| if (BuildConfig.DEBUG) { | ||
| throw new AssertionError("transform has not been initialized"); | ||
| } else { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this else case is redundant
if (BuildConfig.DEBUG) {
throw new AssertionError("transform has not been initialized");
}
transform = new float[16];There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
awesome
* Throw AssertionError to track the exception in case transform array is null on debug mode 08-16 06:23:59.641 23012 23012 E flutter : [ERROR:flutter/fml/platform/android/jni_util.cc(182)] java.lang.IllegalArgumentException: array == null at android.opengl.Matrix.multiplyMM(Native Method) at io.flutter.view.AccessibilityBridge$SemanticsNode.updateRecursively(Unknown Source:28) at io.flutter.view.AccessibilityBridge$SemanticsNode.updateRecursively(Unknown Source:240) at io.flutter.view.AccessibilityBridge$SemanticsNode.updateRecursively(Unknown Source:240) at io.flutter.view.AccessibilityBridge$SemanticsNode.updateRecursively(Unknown Source:240) at io.flutter.view.AccessibilityBridge$SemanticsNode.updateRecursively(Unknown Source:240) at io.flutter.view.AccessibilityBridge$SemanticsNode.access$4900(Unknown Source:0) at io.flutter.view.AccessibilityBridge.updateSemantics(Unknown Source:192) at io.flutter.view.AccessibilityBridge$1.updateSemantics(Unknown Source:21) at io.flutter.embedding.engine.FlutterJNI.updateSemantics(Unknown Source:9) at android.os.MessageQueue.nativePollOnce(Native 08-16 06:23:59.641 23012 23012 F flutter : [FATAL:flutter/shell/platform/android/platform_view_android_jni_impl.cc(1214)] Check failed: fml::jni::CheckException(env).
|
Can you add a test to test if it throw assertionError when a node has uninitialized transform, and mock the BuildConfig to test it doesn't crash? |
I'm afraid I cannot reproduce this crash, it appears just occasionally. |
Can you create test similar to ones in AccessibilityBridgeText that sends a TestSemanticsUpdate with a node that contains a child id but not part of the update, for example, you can duplicate TestSemanticsNode but in the |
|
@GuaiYiHu Did you still plan on adding a test or finding a way to repro this bug? |
|
From Triage: This looks like a benign change that seems to be hard to test and follows patterns consistent with the rest of the code. It's low risk, fixes crashes found in the wild and has an LGTM. Let's land this and file followup issues as needed. |
08-16 06:23:59.641 23012 23012 E flutter : [ERROR:flutter/fml/platform/android/jni_util.cc(182)] java.lang.IllegalArgumentException: array == null
at android.opengl.Matrix.multiplyMM(Native Method)
at io.flutter.view.AccessibilityBridge$SemanticsNode.updateRecursively(Unknown Source:28)
at io.flutter.view.AccessibilityBridge$SemanticsNode.updateRecursively(Unknown Source:240)
at io.flutter.view.AccessibilityBridge$SemanticsNode.updateRecursively(Unknown Source:240)
at io.flutter.view.AccessibilityBridge$SemanticsNode.updateRecursively(Unknown Source:240)
at io.flutter.view.AccessibilityBridge$SemanticsNode.updateRecursively(Unknown Source:240)
at io.flutter.view.AccessibilityBridge$SemanticsNode.access$4900(Unknown Source:0)
at io.flutter.view.AccessibilityBridge.updateSemantics(Unknown Source:192)
at io.flutter.view.AccessibilityBridge$1.updateSemantics(Unknown Source:21)
at io.flutter.embedding.engine.FlutterJNI.updateSemantics(Unknown Source:9)
at android.os.MessageQueue.nativePollOnce(Native
08-16 06:23:59.641 23012 23012 F flutter : [FATAL:flutter/shell/platform/android/platform_view_android_jni_impl.cc(1214)] Check failed: fml::jni::CheckException(env).
Fix array == null error
flutter/flutter#89834
flutter/flutter#31139
Pre-launch Checklist
writing and running engine tests.
///).If you need help, consider asking for advice on the #hackers-new channel on Discord.