Skip to content

Commit 14549b3

Browse files
authored
make FakeView not send Scene and semantics to the engine (#138849)
`FakeView` wraps the same underlying `FlutterView`. Sending semantics updates and Scene objects from multiple fake views into the same engine `FlutterView` violates contracts with the engine. This PR stubs out `render` and `updateSemantics` methods in `FakeView` classes to prevent that. This unblocks flutter/engine#48251, which implements multi-view semantics for web.
1 parent c7d4b32 commit 14549b3

File tree

7 files changed

+76
-60
lines changed

7 files changed

+76
-60
lines changed
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// Copyright 2014 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import 'dart:ui';
6+
7+
import 'package:flutter_test/flutter_test.dart';
8+
9+
class FakeView extends TestFlutterView {
10+
FakeView(FlutterView view, { this.viewId = 100 }) : super(
11+
view: view,
12+
platformDispatcher: view.platformDispatcher as TestPlatformDispatcher,
13+
display: view.display as TestDisplay,
14+
);
15+
16+
@override
17+
final int viewId;
18+
19+
@override
20+
void render(Scene scene) {
21+
// Do not render the scene in the engine. The engine only observes one
22+
// instance of FlutterView (the _view), and it is generally expected that
23+
// the framework will render no more than one `Scene` per frame.
24+
}
25+
26+
@override
27+
void updateSemantics(SemanticsUpdate update) {
28+
// Do not send the update to the engine. The engine only observes one
29+
// instance of FlutterView (the _view). Sending semantic updates meant for
30+
// different views to the same engine view does not work as the updates do
31+
// not produce consistent semantics trees.
32+
}
33+
}

packages/flutter/test/widgets/multi_view_tree_updates_test.dart

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
44

5-
import 'dart:ui';
6-
75
import 'package:flutter/material.dart';
86
import 'package:flutter/rendering.dart';
97
import 'package:flutter_test/flutter_test.dart';
108
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
119

10+
import 'multi_view_testing.dart';
11+
1212
void main() {
1313
testWidgetsWithLeakTracking('Widgets in view update as expected', (WidgetTester tester) async {
1414
final Widget widget = View(
@@ -209,14 +209,3 @@ Future<void> pumpWidgetWithoutViewWrapper({required WidgetTester tester, require
209209
tester.binding.scheduleFrame();
210210
return tester.binding.pump();
211211
}
212-
213-
class FakeView extends TestFlutterView{
214-
FakeView(FlutterView view, { this.viewId = 100 }) : super(
215-
view: view,
216-
platformDispatcher: view.platformDispatcher as TestPlatformDispatcher,
217-
display: view.display as TestDisplay,
218-
);
219-
220-
@override
221-
final int viewId;
222-
}

packages/flutter/test/widgets/tree_shape_test.dart

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import 'package:flutter/rendering.dart';
99
import 'package:flutter_test/flutter_test.dart';
1010
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
1111

12+
import 'multi_view_testing.dart';
13+
1214
void main() {
1315
testWidgetsWithLeakTracking('Providing a RenderObjectWidget directly to the RootWidget fails', (WidgetTester tester) async {
1416
// No render tree exists to attach the RenderObjectWidget to.
@@ -1149,14 +1151,3 @@ Future<void> pumpWidgetWithoutViewWrapper({required WidgetTester tester, require
11491151
tester.binding.scheduleFrame();
11501152
return tester.binding.pump();
11511153
}
1152-
1153-
class FakeView extends TestFlutterView{
1154-
FakeView(FlutterView view, { this.viewId = 100 }) : super(
1155-
view: view,
1156-
platformDispatcher: view.platformDispatcher as TestPlatformDispatcher,
1157-
display: view.display as TestDisplay,
1158-
);
1159-
1160-
@override
1161-
final int viewId;
1162-
}

packages/flutter/test/widgets/view_test.dart

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import 'package:flutter/rendering.dart';
99
import 'package:flutter_test/flutter_test.dart';
1010
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
1111

12+
import 'multi_view_testing.dart';
13+
1214
void main() {
1315
testWidgetsWithLeakTracking('Widgets running with runApp can find View', (WidgetTester tester) async {
1416
FlutterView? viewOf;
@@ -456,17 +458,6 @@ Future<void> pumpWidgetWithoutViewWrapper({required WidgetTester tester, require
456458
return tester.binding.pump();
457459
}
458460

459-
class FakeView extends TestFlutterView{
460-
FakeView(FlutterView view, { this.viewId = 100 }) : super(
461-
view: view,
462-
platformDispatcher: view.platformDispatcher as TestPlatformDispatcher,
463-
display: view.display as TestDisplay,
464-
);
465-
466-
@override
467-
final int viewId;
468-
}
469-
470461
class SpyRenderWidget extends SizedBox {
471462
const SpyRenderWidget({super.key, required this.label, required this.log, super.child});
472463

packages/flutter_test/test/multi_view_accessibility_test.dart

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,12 @@
33
// found in the LICENSE file.
44

55
import 'dart:convert';
6-
import 'dart:ui';
76

87
import 'package:flutter/material.dart';
98
import 'package:flutter_test/flutter_test.dart';
109

10+
import 'multi_view_testing.dart';
11+
1112
void main() {
1213
testWidgets('Detects tap targets in all views', (WidgetTester tester) async {
1314
final SemanticsHandle handle = tester.ensureSemantics();
@@ -122,14 +123,3 @@ Future<void> pumpViews({required WidgetTester tester, required List<Widget> vie
122123
tester.binding.scheduleFrame();
123124
return tester.binding.pump();
124125
}
125-
126-
class FakeView extends TestFlutterView{
127-
FakeView(FlutterView view, { this.viewId = 100 }) : super(
128-
view: view,
129-
platformDispatcher: view.platformDispatcher as TestPlatformDispatcher,
130-
display: view.display as TestDisplay,
131-
);
132-
133-
@override
134-
final int viewId;
135-
}

packages/flutter_test/test/multi_view_controller_test.dart

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
44

5-
import 'dart:ui';
6-
75
import 'package:flutter/rendering.dart';
86
import 'package:flutter/widgets.dart';
97
import 'package:flutter_test/flutter_test.dart';
108

9+
import 'multi_view_testing.dart';
10+
1111
void main() {
1212
testWidgets('simulatedAccessibilityTraversal - start and end in same view', (WidgetTester tester) async {
1313
await pumpViews(tester: tester);
@@ -219,14 +219,3 @@ Future<void> pumpViews({required WidgetTester tester}) {
219219
tester.binding.scheduleFrame();
220220
return tester.binding.pump();
221221
}
222-
223-
class FakeView extends TestFlutterView{
224-
FakeView(FlutterView view, { this.viewId = 100 }) : super(
225-
view: view,
226-
platformDispatcher: view.platformDispatcher as TestPlatformDispatcher,
227-
display: view.display as TestDisplay,
228-
);
229-
230-
@override
231-
final int viewId;
232-
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// Copyright 2014 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import 'dart:ui';
6+
7+
import 'package:flutter_test/flutter_test.dart';
8+
9+
class FakeView extends TestFlutterView {
10+
FakeView(FlutterView view, { this.viewId = 100 }) : super(
11+
view: view,
12+
platformDispatcher: view.platformDispatcher as TestPlatformDispatcher,
13+
display: view.display as TestDisplay,
14+
);
15+
16+
@override
17+
final int viewId;
18+
19+
@override
20+
void render(Scene scene) {
21+
// Do not render the scene in the engine. The engine only observes one
22+
// instance of FlutterView (the _view), and it is generally expected that
23+
// the framework will render no more than one `Scene` per frame.
24+
}
25+
26+
@override
27+
void updateSemantics(SemanticsUpdate update) {
28+
// Do not send the update to the engine. The engine only observes one
29+
// instance of FlutterView (the _view). Sending semantic updates meant for
30+
// different views to the same engine view does not work as the updates do
31+
// not produce consistent semantics trees.
32+
}
33+
}

0 commit comments

Comments
 (0)