Merge "[flexiglass] Make the window-view full-screen." into udc-qpr-dev

This commit is contained in:
Treehugger Robot
2023-07-27 08:16:45 +00:00
committed by Android (Google) Code Review
5 changed files with 118 additions and 107 deletions

View File

@@ -24,8 +24,10 @@ class SceneWindowRootView(
viewModel: SceneContainerViewModel, viewModel: SceneContainerViewModel,
containerConfig: SceneContainerConfig, containerConfig: SceneContainerConfig,
scenes: Set<Scene>, scenes: Set<Scene>,
layoutInsetController: LayoutInsetsController,
) { ) {
this.viewModel = viewModel this.viewModel = viewModel
setLayoutInsetsController(layoutInsetController)
SceneWindowRootViewBinder.bind( SceneWindowRootViewBinder.bind(
view = this@SceneWindowRootView, view = this@SceneWindowRootView,
viewModel = viewModel, viewModel = viewModel,

View File

@@ -1,9 +1,15 @@
package com.android.systemui.scene.ui.view package com.android.systemui.scene.ui.view
import android.annotation.SuppressLint
import android.content.Context import android.content.Context
import android.util.AttributeSet import android.util.AttributeSet
import android.util.Pair
import android.view.DisplayCutout
import android.view.View import android.view.View
import android.view.WindowInsets
import android.widget.FrameLayout import android.widget.FrameLayout
import androidx.core.view.updateMargins
import com.android.systemui.R
import com.android.systemui.compose.ComposeFacade import com.android.systemui.compose.ComposeFacade
/** /**
@@ -25,6 +31,10 @@ open class WindowRootView(
attrs, attrs,
) { ) {
private lateinit var layoutInsetsController: LayoutInsetsController
private var leftInset = 0
private var rightInset = 0
override fun onAttachedToWindow() { override fun onAttachedToWindow() {
super.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. * 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. // 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 } 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()
}
}
} }

View File

@@ -17,19 +17,15 @@
package com.android.systemui.shade; package com.android.systemui.shade;
import static android.os.Trace.TRACE_TAG_APP; 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 static com.android.systemui.statusbar.phone.CentralSurfaces.DEBUG;
import android.annotation.ColorInt; import android.annotation.ColorInt;
import android.annotation.DrawableRes; import android.annotation.DrawableRes;
import android.annotation.LayoutRes; import android.annotation.LayoutRes;
import android.annotation.Nullable;
import android.content.Context; import android.content.Context;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.content.res.TypedArray;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.graphics.Insets;
import android.graphics.Paint; import android.graphics.Paint;
import android.graphics.Rect; import android.graphics.Rect;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
@@ -37,9 +33,7 @@ import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.os.Trace; import android.os.Trace;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.util.Pair;
import android.view.ActionMode; import android.view.ActionMode;
import android.view.DisplayCutout;
import android.view.InputQueue; import android.view.InputQueue;
import android.view.KeyEvent; import android.view.KeyEvent;
import android.view.LayoutInflater; import android.view.LayoutInflater;
@@ -51,13 +45,10 @@ import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.ViewTreeObserver; import android.view.ViewTreeObserver;
import android.view.Window; import android.view.Window;
import android.view.WindowInsets;
import android.view.WindowInsetsController; import android.view.WindowInsetsController;
import android.widget.FrameLayout;
import com.android.internal.view.FloatingActionMode; import com.android.internal.view.FloatingActionMode;
import com.android.internal.widget.floatingtoolbar.FloatingToolbar; import com.android.internal.widget.floatingtoolbar.FloatingToolbar;
import com.android.systemui.R;
import com.android.systemui.scene.ui.view.WindowRootView; 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 class NotificationShadeWindowView extends WindowRootView {
public static final String TAG = "NotificationShadeWindowView"; 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 // 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. // DecorView, but since this is a special window we have to roll our own.
private View mFloatingActionModeOriginatingView; private View mFloatingActionModeOriginatingView;
@@ -79,71 +67,12 @@ public class NotificationShadeWindowView extends WindowRootView {
private ViewTreeObserver.OnPreDrawListener mFloatingToolbarPreDrawListener; private ViewTreeObserver.OnPreDrawListener mFloatingToolbarPreDrawListener;
private InteractionEventHandler mInteractionEventHandler; private InteractionEventHandler mInteractionEventHandler;
private LayoutInsetsController mLayoutInsetProvider;
public NotificationShadeWindowView(Context context, AttributeSet attrs) { public NotificationShadeWindowView(Context context, AttributeSet attrs) {
super(context, attrs); super(context, attrs);
setMotionEventSplittingEnabled(false); 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 @Override
protected void onAttachedToWindow() { protected void onAttachedToWindow() {
super.onAttachedToWindow(); super.onAttachedToWindow();
@@ -172,10 +101,6 @@ public class NotificationShadeWindowView extends WindowRootView {
mInteractionEventHandler = listener; mInteractionEventHandler = listener;
} }
protected void setLayoutInsetsController(LayoutInsetsController provider) {
mLayoutInsetProvider = provider;
}
@Override @Override
public boolean dispatchTouchEvent(MotionEvent ev) { public boolean dispatchTouchEvent(MotionEvent ev) {
Boolean result = mInteractionEventHandler.handleDispatchTouchEvent(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 @Override
public ActionMode startActionModeForChild(View originalView, ActionMode.Callback callback, public ActionMode startActionModeForChild(View originalView, ActionMode.Callback callback,
int type) { 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 { interface InteractionEventHandler {
/** /**
* Returns a result for {@link ViewGroup#dispatchTouchEvent(MotionEvent)} or null to defer * Returns a result for {@link ViewGroup#dispatchTouchEvent(MotionEvent)} or null to defer

View File

@@ -42,6 +42,7 @@ import com.android.systemui.scene.ui.view.WindowRootView
import com.android.systemui.scene.ui.viewmodel.SceneContainerViewModel import com.android.systemui.scene.ui.viewmodel.SceneContainerViewModel
import com.android.systemui.settings.UserTracker import com.android.systemui.settings.UserTracker
import com.android.systemui.statusbar.LightRevealScrim import com.android.systemui.statusbar.LightRevealScrim
import com.android.systemui.statusbar.NotificationInsetsController
import com.android.systemui.statusbar.NotificationShelf import com.android.systemui.statusbar.NotificationShelf
import com.android.systemui.statusbar.NotificationShelfController import com.android.systemui.statusbar.NotificationShelfController
import com.android.systemui.statusbar.notification.row.dagger.NotificationShelfComponent import com.android.systemui.statusbar.notification.row.dagger.NotificationShelfComponent
@@ -78,6 +79,7 @@ abstract class ShadeViewProviderModule {
containerConfigProvider: Provider<SceneContainerConfig>, containerConfigProvider: Provider<SceneContainerConfig>,
@Named(SceneContainerNames.SYSTEM_UI_DEFAULT) @Named(SceneContainerNames.SYSTEM_UI_DEFAULT)
scenesProvider: Provider<Set<@JvmSuppressWildcards Scene>>, scenesProvider: Provider<Set<@JvmSuppressWildcards Scene>>,
layoutInsetController: NotificationInsetsController,
): WindowRootView { ): WindowRootView {
return if ( return if (
featureFlags.isEnabled(Flags.SCENE_CONTAINER) && ComposeFacade.isComposeAvailable() featureFlags.isEnabled(Flags.SCENE_CONTAINER) && ComposeFacade.isComposeAvailable()
@@ -88,6 +90,7 @@ abstract class ShadeViewProviderModule {
viewModel = viewModelProvider.get(), viewModel = viewModelProvider.get(),
containerConfig = containerConfigProvider.get(), containerConfig = containerConfigProvider.get(),
scenes = scenesProvider.get(), scenes = scenesProvider.get(),
layoutInsetController = layoutInsetController,
) )
sceneWindowRootView sceneWindowRootView
} else { } else {

View File

@@ -16,11 +16,11 @@
package com.android.systemui.statusbar; 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. * Calculates insets for the notification shade window view.
*/ */
public abstract class NotificationInsetsController public abstract class NotificationInsetsController
implements NotificationShadeWindowView.LayoutInsetsController { implements WindowRootView.LayoutInsetsController {
} }