Unverified Commit c7498f60 authored by Michael Goderbauer's avatar Michael Goderbauer Committed by GitHub

Improve dumpSemanticsTree error when semantics are unavailable (#108574)

parent 5da997e6
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
import 'package:flutter/gestures.dart' show DragStartBehavior; import 'package:flutter/gestures.dart' show DragStartBehavior;
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart' show DebugSemanticsDumpOrder, debugDumpLayerTree, debugDumpRenderTree, debugDumpSemanticsTree; import 'package:flutter/rendering.dart' show debugDumpLayerTree, debugDumpRenderTree, debugDumpSemanticsTree;
import 'package:flutter/scheduler.dart' show timeDilation; import 'package:flutter/scheduler.dart' show timeDilation;
import 'i18n/stock_strings.dart'; import 'i18n/stock_strings.dart';
...@@ -136,7 +136,7 @@ class StockHomeState extends State<StockHome> { ...@@ -136,7 +136,7 @@ class StockHomeState extends State<StockHome> {
debugDumpApp(); debugDumpApp();
debugDumpRenderTree(); debugDumpRenderTree();
debugDumpLayerTree(); debugDumpLayerTree();
debugDumpSemanticsTree(DebugSemanticsDumpOrder.traversalOrder); debugDumpSemanticsTree();
} catch (e, stack) { } catch (e, stack) {
debugPrint('Exception while dumping app:\n$e\n$stack'); debugPrint('Exception while dumping app:\n$e\n$stack');
} }
......
...@@ -166,20 +166,16 @@ mixin RendererBinding on BindingBase, ServicesBinding, SchedulerBinding, Gesture ...@@ -166,20 +166,16 @@ mixin RendererBinding on BindingBase, ServicesBinding, SchedulerBinding, Gesture
registerServiceExtension( registerServiceExtension(
name: 'debugDumpSemanticsTreeInTraversalOrder', name: 'debugDumpSemanticsTreeInTraversalOrder',
callback: (Map<String, String> parameters) async { callback: (Map<String, String> parameters) async {
final String data = RendererBinding.instance.renderView.debugSemantics
?.toStringDeep() ?? 'Semantics not collected.';
return <String, Object>{ return <String, Object>{
'data': data, 'data': _generateSemanticsTree(DebugSemanticsDumpOrder.traversalOrder),
}; };
}, },
); );
registerServiceExtension( registerServiceExtension(
name: 'debugDumpSemanticsTreeInInverseHitTestOrder', name: 'debugDumpSemanticsTreeInInverseHitTestOrder',
callback: (Map<String, String> parameters) async { callback: (Map<String, String> parameters) async {
final String data = RendererBinding.instance.renderView.debugSemantics
?.toStringDeep(childOrder: DebugSemanticsDumpOrder.inverseHitTest) ?? 'Semantics not collected.';
return <String, Object>{ return <String, Object>{
'data': data, 'data': _generateSemanticsTree(DebugSemanticsDumpOrder.inverseHitTest),
}; };
}, },
); );
...@@ -575,8 +571,19 @@ void debugDumpLayerTree() { ...@@ -575,8 +571,19 @@ void debugDumpLayerTree() {
/// ///
/// The order in which the children of a [SemanticsNode] will be printed is /// The order in which the children of a [SemanticsNode] will be printed is
/// controlled by the [childOrder] parameter. /// controlled by the [childOrder] parameter.
void debugDumpSemanticsTree(DebugSemanticsDumpOrder childOrder) { void debugDumpSemanticsTree([DebugSemanticsDumpOrder childOrder = DebugSemanticsDumpOrder.traversalOrder]) {
debugPrint(RendererBinding.instance.renderView.debugSemantics?.toStringDeep(childOrder: childOrder) ?? 'Semantics not collected.'); debugPrint(_generateSemanticsTree(childOrder));
}
String _generateSemanticsTree(DebugSemanticsDumpOrder childOrder) {
final String? tree = RendererBinding.instance.renderView.debugSemantics?.toStringDeep(childOrder: childOrder);
if (tree != null) {
return tree;
}
return 'Semantics not generated.\n'
'For performance reasons, the framework only generates semantics when asked to do so by the platform.\n'
'Usually, platforms only ask for semantics when assistive technologies (like screen readers) are running.\n'
'To generate semantics, try turning on an assistive technology (like VoiceOver or TalkBack) on your device.';
} }
/// A concrete binding for applications that use the Rendering framework /// A concrete binding for applications that use the Rendering framework
......
...@@ -262,7 +262,10 @@ void main() { ...@@ -262,7 +262,10 @@ void main() {
final Map<String, dynamic> result = await binding.testExtension('debugDumpSemanticsTreeInTraversalOrder', <String, String>{}); final Map<String, dynamic> result = await binding.testExtension('debugDumpSemanticsTreeInTraversalOrder', <String, String>{});
expect(result, <String, String>{ expect(result, <String, String>{
'data': 'Semantics not collected.', 'data': 'Semantics not generated.\n'
'For performance reasons, the framework only generates semantics when asked to do so by the platform.\n'
'Usually, platforms only ask for semantics when assistive technologies (like screen readers) are running.\n'
'To generate semantics, try turning on an assistive technology (like VoiceOver or TalkBack) on your device.'
}); });
}); });
...@@ -271,7 +274,10 @@ void main() { ...@@ -271,7 +274,10 @@ void main() {
final Map<String, dynamic> result = await binding.testExtension('debugDumpSemanticsTreeInInverseHitTestOrder', <String, String>{}); final Map<String, dynamic> result = await binding.testExtension('debugDumpSemanticsTreeInInverseHitTestOrder', <String, String>{});
expect(result, <String, String>{ expect(result, <String, String>{
'data': 'Semantics not collected.', 'data': 'Semantics not generated.\n'
'For performance reasons, the framework only generates semantics when asked to do so by the platform.\n'
'Usually, platforms only ask for semantics when assistive technologies (like screen readers) are running.\n'
'To generate semantics, try turning on an assistive technology (like VoiceOver or TalkBack) on your device.'
}); });
}); });
......
...@@ -19,4 +19,20 @@ void main() { ...@@ -19,4 +19,20 @@ void main() {
RendererBinding.instance.handleMetricsChanged(); RendererBinding.instance.handleMetricsChanged();
expect(SchedulerBinding.instance.hasScheduledFrame, true); expect(SchedulerBinding.instance.hasScheduledFrame, true);
}); });
test('debugDumpSemantics prints explanation when semantics are unavailable', () {
final List<String?> log = <String?>[];
debugPrint = (String? message, {int? wrapWidth}) {
log.add(message);
};
debugDumpSemanticsTree();
expect(log, hasLength(1));
expect(
log.single,
'Semantics not generated.\n'
'For performance reasons, the framework only generates semantics when asked to do so by the platform.\n'
'Usually, platforms only ask for semantics when assistive technologies (like screen readers) are running.\n'
'To generate semantics, try turning on an assistive technology (like VoiceOver or TalkBack) on your device.'
);
});
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment