From 2b66f64511df7de1404802aab5ccbdbb8587244e Mon Sep 17 00:00:00 2001 From: Simon Lightfoot Date: Fri, 21 Jun 2019 00:46:26 +0100 Subject: [PATCH] Avoid a full screen overlay within virtual displays (flutter/engine#9343) Add views that are added directly to a platform view's window as siblings to the platform view's container view, rather than as children of a full screen container. This prevents a false-negative for a visibility check from a specific ads SDK (Teads), which [reported the following warning](https://github.com/flutter/flutter/issues/12114#issuecomment-500906158): ``` W/teads#Visibility(17978): The Teads AdView is visible at 0%, hidded by 1 View(s): W/teads#Visibility(17978): - View of class io.flutter.plugin.platform.SingleViewPresentation$FakeWindowViewGroup, with id: -1, with contentDescription: null, with a size of: [width: 1050, height: 875] is hidding 100% of the ad ``` --- .../platform/SingleViewPresentation.java | 39 +++++++++++-------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/engine/src/flutter/shell/platform/android/io/flutter/plugin/platform/SingleViewPresentation.java b/engine/src/flutter/shell/platform/android/io/flutter/plugin/platform/SingleViewPresentation.java index 7acd66b3b4..b41d9c3a2b 100644 --- a/engine/src/flutter/shell/platform/android/io/flutter/plugin/platform/SingleViewPresentation.java +++ b/engine/src/flutter/shell/platform/android/io/flutter/plugin/platform/SingleViewPresentation.java @@ -29,13 +29,13 @@ import static android.view.View.OnFocusChangeListener; * * The view hierarchy for the presentation is as following: * - * rootView - * / \ - * / \ - * / \ - * container state.fakeWindowViewGroup - * | - * EmbeddedView + * rootView + * | + * state.fakeWindowViewGroup + * / \ + * state.container [other popup views] + * | + * EmbeddedView */ @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) class SingleViewPresentation extends Presentation { @@ -55,6 +55,9 @@ class SingleViewPresentation extends Presentation { // Contains views that were added directly to the window manager (e.g android.widget.PopupWindow). private FakeWindowViewGroup fakeWindowViewGroup; + + // Contains the embedded platform view (platformView.getView()) when it is attached to the presentation. + private FrameLayout container; } private final PlatformViewFactory viewFactory; @@ -72,13 +75,13 @@ class SingleViewPresentation extends Presentation { // so when we create the platform view we can tell it its view id. private Object createParams; - // The root view for the presentation, it has 2 childs: container which contains the embedded view, and - // fakeWindowViewGroup which contains views that were added directly to the presentation's window manager. + // The root view for the presentation, it has a single child called fakeWindowViewGroup which contains + // views that were added directly to the presentation's window manager. fakeWindowViewGroup's first + // child is the state.container which contains the embedded view. So all other views are drawn on-top but + // the embedded view itself is not obscured directly by the fakeWindowViewGroup. + // private AccessibilityDelegatingFrameLayout rootView; - // Contains the embedded platform view (platformView.getView()) when it is attached to the presentation. - private FrameLayout container; - private PresentationState state; private boolean startFocused = false; @@ -142,12 +145,17 @@ class SingleViewPresentation extends Presentation { if (state.fakeWindowViewGroup == null) { state.fakeWindowViewGroup = new FakeWindowViewGroup(getContext()); } + if (state.container == null) { + state.container = new FrameLayout(getContext()); + final WindowManager.LayoutParams params = new WindowManager.LayoutParams(); + params.gravity = Gravity.FILL; + state.fakeWindowViewGroup.addView(state.container, params); + } if (state.windowManagerHandler == null) { WindowManager windowManagerDelegate = (WindowManager) getContext().getSystemService(WINDOW_SERVICE); state.windowManagerHandler = new WindowManagerHandler(windowManagerDelegate, state.fakeWindowViewGroup); } - container = new FrameLayout(getContext()); PresentationContext context = new PresentationContext(getContext(), state.windowManagerHandler); if (state.platformView == null) { @@ -155,9 +163,8 @@ class SingleViewPresentation extends Presentation { } View embeddedView = state.platformView.getView(); - container.addView(embeddedView); + state.container.addView(embeddedView); rootView = new AccessibilityDelegatingFrameLayout(getContext(), accessibilityEventsDelegate, embeddedView); - rootView.addView(container); rootView.addView(state.fakeWindowViewGroup); embeddedView.setOnFocusChangeListener(focusChangeListener); @@ -171,7 +178,7 @@ class SingleViewPresentation extends Presentation { } public PresentationState detachState() { - container.removeAllViews(); + state.container.removeAllViews(); rootView.removeAllViews(); return state; }