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 https://github.com/flutter/engine/pull/48251, which implements multi-view semantics for web.
This commit is contained in:
Yegor 2023-11-22 12:48:20 -08:00 committed by GitHub
parent c7d4b32fdd
commit 14549b3889
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 76 additions and 60 deletions

View File

@ -0,0 +1,33 @@
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:ui';
import 'package:flutter_test/flutter_test.dart';
class FakeView extends TestFlutterView {
FakeView(FlutterView view, { this.viewId = 100 }) : super(
view: view,
platformDispatcher: view.platformDispatcher as TestPlatformDispatcher,
display: view.display as TestDisplay,
);
@override
final int viewId;
@override
void render(Scene scene) {
// Do not render the scene in the engine. The engine only observes one
// instance of FlutterView (the _view), and it is generally expected that
// the framework will render no more than one `Scene` per frame.
}
@override
void updateSemantics(SemanticsUpdate update) {
// Do not send the update to the engine. The engine only observes one
// instance of FlutterView (the _view). Sending semantic updates meant for
// different views to the same engine view does not work as the updates do
// not produce consistent semantics trees.
}
}

View File

@ -2,13 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import 'multi_view_testing.dart';
void main() {
testWidgetsWithLeakTracking('Widgets in view update as expected', (WidgetTester tester) async {
final Widget widget = View(
@ -209,14 +209,3 @@ Future<void> pumpWidgetWithoutViewWrapper({required WidgetTester tester, require
tester.binding.scheduleFrame();
return tester.binding.pump();
}
class FakeView extends TestFlutterView{
FakeView(FlutterView view, { this.viewId = 100 }) : super(
view: view,
platformDispatcher: view.platformDispatcher as TestPlatformDispatcher,
display: view.display as TestDisplay,
);
@override
final int viewId;
}

View File

@ -9,6 +9,8 @@ import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import 'multi_view_testing.dart';
void main() {
testWidgetsWithLeakTracking('Providing a RenderObjectWidget directly to the RootWidget fails', (WidgetTester tester) async {
// No render tree exists to attach the RenderObjectWidget to.
@ -1149,14 +1151,3 @@ Future<void> pumpWidgetWithoutViewWrapper({required WidgetTester tester, require
tester.binding.scheduleFrame();
return tester.binding.pump();
}
class FakeView extends TestFlutterView{
FakeView(FlutterView view, { this.viewId = 100 }) : super(
view: view,
platformDispatcher: view.platformDispatcher as TestPlatformDispatcher,
display: view.display as TestDisplay,
);
@override
final int viewId;
}

View File

@ -9,6 +9,8 @@ import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import 'multi_view_testing.dart';
void main() {
testWidgetsWithLeakTracking('Widgets running with runApp can find View', (WidgetTester tester) async {
FlutterView? viewOf;
@ -456,17 +458,6 @@ Future<void> pumpWidgetWithoutViewWrapper({required WidgetTester tester, require
return tester.binding.pump();
}
class FakeView extends TestFlutterView{
FakeView(FlutterView view, { this.viewId = 100 }) : super(
view: view,
platformDispatcher: view.platformDispatcher as TestPlatformDispatcher,
display: view.display as TestDisplay,
);
@override
final int viewId;
}
class SpyRenderWidget extends SizedBox {
const SpyRenderWidget({super.key, required this.label, required this.log, super.child});

View File

@ -3,11 +3,12 @@
// found in the LICENSE file.
import 'dart:convert';
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'multi_view_testing.dart';
void main() {
testWidgets('Detects tap targets in all views', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics();
@ -122,14 +123,3 @@ Future<void> pumpViews({required WidgetTester tester, required List<Widget> vie
tester.binding.scheduleFrame();
return tester.binding.pump();
}
class FakeView extends TestFlutterView{
FakeView(FlutterView view, { this.viewId = 100 }) : super(
view: view,
platformDispatcher: view.platformDispatcher as TestPlatformDispatcher,
display: view.display as TestDisplay,
);
@override
final int viewId;
}

View File

@ -2,12 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:ui';
import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart';
import 'multi_view_testing.dart';
void main() {
testWidgets('simulatedAccessibilityTraversal - start and end in same view', (WidgetTester tester) async {
await pumpViews(tester: tester);
@ -219,14 +219,3 @@ Future<void> pumpViews({required WidgetTester tester}) {
tester.binding.scheduleFrame();
return tester.binding.pump();
}
class FakeView extends TestFlutterView{
FakeView(FlutterView view, { this.viewId = 100 }) : super(
view: view,
platformDispatcher: view.platformDispatcher as TestPlatformDispatcher,
display: view.display as TestDisplay,
);
@override
final int viewId;
}

View File

@ -0,0 +1,33 @@
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:ui';
import 'package:flutter_test/flutter_test.dart';
class FakeView extends TestFlutterView {
FakeView(FlutterView view, { this.viewId = 100 }) : super(
view: view,
platformDispatcher: view.platformDispatcher as TestPlatformDispatcher,
display: view.display as TestDisplay,
);
@override
final int viewId;
@override
void render(Scene scene) {
// Do not render the scene in the engine. The engine only observes one
// instance of FlutterView (the _view), and it is generally expected that
// the framework will render no more than one `Scene` per frame.
}
@override
void updateSemantics(SemanticsUpdate update) {
// Do not send the update to the engine. The engine only observes one
// instance of FlutterView (the _view). Sending semantic updates meant for
// different views to the same engine view does not work as the updates do
// not produce consistent semantics trees.
}
}