Loading packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootView.kt +2 −0 Original line number Diff line number Diff line Loading @@ -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, Loading packages/SystemUI/src/com/android/systemui/scene/ui/view/WindowRootView.kt +116 −0 Original line number Diff line number Diff line 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 /** A view that can serve as the root of the main SysUI window. */ Loading @@ -16,6 +22,10 @@ open class WindowRootView( attrs, ) { private lateinit var layoutInsetsController: LayoutInsetsController private var leftInset = 0 private var rightInset = 0 override fun onAttachedToWindow() { super.onAttachedToWindow() Loading @@ -32,8 +42,114 @@ 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. * * Please see the class-level documentation to understand why this is possible. */ private fun isRoot(): Boolean { // 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() } } } packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowView.java +0 −105 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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; /** Loading @@ -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; Loading @@ -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(); Loading Loading @@ -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); Loading Loading @@ -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) { Loading Loading @@ -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 Loading packages/SystemUI/src/com/android/systemui/shade/ShadeViewProviderModule.kt +3 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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() Loading @@ -88,6 +90,7 @@ abstract class ShadeViewProviderModule { viewModel = viewModelProvider.get(), containerConfig = containerConfigProvider.get(), scenes = scenesProvider.get(), layoutInsetController = layoutInsetController, ) sceneWindowRootView } else { Loading packages/SystemUI/src/com/android/systemui/statusbar/NotificationInsetsController.java +2 −2 Original line number Diff line number Diff line Loading @@ -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 { } Loading
packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootView.kt +2 −0 Original line number Diff line number Diff line Loading @@ -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, Loading
packages/SystemUI/src/com/android/systemui/scene/ui/view/WindowRootView.kt +116 −0 Original line number Diff line number Diff line 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 /** A view that can serve as the root of the main SysUI window. */ Loading @@ -16,6 +22,10 @@ open class WindowRootView( attrs, ) { private lateinit var layoutInsetsController: LayoutInsetsController private var leftInset = 0 private var rightInset = 0 override fun onAttachedToWindow() { super.onAttachedToWindow() Loading @@ -32,8 +42,114 @@ 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. * * Please see the class-level documentation to understand why this is possible. */ private fun isRoot(): Boolean { // 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() } } }
packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowView.java +0 −105 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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; /** Loading @@ -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; Loading @@ -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(); Loading Loading @@ -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); Loading Loading @@ -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) { Loading Loading @@ -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 Loading
packages/SystemUI/src/com/android/systemui/shade/ShadeViewProviderModule.kt +3 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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() Loading @@ -88,6 +90,7 @@ abstract class ShadeViewProviderModule { viewModel = viewModelProvider.get(), containerConfig = containerConfigProvider.get(), scenes = scenesProvider.get(), layoutInsetController = layoutInsetController, ) sceneWindowRootView } else { Loading
packages/SystemUI/src/com/android/systemui/statusbar/NotificationInsetsController.java +2 −2 Original line number Diff line number Diff line Loading @@ -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 { }