Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 70039d3

Browse files
authored
[web] Do not wipe the PlatformViewManager when disposing of a view. (#49991)
When a view gets disposed of, its rasterizer completely clears up the singleton `PlatformViewManager`. Particularly, it removes all registered platform view factories. This is wrong because the remaining PlatformViews on the page cannot be re-rendered, and the default Platform View factories (used by `pointer_interceptor`, for example), disappear. This PR attempts to preserve the `dispose` logic of the canvaskit rasterizer, without using the `debugClear` method of the `PlatformViewManager` (which is supposedly test-only). ## Issues * Fixes flutter/flutter#142094 ## Tests * Added unit-test * Deployed demo app: https://dit-maps-tests.web.app [C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
1 parent 182b595 commit 70039d3

File tree

3 files changed

+29
-11
lines changed

3 files changed

+29
-11
lines changed

lib/web_ui/lib/src/engine/canvaskit/embedded_views.dart

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -410,8 +410,7 @@ class HtmlViewEmbedder {
410410
// are going to be added back. Moving rather than removing and re-adding
411411
// the view helps it maintain state.
412412
disposeViews(diffResult.viewsToRemove
413-
.where((int view) => !diffResult.viewsToAdd.contains(view))
414-
.toSet());
413+
.where((int view) => !diffResult.viewsToAdd.contains(view)));
415414
_activeCompositionOrder.addAll(_compositionOrder);
416415
unusedViews.removeAll(_compositionOrder);
417416

@@ -510,7 +509,7 @@ class HtmlViewEmbedder {
510509
);
511510
}
512511

513-
void disposeViews(Set<int> viewsToDispose) {
512+
void disposeViews(Iterable<int> viewsToDispose) {
514513
for (final int viewId in viewsToDispose) {
515514
// Remove viewId from the _viewClipChains Map, and then from the DOM.
516515
final ViewClipChain? clipChain = _viewClipChains.remove(viewId);
@@ -659,8 +658,7 @@ class HtmlViewEmbedder {
659658

660659
/// Disposes the state of this view embedder.
661660
void dispose() {
662-
final Set<int> allViews = PlatformViewManager.instance.debugClear();
663-
disposeViews(allViews);
661+
disposeViews(_viewClipChains.keys);
664662
_context = EmbedderFrameContext();
665663
_currentCompositionParams.clear();
666664
debugCleanupSvgClipPaths();

lib/web_ui/lib/src/engine/platform_views/content_manager.dart

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -213,16 +213,12 @@ class PlatformViewManager {
213213
bool isVisible(int viewId) => !isInvisible(viewId);
214214

215215
/// Clears the state. Used in tests.
216-
///
217-
/// Returns the set of know view ids, so they can be cleaned up.
218-
Set<int> debugClear() {
219-
final Set<int> result = _contents.keys.toSet();
220-
result.forEach(clearPlatformView);
216+
void debugClear() {
217+
_contents.keys.toList().forEach(clearPlatformView);
221218
_factories.clear();
222219
_contents.clear();
223220
_invisibleViews.clear();
224221
_viewIdToType.clear();
225-
return result;
226222
}
227223
}
228224

lib/web_ui/test/canvaskit/multi_view_test.dart

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import 'package:test/bootstrap/browser.dart';
66
import 'package:test/test.dart';
77
import 'package:ui/src/engine.dart';
88
import 'package:ui/ui.dart' as ui;
9+
import 'package:ui/ui_web/src/ui_web.dart' as ui_web;
910

1011
import '../common/matchers.dart';
1112
import 'common.dart';
@@ -68,5 +69,28 @@ void testMain() {
6869
isNull,
6970
);
7071
});
72+
73+
// Issue https://github.com/flutter/flutter/issues/142094
74+
test('does not reset platform view factories when disposing a view', () async {
75+
expect(PlatformViewManager.instance.knowsViewType('self-test'), isFalse);
76+
77+
final EngineFlutterView view = EngineFlutterView(
78+
EnginePlatformDispatcher.instance, createDomElement('multi-view'));
79+
EnginePlatformDispatcher.instance.viewManager.registerView(view);
80+
expect(
81+
CanvasKitRenderer.instance.debugGetRasterizerForView(view),
82+
isNotNull,
83+
);
84+
85+
EnginePlatformDispatcher.instance.viewManager
86+
.disposeAndUnregisterView(view.viewId);
87+
expect(
88+
CanvasKitRenderer.instance.debugGetRasterizerForView(view),
89+
isNull,
90+
);
91+
92+
expect(PlatformViewManager.instance.knowsViewType(ui_web.PlatformViewRegistry.defaultVisibleViewType), isTrue);
93+
expect(PlatformViewManager.instance.knowsViewType(ui_web.PlatformViewRegistry.defaultInvisibleViewType), isTrue);
94+
});
7195
});
7296
}

0 commit comments

Comments
 (0)