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

Commit 557f3e6

Browse files
author
Emmanuel Garcia
committed
Fix memory leak in PlatformViewsController
1 parent 08cec9e commit 557f3e6

2 files changed

Lines changed: 55 additions & 1 deletion

File tree

shell/platform/android/io/flutter/plugin/platform/PlatformViewsController.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ public class PlatformViewsController implements PlatformViewsAccessibilityDelega
7979
// Since each virtual display has it's unique context this allows associating any view with the
8080
// platform view that
8181
// it is associated with(e.g if a platform view creates other views in the same virtual display.
82-
private final HashMap<Context, View> contextToPlatformView;
82+
@VisibleForTesting /* package */ final HashMap<Context, View> contextToPlatformView;
8383

8484
// The views returned by `PlatformView#getView()`.
8585
//
@@ -711,6 +711,10 @@ private void flushAllViews() {
711711
while (platformViews.size() > 0) {
712712
channelHandler.disposeAndroidViewForPlatformView(platformViews.keyAt(0));
713713
}
714+
715+
if (contextToPlatformView.size() > 0) {
716+
contextToPlatformView.clear();
717+
}
714718
}
715719

716720
private void initializeRootImageViewIfNeeded() {

shell/platform/android/test/io/flutter/plugin/platform/PlatformViewsControllerTest.java

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,56 @@ public void createPlatformViewMessage__throwsIfViewIsNull() {
291291
});
292292
}
293293

294+
@Test
295+
@Config(shadows = {ShadowFlutterJNI.class})
296+
public void onDetachedFromJNI_clearsPlatformViewContext() {
297+
PlatformViewsController platformViewsController = new PlatformViewsController();
298+
299+
int platformViewId = 0;
300+
assertNull(platformViewsController.getPlatformViewById(platformViewId));
301+
302+
PlatformViewFactory viewFactory = mock(PlatformViewFactory.class);
303+
PlatformView platformView = mock(PlatformView.class);
304+
when(platformView.getView()).thenReturn(null);
305+
when(viewFactory.create(any(), eq(platformViewId), any())).thenReturn(platformView);
306+
platformViewsController.getRegistry().registerViewFactory("testType", viewFactory);
307+
308+
FlutterJNI jni = new FlutterJNI();
309+
attach(jni, platformViewsController);
310+
311+
// Simulate create call from the framework.
312+
createPlatformView(jni, platformViewsController, platformViewId, "testType");
313+
314+
assertFalse(platformViewsController.contextToPlatformView.isEmpty());
315+
platformViewsController.onDetachedFromJNI();
316+
assertTrue(platformViewsController.contextToPlatformView.isEmpty());
317+
}
318+
319+
@Test
320+
@Config(shadows = {ShadowFlutterJNI.class})
321+
public void onPreEngineRestart_clearsPlatformViewContext() {
322+
PlatformViewsController platformViewsController = new PlatformViewsController();
323+
324+
int platformViewId = 0;
325+
assertNull(platformViewsController.getPlatformViewById(platformViewId));
326+
327+
PlatformViewFactory viewFactory = mock(PlatformViewFactory.class);
328+
PlatformView platformView = mock(PlatformView.class);
329+
when(platformView.getView()).thenReturn(null);
330+
when(viewFactory.create(any(), eq(platformViewId), any())).thenReturn(platformView);
331+
platformViewsController.getRegistry().registerViewFactory("testType", viewFactory);
332+
333+
FlutterJNI jni = new FlutterJNI();
334+
attach(jni, platformViewsController);
335+
336+
// Simulate create call from the framework.
337+
createPlatformView(jni, platformViewsController, platformViewId, "testType");
338+
339+
assertFalse(platformViewsController.contextToPlatformView.isEmpty());
340+
platformViewsController.onDetachedFromJNI();
341+
assertTrue(platformViewsController.contextToPlatformView.isEmpty());
342+
}
343+
294344
@Test
295345
@Config(shadows = {ShadowFlutterJNI.class})
296346
public void createPlatformViewMessage__throwsIfViewHasParent() {

0 commit comments

Comments
 (0)