5151public class PlatformViewsController implements PlatformViewsAccessibilityDelegate {
5252 private static final String TAG = "PlatformViewsController" ;
5353
54- // These view types allow to issue drawing commands directly without
55- // notifying the Android view hierarchy that a change was made .
54+ // These view types allow out-of-band drawing operation that don't notify the Android view
55+ // hierarchy.
5656 // To support these cases, Flutter hosts the embedded view in a VirtualDisplay,
5757 // and binds the VirtualDisplay to a GL texture that is then composed by the engine.
5858 // Related issue: https://github.com/flutter/flutter/issues/103630
@@ -238,8 +238,15 @@ public long createForTextureLayer(
238238
239239 final int physicalWidth = toPhysicalPixels (request .logicalWidth );
240240 final int physicalHeight = toPhysicalPixels (request .logicalHeight );
241+
242+ // Case 1. Add the view to a virtual display if the embedded view contains any of the
243+ // VIEW_TYPES_REQUIRE_VD view types.
244+ // These views allow out-of-band graphics operations that aren't notified to the Android
245+ // view hierarchy via callbacks such as ViewParent#onDescendantInvalidated().
246+ // The virtual display is wired up to a GL texture that is composed by the Flutter engine.
241247 final boolean shouldUseVirtualDisplay =
242248 ViewUtils .hasChildViewOfType (embeddedView , VIEW_TYPES_REQUIRE_VD );
249+
243250 if (!usesSoftwareRendering && shouldUseVirtualDisplay ) {
244251 Log .i (TAG , "Hosting view in a virtual display for platform view: " + viewId );
245252 // API level 20 is required to use VirtualDisplay#setSurface.
@@ -281,43 +288,42 @@ public long createForTextureLayer(
281288 return textureEntry .id ();
282289 }
283290
291+ // Case 2. Attach the view to the Android view hierarchy and record their drawing
292+ // operations, so they can be forwarded to a GL texture that is composed by the
293+ // Flutter engine.
294+
284295 // API level 23 is required to use Surface#lockHardwareCanvas().
285296 ensureValidAndroidVersion (23 );
286297 Log .i (TAG , "Hosting view in view hierarchy for platform view: " + viewId );
287298
288- PlatformViewWrapper wrapperView ;
299+ PlatformViewWrapper viewWrapper ;
289300 long txId ;
290301 if (usesSoftwareRendering ) {
291- wrapperView = new PlatformViewWrapper (context );
302+ viewWrapper = new PlatformViewWrapper (context );
292303 txId = -1 ;
293304 } else {
294305 final TextureRegistry .SurfaceTextureEntry textureEntry =
295306 textureRegistry .createSurfaceTexture ();
296- wrapperView = new PlatformViewWrapper (context , textureEntry );
307+ viewWrapper = new PlatformViewWrapper (context , textureEntry );
297308 txId = textureEntry .id ();
298309 }
299- wrapperView .setTouchProcessor (androidTouchProcessor );
300- wrapperView .setBufferSize (physicalWidth , physicalHeight );
310+ viewWrapper .setTouchProcessor (androidTouchProcessor );
311+ viewWrapper .setBufferSize (physicalWidth , physicalHeight );
301312
302- final FrameLayout .LayoutParams layoutParams =
313+ final FrameLayout .LayoutParams viewWrapperLayoutParams =
303314 new FrameLayout .LayoutParams (physicalWidth , physicalHeight );
304315
316+ // Size and position the view wrapper.
305317 final int physicalTop = toPhysicalPixels (request .logicalTop );
306318 final int physicalLeft = toPhysicalPixels (request .logicalLeft );
307- layoutParams .topMargin = physicalTop ;
308- layoutParams .leftMargin = physicalLeft ;
309- wrapperView .setLayoutParams (layoutParams );
319+ viewWrapperLayoutParams .topMargin = physicalTop ;
320+ viewWrapperLayoutParams .leftMargin = physicalLeft ;
321+ viewWrapper .setLayoutParams (viewWrapperLayoutParams );
310322
311- final View embeddedView = platformView .getView ();
312- if (embeddedView == null ) {
313- throw new IllegalStateException (
314- "PlatformView#getView() returned null, but an Android view reference was expected." );
315- } else if (embeddedView .getParent () != null ) {
316- throw new IllegalStateException (
317- "The Android view returned from PlatformView#getView() was already added to a parent view." );
318- }
323+ // Size the embedded view.
324+ // This isn't needed when the virtual display is used because the virtual display itself
325+ // is sized.
319326 embeddedView .setLayoutParams (new FrameLayout .LayoutParams (physicalWidth , physicalHeight ));
320- embeddedView .setLayoutDirection (request .direction );
321327
322328 // Accessibility in the embedded view is initially disabled because if a Flutter app
323329 // disabled accessibility in the first frame, the embedding won't receive an update to
@@ -329,17 +335,21 @@ public long createForTextureLayer(
329335 embeddedView .setImportantForAccessibility (
330336 View .IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS );
331337
332- wrapperView .addView (embeddedView );
333- wrapperView .setOnDescendantFocusChangeListener (
338+ // Add the embedded view to the wrapper.
339+ viewWrapper .addView (embeddedView );
340+
341+ // Listen for focus changed in any subview, so the framework is notified when the platform
342+ // view is focused.
343+ viewWrapper .setOnDescendantFocusChangeListener (
334344 (v , hasFocus ) -> {
335345 if (hasFocus ) {
336346 platformViewsChannel .invokeViewFocused (viewId );
337347 } else if (textInputPlugin != null ) {
338348 textInputPlugin .clearPlatformViewClient (viewId );
339349 }
340350 });
341- flutterView .addView (wrapperView );
342- viewWrappers .append (viewId , wrapperView );
351+ flutterView .addView (viewWrapper );
352+ viewWrappers .append (viewId , viewWrapper );
343353 return txId ;
344354 }
345355
@@ -404,18 +414,18 @@ public void offset(int viewId, double top, double left) {
404414 // texture
405415 // is positioned by the Flutter engine, which knows where to position different types of
406416 // layers.
407- final PlatformViewWrapper wrapper = viewWrappers .get (viewId );
408- if (wrapper == null ) {
417+ final PlatformViewWrapper viewWrapper = viewWrappers .get (viewId );
418+ if (viewWrapper == null ) {
409419 Log .e (TAG , "Setting offset for unknown platform view with id: " + viewId );
410420 return ;
411421 }
412422 final int physicalTop = toPhysicalPixels (top );
413423 final int physicalLeft = toPhysicalPixels (left );
414424 final FrameLayout .LayoutParams layoutParams =
415- (FrameLayout .LayoutParams ) wrapper .getLayoutParams ();
425+ (FrameLayout .LayoutParams ) viewWrapper .getLayoutParams ();
416426 layoutParams .topMargin = physicalTop ;
417427 layoutParams .leftMargin = physicalLeft ;
418- wrapper .setLayoutParams (layoutParams );
428+ viewWrapper .setLayoutParams (layoutParams );
419429 }
420430
421431 @ Override
@@ -446,8 +456,8 @@ public void resize(
446456 }
447457
448458 final PlatformView platformView = platformViews .get (viewId );
449- final PlatformViewWrapper view = viewWrappers .get (viewId );
450- if (platformView == null || view == null ) {
459+ final PlatformViewWrapper viewWrapper = viewWrappers .get (viewId );
460+ if (platformView == null || viewWrapper == null ) {
451461 Log .e (TAG , "Resizing unknown platform view with id: " + viewId );
452462 return ;
453463 }
@@ -459,20 +469,21 @@ public void resize(
459469 // Resizing the texture causes pixel stretching since the size of the GL texture used in
460470 // the engine
461471 // is set by the framework, but the texture buffer size is set by the platform down below.
462- if (physicalWidth > view .getBufferWidth () || physicalHeight > view .getBufferHeight ()) {
463- view .setBufferSize (physicalWidth , physicalHeight );
472+ if (physicalWidth > viewWrapper .getBufferWidth ()
473+ || physicalHeight > viewWrapper .getBufferHeight ()) {
474+ viewWrapper .setBufferSize (physicalWidth , physicalHeight );
464475 }
465476
466- final ViewGroup .LayoutParams viewWrapperLayoutParams = view .getLayoutParams ();
467- viewWrapperLayoutParams .width = newWidth ;
468- viewWrapperLayoutParams .height = newHeight ;
469- view .setLayoutParams (viewWrapperLayoutParams );
477+ final ViewGroup .LayoutParams viewWrapperLayoutParams = viewWrapper .getLayoutParams ();
478+ viewWrapperLayoutParams .width = physicalWidth ;
479+ viewWrapperLayoutParams .height = physicalHeight ;
480+ viewWrapper .setLayoutParams (viewWrapperLayoutParams );
470481
471482 final View embeddedView = platformView .getView ();
472483 if (embeddedView != null ) {
473484 final ViewGroup .LayoutParams embeddedViewLayoutParams = embeddedView .getLayoutParams ();
474- embeddedViewLayoutParams .width = newWidth ;
475- embeddedViewLayoutParams .height = newHeight ;
485+ embeddedViewLayoutParams .width = physicalWidth ;
486+ embeddedViewLayoutParams .height = physicalHeight ;
476487 embeddedView .setLayoutParams (embeddedViewLayoutParams );
477488 }
478489 onComplete .run (
@@ -520,12 +531,12 @@ public void setDirection(int viewId, int direction) {
520531 Log .e (TAG , "Setting direction to an unknown view with id: " + viewId );
521532 return ;
522533 }
523- final View view = platformView .getView ();
524- if (view == null ) {
534+ final View embeddedView = platformView .getView ();
535+ if (embeddedView == null ) {
525536 Log .e (TAG , "Setting direction to a null view with id: " + viewId );
526537 return ;
527538 }
528- view .setLayoutDirection (direction );
539+ embeddedView .setLayoutDirection (direction );
529540 }
530541
531542 @ Override
@@ -535,12 +546,12 @@ public void clearFocus(int viewId) {
535546 Log .e (TAG , "Clearing focus on an unknown view with id: " + viewId );
536547 return ;
537548 }
538- final View view = platformView .getView ();
539- if (view == null ) {
549+ final View embeddedView = platformView .getView ();
550+ if (embeddedView == null ) {
540551 Log .e (TAG , "Clearing focus on a null view with id: " + viewId );
541552 return ;
542553 }
543- view .clearFocus ();
554+ embeddedView .clearFocus ();
544555 }
545556
546557 private void ensureValidAndroidVersion (int minSdkVersion ) {
0 commit comments