[flexiglass] Make the window-view full-screen.
Before this CL, the window-view for the scene container (our root view) was not full-screen; it was getting cut off by the top and bottom window insets (status bar and nav bar). With this CL, that's no longer the case and Flexiglass is now full-screen behind the status bar and nav bar. The approach was to identify the pieces of the legacy NotificationShadeWindowView and move them to the common base class of that and of the newer SceneWindowRootView, which is WindowRootView. Fix: 290984671 Test: manually verified that the bouncer scene extends to the top and bottom of the display when Flexiglass is turned on but also when it's turned off (no harm done). Change-Id: I05cc4202bae1530506f6f0c90afdcda03ad7d020 Merged-In: I05cc4202bae1530506f6f0c90afdcda03ad7d020
This commit is contained in:
committed by
Ale Nijamkin
parent
714771e86a
commit
8f20646bb5
@@ -24,8 +24,10 @@ class SceneWindowRootView(
|
||||
viewModel: SceneContainerViewModel,
|
||||
containerConfig: SceneContainerConfig,
|
||||
scenes: Set<Scene>,
|
||||
layoutInsetController: LayoutInsetsController,
|
||||
) {
|
||||
this.viewModel = viewModel
|
||||
setLayoutInsetsController(layoutInsetController)
|
||||
SceneWindowRootViewBinder.bind(
|
||||
view = this@SceneWindowRootView,
|
||||
viewModel = viewModel,
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
package com.android.systemui.scene.ui.view
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.util.Pair
|
||||
import android.view.DisplayCutout
|
||||
import android.view.View
|
||||
import android.view.WindowInsets
|
||||
import android.widget.FrameLayout
|
||||
import androidx.core.view.updateMargins
|
||||
import com.android.systemui.R
|
||||
import com.android.systemui.compose.ComposeFacade
|
||||
|
||||
/**
|
||||
@@ -25,6 +31,10 @@ open class WindowRootView(
|
||||
attrs,
|
||||
) {
|
||||
|
||||
private lateinit var layoutInsetsController: LayoutInsetsController
|
||||
private var leftInset = 0
|
||||
private var rightInset = 0
|
||||
|
||||
override fun onAttachedToWindow() {
|
||||
super.onAttachedToWindow()
|
||||
|
||||
@@ -41,6 +51,67 @@ open class WindowRootView(
|
||||
}
|
||||
}
|
||||
|
||||
override fun generateLayoutParams(attrs: AttributeSet?): FrameLayout.LayoutParams? {
|
||||
return LayoutParams(context, attrs)
|
||||
}
|
||||
|
||||
override fun generateDefaultLayoutParams(): FrameLayout.LayoutParams? {
|
||||
return LayoutParams(
|
||||
FrameLayout.LayoutParams.MATCH_PARENT,
|
||||
FrameLayout.LayoutParams.MATCH_PARENT
|
||||
)
|
||||
}
|
||||
|
||||
override fun onApplyWindowInsets(windowInsets: WindowInsets): WindowInsets? {
|
||||
val insets = windowInsets.getInsetsIgnoringVisibility(WindowInsets.Type.systemBars())
|
||||
if (fitsSystemWindows) {
|
||||
val paddingChanged = insets.top != paddingTop || insets.bottom != paddingBottom
|
||||
|
||||
// Drop top inset, and pass through bottom inset.
|
||||
if (paddingChanged) {
|
||||
setPadding(0, 0, 0, 0)
|
||||
}
|
||||
} else {
|
||||
val changed =
|
||||
paddingLeft != 0 || paddingRight != 0 || paddingTop != 0 || paddingBottom != 0
|
||||
if (changed) {
|
||||
setPadding(0, 0, 0, 0)
|
||||
}
|
||||
}
|
||||
leftInset = 0
|
||||
rightInset = 0
|
||||
|
||||
val displayCutout = rootWindowInsets.displayCutout
|
||||
val pairInsets: Pair<Int, Int> =
|
||||
layoutInsetsController.getinsets(windowInsets, displayCutout)
|
||||
leftInset = pairInsets.first
|
||||
rightInset = pairInsets.second
|
||||
applyMargins()
|
||||
return windowInsets
|
||||
}
|
||||
|
||||
fun setLayoutInsetsController(layoutInsetsController: LayoutInsetsController) {
|
||||
this.layoutInsetsController = layoutInsetsController
|
||||
}
|
||||
|
||||
private fun applyMargins() {
|
||||
val count = childCount
|
||||
for (i in 0 until count) {
|
||||
val child = getChildAt(i)
|
||||
if (child.layoutParams is LayoutParams) {
|
||||
val layoutParams = child.layoutParams as LayoutParams
|
||||
if (
|
||||
!layoutParams.ignoreRightInset &&
|
||||
(layoutParams.rightMargin != rightInset ||
|
||||
layoutParams.leftMargin != leftInset)
|
||||
) {
|
||||
layoutParams.updateMargins(left = leftInset, right = rightInset)
|
||||
child.requestLayout()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns `true` if this view is the true root of the view-hierarchy; `false` otherwise.
|
||||
*
|
||||
@@ -50,4 +121,44 @@ open class WindowRootView(
|
||||
// TODO(b/283300105): remove this check once there's only one subclass of WindowRootView.
|
||||
return parent.let { it !is View || it.id == android.R.id.content }
|
||||
}
|
||||
|
||||
/** Controller responsible for calculating insets for the shade window. */
|
||||
interface LayoutInsetsController {
|
||||
|
||||
/** Update the insets and calculate them accordingly. */
|
||||
fun getinsets(
|
||||
windowInsets: WindowInsets?,
|
||||
displayCutout: DisplayCutout?,
|
||||
): Pair<Int, Int>
|
||||
}
|
||||
|
||||
private class LayoutParams : FrameLayout.LayoutParams {
|
||||
var ignoreRightInset = false
|
||||
|
||||
constructor(
|
||||
width: Int,
|
||||
height: Int,
|
||||
) : super(
|
||||
width,
|
||||
height,
|
||||
)
|
||||
|
||||
@SuppressLint("CustomViewStyleable")
|
||||
constructor(
|
||||
context: Context,
|
||||
attrs: AttributeSet?,
|
||||
) : super(
|
||||
context,
|
||||
attrs,
|
||||
) {
|
||||
val obtainedAttributes =
|
||||
context.obtainStyledAttributes(attrs, R.styleable.StatusBarWindowView_Layout)
|
||||
ignoreRightInset =
|
||||
obtainedAttributes.getBoolean(
|
||||
R.styleable.StatusBarWindowView_Layout_ignoreRightInset,
|
||||
false
|
||||
)
|
||||
obtainedAttributes.recycle()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,19 +17,15 @@
|
||||
package com.android.systemui.shade;
|
||||
|
||||
import static android.os.Trace.TRACE_TAG_APP;
|
||||
import static android.view.WindowInsets.Type.systemBars;
|
||||
|
||||
import static com.android.systemui.statusbar.phone.CentralSurfaces.DEBUG;
|
||||
|
||||
import android.annotation.ColorInt;
|
||||
import android.annotation.DrawableRes;
|
||||
import android.annotation.LayoutRes;
|
||||
import android.annotation.Nullable;
|
||||
import android.content.Context;
|
||||
import android.content.res.Configuration;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Insets;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.Drawable;
|
||||
@@ -37,9 +33,7 @@ import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.Trace;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Pair;
|
||||
import android.view.ActionMode;
|
||||
import android.view.DisplayCutout;
|
||||
import android.view.InputQueue;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.LayoutInflater;
|
||||
@@ -51,13 +45,10 @@ import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewTreeObserver;
|
||||
import android.view.Window;
|
||||
import android.view.WindowInsets;
|
||||
import android.view.WindowInsetsController;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
import com.android.internal.view.FloatingActionMode;
|
||||
import com.android.internal.widget.floatingtoolbar.FloatingToolbar;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.scene.ui.view.WindowRootView;
|
||||
|
||||
/**
|
||||
@@ -68,9 +59,6 @@ import com.android.systemui.scene.ui.view.WindowRootView;
|
||||
public class NotificationShadeWindowView extends WindowRootView {
|
||||
public static final String TAG = "NotificationShadeWindowView";
|
||||
|
||||
private int mRightInset = 0;
|
||||
private int mLeftInset = 0;
|
||||
|
||||
// Implements the floating action mode for TextView's Cut/Copy/Past menu. Normally provided by
|
||||
// DecorView, but since this is a special window we have to roll our own.
|
||||
private View mFloatingActionModeOriginatingView;
|
||||
@@ -79,71 +67,12 @@ public class NotificationShadeWindowView extends WindowRootView {
|
||||
private ViewTreeObserver.OnPreDrawListener mFloatingToolbarPreDrawListener;
|
||||
|
||||
private InteractionEventHandler mInteractionEventHandler;
|
||||
private LayoutInsetsController mLayoutInsetProvider;
|
||||
|
||||
public NotificationShadeWindowView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
setMotionEventSplittingEnabled(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WindowInsets onApplyWindowInsets(WindowInsets windowInsets) {
|
||||
final Insets insets = windowInsets.getInsetsIgnoringVisibility(systemBars());
|
||||
if (getFitsSystemWindows()) {
|
||||
boolean paddingChanged = insets.top != getPaddingTop()
|
||||
|| insets.bottom != getPaddingBottom();
|
||||
|
||||
// Drop top inset, and pass through bottom inset.
|
||||
if (paddingChanged) {
|
||||
setPadding(0, 0, 0, 0);
|
||||
}
|
||||
} else {
|
||||
boolean changed = getPaddingLeft() != 0
|
||||
|| getPaddingRight() != 0
|
||||
|| getPaddingTop() != 0
|
||||
|| getPaddingBottom() != 0;
|
||||
if (changed) {
|
||||
setPadding(0, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
mLeftInset = 0;
|
||||
mRightInset = 0;
|
||||
DisplayCutout displayCutout = getRootWindowInsets().getDisplayCutout();
|
||||
Pair<Integer, Integer> pairInsets = mLayoutInsetProvider
|
||||
.getinsets(windowInsets, displayCutout);
|
||||
mLeftInset = pairInsets.first;
|
||||
mRightInset = pairInsets.second;
|
||||
applyMargins();
|
||||
return windowInsets;
|
||||
}
|
||||
|
||||
private void applyMargins() {
|
||||
final int count = getChildCount();
|
||||
for (int i = 0; i < count; i++) {
|
||||
View child = getChildAt(i);
|
||||
if (child.getLayoutParams() instanceof LayoutParams) {
|
||||
LayoutParams lp = (LayoutParams) child.getLayoutParams();
|
||||
if (!lp.ignoreRightInset
|
||||
&& (lp.rightMargin != mRightInset || lp.leftMargin != mLeftInset)) {
|
||||
lp.rightMargin = mRightInset;
|
||||
lp.leftMargin = mLeftInset;
|
||||
child.requestLayout();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public FrameLayout.LayoutParams generateLayoutParams(AttributeSet attrs) {
|
||||
return new LayoutParams(getContext(), attrs);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected FrameLayout.LayoutParams generateDefaultLayoutParams() {
|
||||
return new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onAttachedToWindow() {
|
||||
super.onAttachedToWindow();
|
||||
@@ -172,10 +101,6 @@ public class NotificationShadeWindowView extends WindowRootView {
|
||||
mInteractionEventHandler = listener;
|
||||
}
|
||||
|
||||
protected void setLayoutInsetsController(LayoutInsetsController provider) {
|
||||
mLayoutInsetProvider = provider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean dispatchTouchEvent(MotionEvent ev) {
|
||||
Boolean result = mInteractionEventHandler.handleDispatchTouchEvent(ev);
|
||||
@@ -227,24 +152,6 @@ public class NotificationShadeWindowView extends WindowRootView {
|
||||
}
|
||||
}
|
||||
|
||||
private static class LayoutParams extends FrameLayout.LayoutParams {
|
||||
|
||||
public boolean ignoreRightInset;
|
||||
|
||||
LayoutParams(int width, int height) {
|
||||
super(width, height);
|
||||
}
|
||||
|
||||
LayoutParams(Context c, AttributeSet attrs) {
|
||||
super(c, attrs);
|
||||
|
||||
TypedArray a = c.obtainStyledAttributes(attrs, R.styleable.StatusBarWindowView_Layout);
|
||||
ignoreRightInset = a.getBoolean(
|
||||
R.styleable.StatusBarWindowView_Layout_ignoreRightInset, false);
|
||||
a.recycle();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionMode startActionModeForChild(View originalView, ActionMode.Callback callback,
|
||||
int type) {
|
||||
@@ -357,18 +264,6 @@ public class NotificationShadeWindowView extends WindowRootView {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Controller responsible for calculating insets for the shade window.
|
||||
*/
|
||||
public interface LayoutInsetsController {
|
||||
|
||||
/**
|
||||
* Update the insets and calculate them accordingly.
|
||||
*/
|
||||
Pair<Integer, Integer> getinsets(@Nullable WindowInsets windowInsets,
|
||||
@Nullable DisplayCutout displayCutout);
|
||||
}
|
||||
|
||||
interface InteractionEventHandler {
|
||||
/**
|
||||
* Returns a result for {@link ViewGroup#dispatchTouchEvent(MotionEvent)} or null to defer
|
||||
|
||||
@@ -42,6 +42,7 @@ import com.android.systemui.scene.ui.view.WindowRootView
|
||||
import com.android.systemui.scene.ui.viewmodel.SceneContainerViewModel
|
||||
import com.android.systemui.settings.UserTracker
|
||||
import com.android.systemui.statusbar.LightRevealScrim
|
||||
import com.android.systemui.statusbar.NotificationInsetsController
|
||||
import com.android.systemui.statusbar.NotificationShelf
|
||||
import com.android.systemui.statusbar.NotificationShelfController
|
||||
import com.android.systemui.statusbar.notification.row.dagger.NotificationShelfComponent
|
||||
@@ -78,6 +79,7 @@ abstract class ShadeViewProviderModule {
|
||||
containerConfigProvider: Provider<SceneContainerConfig>,
|
||||
@Named(SceneContainerNames.SYSTEM_UI_DEFAULT)
|
||||
scenesProvider: Provider<Set<@JvmSuppressWildcards Scene>>,
|
||||
layoutInsetController: NotificationInsetsController,
|
||||
): WindowRootView {
|
||||
return if (
|
||||
featureFlags.isEnabled(Flags.SCENE_CONTAINER) && ComposeFacade.isComposeAvailable()
|
||||
@@ -88,6 +90,7 @@ abstract class ShadeViewProviderModule {
|
||||
viewModel = viewModelProvider.get(),
|
||||
containerConfig = containerConfigProvider.get(),
|
||||
scenes = scenesProvider.get(),
|
||||
layoutInsetController = layoutInsetController,
|
||||
)
|
||||
sceneWindowRootView
|
||||
} else {
|
||||
|
||||
@@ -16,11 +16,11 @@
|
||||
|
||||
package com.android.systemui.statusbar;
|
||||
|
||||
import com.android.systemui.shade.NotificationShadeWindowView;
|
||||
import com.android.systemui.scene.ui.view.WindowRootView;
|
||||
|
||||
/**
|
||||
* Calculates insets for the notification shade window view.
|
||||
*/
|
||||
public abstract class NotificationInsetsController
|
||||
implements NotificationShadeWindowView.LayoutInsetsController {
|
||||
implements WindowRootView.LayoutInsetsController {
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user