Update Surface reference after resizing render target in VirtualDisplay based platform views (#50971)
Fixes https://github.com/flutter/flutter/issues/142952
diff --git a/shell/platform/android/io/flutter/plugin/platform/VirtualDisplayController.java b/shell/platform/android/io/flutter/plugin/platform/VirtualDisplayController.java
index 1cb4437..d041382 100644
--- a/shell/platform/android/io/flutter/plugin/platform/VirtualDisplayController.java
+++ b/shell/platform/android/io/flutter/plugin/platform/VirtualDisplayController.java
@@ -19,10 +19,19 @@
import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
-@TargetApi(20)
+@TargetApi(21)
class VirtualDisplayController {
private static String TAG = "VirtualDisplayController";
+ private static VirtualDisplay.Callback callback =
+ new VirtualDisplay.Callback() {
+ @Override
+ public void onPaused() {}
+
+ @Override
+ public void onResumed() {}
+ };
+
public static VirtualDisplayController create(
Context context,
AccessibilityEventsDelegate accessibilityEventsDelegate,
@@ -40,6 +49,7 @@
DisplayManager displayManager =
(DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE);
final DisplayMetrics metrics = context.getResources().getDisplayMetrics();
+
// Virtual Display crashes for some PlatformViews if the width or height is bigger
// than the physical screen size. We have tried to clamp or scale down the size to prevent
// the crash, but both solutions lead to unwanted behavior because the
@@ -51,6 +61,7 @@
// virtual display and AndroidPlatformView widget.
// https://github.com/flutter/flutter/issues/93115
renderTarget.resize(width, height);
+ int flags = 0;
VirtualDisplay virtualDisplay =
displayManager.createVirtualDisplay(
"flutter-vd#" + viewId,
@@ -58,7 +69,9 @@
height,
metrics.densityDpi,
renderTarget.getSurface(),
- 0);
+ flags,
+ callback,
+ null /* handler */);
if (virtualDisplay == null) {
return null;
@@ -148,9 +161,17 @@
final DisplayManager displayManager =
(DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE);
renderTarget.resize(width, height);
+ int flags = 0;
virtualDisplay =
displayManager.createVirtualDisplay(
- "flutter-vd#" + viewId, width, height, densityDpi, renderTarget.getSurface(), 0);
+ "flutter-vd#" + viewId,
+ width,
+ height,
+ densityDpi,
+ renderTarget.getSurface(),
+ flags,
+ callback,
+ null /* handler */);
final View embeddedView = getView();
// There's a bug in Android version older than O where view tree observer onDrawListeners don't
@@ -210,12 +231,14 @@
renderTarget.release();
}
+ // On Android versions 31+ resizing of a Virtual Display's Presentation is natively supported.
@TargetApi(31)
private void resize31(
View embeddedView, int width, int height, final Runnable onNewSizeFrameAvailable) {
renderTarget.resize(width, height);
- // On Android versions 31+ resizing of a Virtual Display's Presentation is natively supported.
virtualDisplay.resize(width, height, densityDpi);
+ // Must update the surface to match the renderTarget's current surface.
+ virtualDisplay.setSurface(renderTarget.getSurface());
embeddedView.postDelayed(onNewSizeFrameAvailable, 0);
}