diff --git a/engine/src/flutter/shell/platform/android/io/flutter/plugin/platform/PlatformViewsController.java b/engine/src/flutter/shell/platform/android/io/flutter/plugin/platform/PlatformViewsController.java index 1e62501a4f..7a0a09ae09 100644 --- a/engine/src/flutter/shell/platform/android/io/flutter/plugin/platform/PlatformViewsController.java +++ b/engine/src/flutter/shell/platform/android/io/flutter/plugin/platform/PlatformViewsController.java @@ -161,7 +161,7 @@ public class PlatformViewsController implements PlatformViewsAccessibilityDelega ensureValidAndroidVersion(19); ensureValidRequest(request); - final PlatformView platformView = createPlatformView(request); + final PlatformView platformView = createPlatformView(request, false); configureForHybridComposition(platformView, request); // New code should be added to configureForHybridComposition, not here, unless it is @@ -189,7 +189,7 @@ public class PlatformViewsController implements PlatformViewsAccessibilityDelega + viewId); } - final PlatformView platformView = createPlatformView(request); + final PlatformView platformView = createPlatformView(request, true); final View embeddedView = platformView.getView(); if (embeddedView.getParent() != null) { @@ -477,7 +477,8 @@ public class PlatformViewsController implements PlatformViewsAccessibilityDelega // all display modes, and adds it to `platformViews`. @TargetApi(19) private PlatformView createPlatformView( - @NonNull PlatformViewsChannel.PlatformViewCreationRequest request) { + @NonNull PlatformViewsChannel.PlatformViewCreationRequest request, + boolean wrapContext) { final PlatformViewFactory viewFactory = registry.getFactory(request.viewType); if (viewFactory == null) { throw new IllegalStateException( @@ -490,7 +491,9 @@ public class PlatformViewsController implements PlatformViewsAccessibilityDelega } // In some display modes, the context needs to be modified during display. - final Context mutableContext = new MutableContextWrapper(context); + // TODO(stuartmorgan): Make this wrapping unconditional if possible; for context see + // https://github.com/flutter/flutter/issues/113449 + final Context mutableContext = wrapContext ? new MutableContextWrapper(context) : context; final PlatformView platformView = viewFactory.create(mutableContext, request.viewId, createParams); diff --git a/engine/src/flutter/shell/platform/android/test/io/flutter/plugin/platform/PlatformViewsControllerTest.java b/engine/src/flutter/shell/platform/android/test/io/flutter/plugin/platform/PlatformViewsControllerTest.java index 824c148a70..264ec4e020 100644 --- a/engine/src/flutter/shell/platform/android/test/io/flutter/plugin/platform/PlatformViewsControllerTest.java +++ b/engine/src/flutter/shell/platform/android/test/io/flutter/plugin/platform/PlatformViewsControllerTest.java @@ -312,6 +312,55 @@ public class PlatformViewsControllerTest { verify(viewFactory, times(1)).create(any(), eq(platformViewId), any()); } + @Test + @Config(shadows = {ShadowFlutterJNI.class, ShadowPlatformTaskQueue.class}) + public void createPlatformViewMessage__wrapsContextForVirtualDisplay() { + PlatformViewsController platformViewsController = new PlatformViewsController(); + + int platformViewId = 0; + assertNull(platformViewsController.getPlatformViewById(platformViewId)); + + PlatformViewFactory viewFactory = mock(PlatformViewFactory.class); + PlatformView platformView = mock(PlatformView.class); + when(platformView.getView()).thenReturn(mock(View.class)); + ArgumentCaptor passedContext = ArgumentCaptor.forClass(Context.class); + when(viewFactory.create(passedContext.capture(), eq(platformViewId), any())) + .thenReturn(platformView); + platformViewsController.getRegistry().registerViewFactory("testType", viewFactory); + + FlutterJNI jni = new FlutterJNI(); + attach(jni, platformViewsController); + + // Simulate create call from the framework. + createPlatformView( + jni, platformViewsController, platformViewId, "testType", /* hybrid=*/ false); + assertTrue(passedContext.getValue() instanceof MutableContextWrapper); + } + + @Test + @Config(shadows = {ShadowFlutterJNI.class, ShadowPlatformTaskQueue.class}) + public void createPlatformViewMessage__doesNotWrapContextForHybrid() { + PlatformViewsController platformViewsController = new PlatformViewsController(); + + int platformViewId = 0; + assertNull(platformViewsController.getPlatformViewById(platformViewId)); + + PlatformViewFactory viewFactory = mock(PlatformViewFactory.class); + PlatformView platformView = mock(PlatformView.class); + when(platformView.getView()).thenReturn(mock(View.class)); + ArgumentCaptor passedContext = ArgumentCaptor.forClass(Context.class); + when(viewFactory.create(passedContext.capture(), eq(platformViewId), any())) + .thenReturn(platformView); + platformViewsController.getRegistry().registerViewFactory("testType", viewFactory); + + FlutterJNI jni = new FlutterJNI(); + attach(jni, platformViewsController); + + // Simulate create call from the framework. + createPlatformView(jni, platformViewsController, platformViewId, "testType", /* hybrid=*/ true); + assertFalse(passedContext.getValue() instanceof MutableContextWrapper); + } + @Test @Config(shadows = {ShadowFlutterJNI.class, ShadowPlatformTaskQueue.class}) public void createPlatformViewMessage__setsAndroidViewLayoutDirection() {